2. Table of Contents
Part I: System Requirements Models
................................................3
Brief overview of system scope
3
Event table
3
Use case diagrams
4
Domain model class diagram
6
Use case descriptions
7
System sequence diagrams (SSDs)
17
Attribute definitions
25
Basic attributes
25
Detailed attributes
26
Part II: Alternative Design Concepts & Recommendation
.............28
Defining alternatives
28
Four feasible alternatives
28
Recommended design alternative
29
Part III: Design & Implementation to Date
.......................................30
Technology & working environment
30
Implemented to date
30
Screenshots / brief walkthrough
30
Database data
31
Python/Django source
33
HTML template source
38
Database SQL schema code
41
Initial menu hierarchy
44
System reports
44
Part IV: Project Monitoring / Reporting to Date
..............................47
2
CIS591: Analysis Report
3. Part I: System Requirements Models
Part I: System Requirements Models
Brief overview of system scope
The existing LINKS system encompasses several areas including sales leads distribution,
order processing and refunds, executive dashboards, and more. My system, for the sake of
brevity and scope for this class, will only focus on lead distribution, lead processing, and
customer management.
Event table
Event Trigger Source Use Case Response Destination
Processing wants to Management
New lead source Processing rep Define lead source Lead source
create a lead source Processing
Processing wants to Management
enter a lead in New lead Processing rep Create new lead Lead Processing
manually Marketers
Processing wants to Management
import a batch of Batch lead import Processing rep Import external leads Leads Processing
leads Marketers
Processing wants to Management
New promotion Processing rep Define promotion Promotion
create a promotion Processing
Processing wants to New marketing Define marketing Management
Processing rep Marketing campaign
create a campaign campaign campaign Processing
Processing wants to
Batch assign lead Assign leads to lead Management
classify leads to a Processing rep Categorized lead(s)
paths path Marketers
path
Processing chooses Sales company
Distribute leads to Leads assigned to
sales company to Assign leads Processing rep management
sales company sales company
receive leads Marketers
Sales company
management wants Sales company Distribute leads to Leads assigned to Division management
Assign leads
to distribute leads to management division division Marketers
divisions
Division management
Distribute leads to Leads assigned to Sales teams
wants to distribute Assign leads Division management
sales team sales team Marketers
leads to teams
Sales teamleaders
want to assign leads Assign leads to Leads assigned to
Assign leads Sales teamleaders Marketers
to individual marketers marketers
marketers
Marketer follows up Upgrade/downgrade Lead with changed Marketers
Lead properties Marketer
on lead lead status status Sales teamleaders
Time to archive Updated archived
‘End of day’ Archive inactive leads
inactive leads leads list
Any level of
Management (any Customized lead Management (any
management wants a Report request Generate lead report
level) report level)
lead report
Any level of
management wants a Management (any Generate marketer Customized marketer Management (any
Report request
report on certain level) report performance report level)
marketer(s)
CIS591: Analysis Report
3
4. Part I: System Requirements Models
Event Trigger Source Use Case Response Destination
Sales company
management wants a Sales company Generate overall Master performance Sales company
Report request
report on overall management report report management
performance
Processing needs a
Export leads Processing rep Export lead list Exported lead data Processing rep
master list of leads
Processing needs to Marketers
add or change a Edit customer Processing rep Define customer Modified customer Management (any
customer’s details level)
Use case diagrams
System
Define lead
source
Create new lead
Import external
leads
Define promotion
Define marketing
campaign
Processing Assign leads to
Rep lead path
Distribute leads to
sales company
Export lead list
Define customer
4
CIS591: Analysis Report
5. Part I: System Requirements Models
System
Modify lead status
Marketer
System
Distribute leads to
sales team
Distribute leads to
division
Division
Generate lead
manager
report
Generate
marketer report
Sales
manager
Generate overall
report
Sales
Assign leads to
teamleader
marketers
CIS591: Analysis Report
5
6. Part I: System Requirements Models
Domain model class diagram
Domain Class Diagram Benjamin Kreeger
Lead Source
1 companyName Product
address productName
1 *
city productSource
*
state productPrice
Promotion zip productDescription
promotionName country productPicture
promotionSource phone
1..*
0..1 OrderDetails
0..1 orderID
productID
qty
* * *
Lead
Order
createDate
Sales Company orderDate
expireDate
companyName orderCustomerID
customerID
address orderTotal
sourceID
city orderPaymentMethod
promotionID
0..1 *
state orderDueDate
pipelineID
zip orderPayDate
salesCompanyID
country
1 divisionID *
phone *
teamID
isInternal
marketerID
managerID
status
1
1 detail
* *
* 0..1
*
Division Person
Team
divisionName firstName
divisionID
companyID lastName
0..1 teamLeaderID
managerID address
* city
1 1
1 1 state
zip
country
phone
0..1 1
User
Customer
userid
age
maritalStatus
0..1
0..1
numChildren
assetAmount
0..1 *
0..1 liabilityAmount
Manager Team Leader Marketer Processing Rep
managerType commissionRate commissionRate managerID
teamID salesCompanyID
1
* *
6
CIS591: Analysis Report
7. Part I: System Requirements Models
Use case descriptions
Use Case Name: Assign leads to lead path
Assign previously unassigned leads to a specific lead path
Scenario:
Processing representative wants to classify leads to a path.
Triggering Event:
After a batch import of leads, or new leads are imported by hand, there is
Brief Description:
often incomplete information about the leads that can easily be completed
by a processing rep. This information includes the company, the buyer/
non-buyer pipeline, etc. A processing rep will pull up a list of unassigned
leads and assign them each to lead paths (usually a batch at a time).
Processing representative
Actors:
• Import external leads (batch import can lead to this use case)
Related Use Cases:
• Distribute leads to sales company (leads go to this use case)
• Marketers
Stakeholders:
• All levels of management
• Leads in the list must already exist in the system (and with incomplete
Preconditions:
information)
• Lead(s) will have complete lead path information
Postconditions:
• Leads will be sent to assignment queue
Flow of Events: Actor System
1) Processing rep visits assign leads 1.1) System renders lead path form
to lead path form
2) Rep tags leads with company, 2.1) With each batch tagging,
pipeline, etc. system will update leads in the
database with the proper
information
3) Rep will tag leads with all required 3.1) System will hide committed
information and commit leads if they leads from the list
are accurate 3.2) If all leads committed, user is
prompted to return to menu
4) Rep can choose to return to menu
• If rep chooses to return to menu, the system will render the main menu
Exception
page
Conditions:
CIS591: Analysis Report
7
8. Part I: System Requirements Models
Use Case Name: Assign leads to marketers
Assign team-assigned leads to individual marketers
Scenario:
Sales teamleaders want to assign leads to individual marketers
Triggering Event:
A sales teamleader will receive an email when they have new leads in their
Brief Description:
queue for assignment. They will log into the system, bring up their
distribute leads page, and start assigning leads to their individual
marketers. They can choose to manually pick leads, or automatically
assign leads to marketers up to their limit.
Sales teamleader
Actors:
• Assign leads to lead path
Related Use Cases:
• Distribute leads to sales team
• Marketers
Stakeholders:
• Customers
• Leads in the list must already exist in the system with complete details
Preconditions:
• Leads must already be assigned to a sales team
• Leads will be assigned to marketers to follow up on them
Postconditions:
• Leads will no longer be available to assign to marketers
Flow of Events: Actor System
1) Sales teamleader visits distribute 1.1) System checks team leader’s
leads form credentials, renders “leads to
marketers” form
2) Teamleader selects a batch of leads
3) Teamleader chooses marketer to 3.1) System updates leads in
distribute them to, clicks commit database with chosen marketer
4) Manager distributes all leads to
various marketers, leaves form
• If a marketer already has maximum allocated leads, an error will be
Exception
displayed, and only the number of leads selected minus the ones over
Conditions:
marketer’s limit will be assigned
8
CIS591: Analysis Report
9. Part I: System Requirements Models
Use Case Name: Create new lead
Create new lead
Scenario:
Processing representative wants to enter a lead in manually.
Triggering Event:
A single sales lead comes into the office. The processing rep who handles
Brief Description:
the lead imports the relevant data into a form. This data typically includes a
prospective customer’s name and contact information, as well as which
marketing campaign it came in under. The lead is then placed into a queue
for assignment, or to an incomplete queue for lead path assignment.
Processing representative
Actors:
• Import external leads (a batch import of leads instead of a singular lead)
Related Use Cases:
• Assign leads to lead path (if leads have incomplete lead path info)
• Distribute leads to sales company (goes into queue for this use case)
• All levels of management
Stakeholders:
• Marketers
• Lead source, promotion, and marketing campaigns must already exist
Preconditions:
before lead can be imported
• Lead will be created and added to assignment queue / incomplete queue
Postconditions:
• If customer didn’t already exist in database, it will also be added
Flow of Events: Actor System
1) Processing rep visits new lead form 1.1) System renders new lead form
2) Rep enters in relevant lead data
3) Rep submits new lead form 3.1) System validates input
3.2) Insert customer into database
3.3) Insert lead into database
3.4) Redirect to lead form
4) Rep sees lead form again
• If rep doesn’t have some required information (customer, campaign), then
Exception
the form is redisplayed with notifications of problem fields
Conditions:
CIS591: Analysis Report
9
10. Part I: System Requirements Models
Use Case Name: Distribute leads to division
Distribute company-assigned leads to division
Scenario:
Sales company management wants to distribute leads to divisions.
Triggering Event:
As a sales company manager gets new leads in their distribution queue,
Brief Description:
they’ll get an email from the system stating new leads are available for them
to distribute down to their divisions. They’ll log into the system, bring up
their distribute leads page, and assign leads to their divisions.
Sales company manager
Actors:
• Assign leads to lead path
Related Use Cases:
• Distribute leads to sales company
• Distribute leads to sales team
• Marketers
Stakeholders:
• Division management
• Leads in the list must already exist in the system with complete details
Preconditions:
• Leads must already be assigned to a sales company
• Leads will be assigned to division management for further assignment
Postconditions:
• Leads will no longer be available to assign to divisions
Flow of Events: Actor System
1) Sales manager visits distribute 1.1) System checks manager’s
leads form credentials, renders “leads to
divisions” form
2) Manager selects a batch of leads
3) Manager chooses division to 3.1) System updates leads in
distribute them to, clicks commit database with chosen division
4) Manager distributes all leads to
various divisions, leaves form
• If a division already has maximum allocated leads, an error will be
Exception
displayed, and only the number of leads selected minus the ones over
Conditions:
division limit will be assigned
10
CIS591: Analysis Report
11. Part I: System Requirements Models
Use Case Name: Distribute leads to sales company
Distribute unassigned leads to sales company
Scenario:
Processing representative chooses sales company to receive leads.
Triggering Event:
A sales company will have a number of new leads that they can accept per
Brief Description:
day. The processing rep will assign a subset of leads to a sales company
so their management can push those leads out to divisions, teams, and so
forth. The rep will bring up a form with all undistributed leads, and assign a
max number of leads to a sales company.
Processing representative
Actors:
Import external leads
Related Use Cases: •
Create new lead
•
Assign leads to lead path
•
Distribute leads to division
•
• Marketers
Stakeholders:
• Sales company management
• Leads in the list must already exist in the system with complete details
Preconditions:
• Leads must not yet be assigned to any other sales company
• Leads will be assigned to sales company for further assignment
Postconditions:
• Leads will no longer be available to assign to sales companies
Flow of Events: Actor System
1) Processing rep visits distribute 1.1) System checks processing
leads form rep’s credentials, renders “leads to
sales companies” form
2) Rep selects a batch of leads
3) Rep chooses company to distribute 3.1) System updates leads in
leads to, clicks commit database with chosen sales
company
4) Rep distributes all leads to various
sales companies, leaves form
• If a division already has maximum allocated leads, an error will be
Exception
displayed, and only the number of leads selected minus the ones over
Conditions:
division limit will be assigned
CIS591: Analysis Report
11
12. Part I: System Requirements Models
Use Case Name: Distribute leads to sales team
Distribute division-assigned leads to sales team
Scenario:
Division management wants to distribute leads to teams.
Triggering Event:
A division manager will get an email notification once there are new leads in
Brief Description:
their queue. They’ll log into the system, bring up their distribute leads page,
and start assigning their leads to sales teamleaders.
Division manager
Actors:
• Assign leads to lead path
Related Use Cases:
• Distribute leads to division
• Assign leads to marketers
• Marketers
Stakeholders:
• Sales teamleaders
• Leads in the list must already exist in the system with complete details
Preconditions:
• Leads must already be assigned to a division
• Leads will be assigned to sales teamleaders for further assignment
Postconditions:
• Leads will no longer be available to assign to sales teams
Flow of Events: Actor System
1) Division manager visits distribute 1.1) System checks manager’s
leads form credentials, renders “leads to sales
team” form
2) Manager selects a batch of leads
3) Manager chooses team to 3.1) System updates leads in
distribute them to, clicks commit database with chosen team
4) Manager distributes all leads to
various sales teams, leaves form
• If a sales team already has maximum allocated leads, an error will be
Exception
displayed, and only the number of leads selected minus the ones over
Conditions:
sales team’s limit will be assigned
12
CIS591: Analysis Report
13. Part I: System Requirements Models
Use Case Name: Generate lead report
Generate report of all leads in system
Scenario:
Any level of management wants a lead report.
Triggering Event:
A manager at any level may want a report on overall performance across
Brief Description:
leads. The manager will bring up the report section of the app, choose a
lead report, specify the start and end dates, and the system will generate a
report with information about leads followed during those times.
Management (any level)
Actors:
• Generate marketer report
Related Use Cases:
• Generate marketer report
• Marketers
Stakeholders:
• Any level of management
• Leads must exist in the system and have some status attached to them
Preconditions:
• Lead report will be generated
Postconditions:
Flow of Events: Actor System
1) Manager logs into system, brings 1.1) System renders report form
up report form
2) Manager chooses lead report, sets 2.1) System pulls up all leads for
start and end date, clicks submit the specified timeframe, along with
their details, and renders them in a
report
2.2) System displays report
3) Manager views, prints, or saves the
report
Exception
Conditions:
CIS591: Analysis Report
13
14. Part I: System Requirements Models
Use Case Name: Generate marketer report
Generate specific marketer report
Scenario:
Any level of management wants a lead report.
Triggering Event:
A manager may want a report on a marketer’s performance that details
Brief Description:
sales made per day, average made per sale, among other information. The
manager will bring up the report section of the app, choose a marketer
report, choose the marketer, and the system will generate a report (extra
customization for the report to be added at a later time).
Management (any level)
Actors:
• Generate overall report
Related Use Cases:
• Generate lead report
• Marketers
Stakeholders:
• Any level of management
• Marketer must exist in the system
Preconditions:
• Marketer must have made at least one successful sales call
• Marketer report will be generated
Postconditions:
Flow of Events: Actor System
1) Manager logs into system, brings 1.1) System renders report form
up report form
2) Manager chooses marketer report, 2.1) System pulls up marketer’s
chooses a marketer for the report, sales stats, renders them in a
clicks submit report
2.2) System displays report
3) Manager views, prints, or saves the
report
• If marketer is new (hasn’t had a successful sales call), the system will alert
Exception
the user trying to render the report, and the user will have to choose
Conditions:
another marketer.
14
CIS591: Analysis Report
15. Part I: System Requirements Models
Use Case Name: Upgrade or downgrade lead status
Upgrade or downgrade lead status
Scenario:
Marketer follows up on sales lead.
Triggering Event:
A marketer will go down their list of leads assigned to them and make the
Brief Description:
sales calls. Depending on the status of the phone call (if the lead hung up,
was busy, wasn’t home, etc), the marketer will change the status of that
lead in the system. They’ll login to the system, visit their active leads, click
on the lead they’re working on, and change the details of that lead.
Marketer
Actors:
• Assign leads to marketer
Related Use Cases:
• Sales teamleaders
Stakeholders:
• Customers
• Lead in the list must already exist in the system with complete details
Preconditions:
• Lead must already be assigned to a marketer
• Lead will be modified with additional details on the prospective customer
Postconditions:
• Lead will either be active or inactive depending on status
Flow of Events: Actor System
1) Marketer visits active leads page 1.1) System checks marketer’s
credentials, renders their active
leads in a list
2) Marketer selects current lead 2.1) System renders page with lead
detail (editable)
3) Marketer follows up on lead and 3.1) System saves changes to lead
updates lead information as in the database
necessary, saves changes
4) Marketer returns to active leads 4.1) System renders marketer’s
page active leads in a list
Exception
Conditions:
Archive inactive leads
At the end of each day, any lead that’s been marked inactive (that means the ‘customer’ has
refused several attempts at a sale) will be archived into a history of leads, and hidden from
view unless pulled up in a report. This should occur at 12:01 am, daily.
Define customer
A customer is a more generic term for an external person in the system, whether they’ve
purchased goods from a lead source or not. They’re the person at the other end of the lead,
CIS591: Analysis Report
15
16. Part I: System Requirements Models
and who a marketer would contact. A customer will be defined when a lead is created, unless
the customer already exists in the system. A customer can also be added by hand through
the ‘define customer’ option in the system. In addition, a customer’s information can be
edited by a processing representative manually if it happens to change.
Define lead source
A lead source is usually another company that’s selling a product and one that’s utilizing the
company’s marketing services. In other words, they’re a source of product leads, or lead
sources. When a processing representative wants to create a lead source in the system, they
will log into the system and choose the ‘lead sources’ section. They’ll choose to either define
a new lead source, or redefine an existing lead source. In either use case, they’ll supply the
necessary information (company name, location, contact information, etc.), and save the
changes.
Define marketing campaign
A marketing campaign is also set by the lead source of the product for the campaign; an
example of a campaign would be an infomercial for a real estate investment program. In
order to use leads for this marketing campaign, we’ll need to define it in our system. A
processing representative will gather the information about the marketing campaign (typically
supplied by the lead source), enter the system and choose to define a marketing campaign,
and then enter in the necessary details. Similar steps would be followed for redefining an
existing marketing campaign.
Define promotion
A promotion is set by a lead source (external company) for one of their products (for example,
a promotion could be a real estate investment program). In order to use leads for this
promotion, we’ll need to define it in our system. A processing representative will gather the
information about the promotion, enter the system and choose to define a promotion, and
then enter in the necessary details. Similar steps would be followed for redefining an existing
promotion.
Export lead list
If a lead list ever needs to be exported (or a subset of leads to be exported) to an external
sales company, it’s done in CSV format. This function will allow a processing representative
take any choice of leads and export them, and the system will parse them into a CSV file to
be saved.
Generate overall report
Sometimes a manager may want to pull up a report on how various sales divisions and teams
are doing. The overall report will show performance details for each internal sales company,
with breakdowns for each sales division, with breakdowns for each sales teams, and each
marketer within those teams.
Import external leads
16
CIS591: Analysis Report
17. Part I: System Requirements Models
If a lead source supplies a list of sales leads for a certain promotion and marketing campaign
in comma-separated value format, a processing representative will upload that file into the
system under an ‘import leads’ section, and the system will parse the values from that file into
leads. In some cases, this may lead to incomplete information. In that case, any leads
missing information will be sent to a separate queue to be completed (assigning them to lead
paths).
System sequence diagrams (SSDs)
Assign leads to lead path
System
Processing Rep
Open lead path form
Loop
Tag leads with information and commit
Refresh list
CIS591: Analysis Report
17
18. Part I: System Requirements Models
Assign leads to marketers
System
Sales teamleader
Open lead distribution
Loop
Select batch of leads and marketer
Commit changes
Refresh list
18
CIS591: Analysis Report
19. Part I: System Requirements Models
Create new lead
System
Processing rep
Open new lead form
Loop
Enter in lead data
Submit changes
Return to lead form with confirmation
CIS591: Analysis Report
19
20. Part I: System Requirements Models
Distribute leads to division
System
Sales company mgr.
Open lead distribution form
Loop
Select batch of leads and division
Commit changes
Refresh list
20
CIS591: Analysis Report
21. Part I: System Requirements Models
Distribute leads to sales company
System
Processing rep
Open lead distribution form
Loop
Select batch of leads and team
Commit changes
Refresh list
CIS591: Analysis Report
21
22. Part I: System Requirements Models
Distribute leads to sales team
System
Processing rep
Open lead distribution form
Loop
Select batch of leads and sales company
Commit changes
Refresh list
22
CIS591: Analysis Report
23. Part I: System Requirements Models
Generate lead report
System
Management
Open report form
Choose lead report
Choose start & end date, submit
Displays report
CIS591: Analysis Report
23
24. Part I: System Requirements Models
Generate marketer report
System
Management
Open report form
Choose marketer report
Choose specific marketer, submit
Displays report
24
CIS591: Analysis Report
25. Part I: System Requirements Models
Upgrade or downgrade lead status
System
Marketer
Open active leads page
Choose current lead
Update lead information and status, submit
Redirect to active leads page
Attribute definitions
Basic attributes
Name
•
An identifier, whether for a company, person, product, promotion, division, etc.
Address
•
The number and street of a company or person.
City
•
The location within a state for a company or person.
State
•
The location within a country for a company or person.
Zip
•
The postal code designating a location a company or person.
Country
•
The largest-scoped location designation for a company or person.
Phone
•
A telephone number to reach a company or person at.
Price
•
The cost (to the customer) of a product.
CIS591: Analysis Report
25
26. Part I: System Requirements Models
Total
•
The total cost (to the customer) of an order.
Description
•
The long-text summary detailing more about a product.
Age
•
The age of a customer.
Quantity
•
The amount of a product in an order.
Detailed attributes
Create date
•
The date a lead is created. Typically, this is the date the lead is entered into the
system.
Expire date
•
The date a lead expires. The default for this value is 30 days after its creation,
although it can be changed.
Order date
•
The date an order is created.
Due date
•
The date that payment is due for an order.
Pay date
•
The date that a payment is made on an order.
Payment method
•
The type of payment a customer uses to pay for an order (cash, check, credit
card, money order, etc.)
Source
•
The external originating company for a promotion or a product.
Picture
•
The path to an uploaded picture of a product.
Is internal?
•
A true/false determination if the sales company is an internal one or not. Only
internal sales companies will have leads in the system available for processing.
Status
•
The current situation of a lead (expired, on hold, active, inactive).
Detail
•
More information about a lead. This usually contains notes from a marketer
regarding the customer’s investments, assets, liabilities, lifestyle, etc., obtained
from the customer.
Commission rate
•
The amount of commission a marketer/team leader is paid per sale.
Manager Type
•
The type of manager, usually a position within a sales company or division.
Marital status
•
A brief description of a customer’s marital status (married, single, divorced,
widowed).
Number of children
•
A brief description of the number of children a customer has (those under 18).
26
CIS591: Analysis Report
27. Part I: System Requirements Models
Asset amount
•
A monetary amount detailing the amount of assets a customer might have.
Liability amount
•
A monetary amount detailing the amount of liabilities a customer might have.
CIS591: Analysis Report
27
28. Part II: Alternative Design Concepts and Recommendation
Part II: Alternative Design Concepts & Recommendation
Defining alternatives
Alternatives for our system could be found by changing any number of variables about it. If
we wanted to trade in-house development costs altogether in favor of paying a subscription
to an external company, there are various CRM software packages available. These would
make the system much larger in scope and have much greater automation out-of-the-box.
This approach would also reduce the amount of internal implementation to be done, as it’s
already an established service that we’d merely need to train on internally.
If we wanted to reduce the scope of the system, we could trade in the chosen web
application framework in favor of a few web forms written in whatever language we choose
(PHP, Python, Perl, etc). This would also reduce automation, and web forms wouldn’t have
the depth of the chosen framework. The approach could remain object-oriented, but
procedural implementations would open up as well.
Four feasible alternatives
One alternative we could use in place of this system is going with Salesforce.com. There
would be a subscription cost per-user per-year (Salesforce is a SaaS: software-as-a-service),
and we would get a support contract with the company. It’s got broad coverage on a variety
of platforms; after all, it’s a web-based platform with mobile clients as well (along with email
integration). If we were to go with Salesforce, in-house development of the software would go
away, and we’d be at the mercy of Salesforce as to what features would be implemented.
Another similar alternative we could look at is Oracle Sales, another externally-developed
CRM platform. It integrates with other Oracle applications, and it would run on in-house
hardware. Oracle is known to be a firm force in the industry and would be around for a long
time (in other words, reliability is almost definite).
One alternative we could use in place of this system is to create a series of web forms
written in another language (perhaps PHP) that interact with a database; this would utilize a
very basic three-layer design pattern (the rendered HTML as presentation, the business-logic
PHP scripts, and the back-end database, running MySQL, PostgreSQL, Oracle, etc.).
Depending on the scope of the system, this could take us longer to implement, and would
require us writing considerably more code; the end result, however, would likely be smaller in
scope, and take around the same amount of time to build.
The last alternative would be to alter company policy to allow only Windows PCs to access
the existing system, and opt to not support mobile clients or Linux/Mac clients. At the current
point in time, this would affect a small but growing portion of our staff (most have mobile
clients with web browsers that could access the new system), but if we declare policy now
that we will not support those clients, we could stick with our current C#.NET system and
build on it, instead.
28
CIS591: Analysis Report
29. Part II: Alternative Design Concepts & Recommendation
Recommended design alternative
In reviewing several options for proceeding with our system, my recommendation would be to
go with Salesforce.com. It seems to be a very powerful, easy, and flexible alternative to
writing our own solution in house. If we chose to extend the functionality of Salesforce, we
would either wait for Salesforce to release new features, or tap the existing Salesforce
development community, which is already developing companion software that integrates
with the service (each new extension would cost money, of course).
CIS591: Analysis Report
29
30. Part III: Design & Implementation to Date
Part III: Design & Implementation to Date
You should have completed some prototyping, in this case probably to test the technology
you are planning to use (prototyping for feasibility) as well as initial design ideas (prototyping
for design details). You should also have completed the core functionality of your system.
Technology & working environment
I’m currently using a three-layer approach to developing my program. The Django framework
utilizes object-oriented design in what it calls a MTV pattern, or model-template-view pattern.
This is a minor redefinition of the MVC pattern, or the model-view-controller pattern. In
Django, its views are the business logic, which submits data to templates, which are the
presentation logic.
Web browser URL controller Template layer View layer Model layer Database
Marketer
Open active leads page (/leads/marketer) Get active leads view Get active leads view
Get active leads for marketer Get all active leads for marketer
Marketer's active leads
Marketer's active leads
Template context for active leads
Rendered active leads template
Select active lead Get lead detail view Get lead detail view
Get lead detail for lead #001 Get lead detail for lead #001
Lead #001 detail
Lead #001 detail
Template context for lead #001
Rendered lead detail template
Update lead details, submit form Get update lead view Get update lead view
Update lead #001 Update lead #001
Redirect to active leads template
Template context for active leads
Rendered active leads template
As far as specific development technology and software, I’m doing all my work on my
MacBook under OS X 10.5, using Python 2.6.1 and Django 1.1. My development database is
a SQLite database, but the production database will be MySQL (for performance reasons).
I’m writing all my code in TextMate (and some in Espresso), all my reports in Pages, all my
presentations in Keynote, all my scheduling in Numbers, all my UML diagrams in OmniGraffle,
and I’m using GitHub for my project’s code repository (http://github.com/kreeger/birdie).
Implemented to date
Screenshots / brief walkthrough
To date, I’ve been implementing the marketer use case, upgrade/downgrade lead status,
which is where a marketer pulls up a lead’s detail and updates it accordingly (and chooses to
keep in active or move it to the inactive pile). I’ve got a marketer’s home page set up (really
basic for now) that allows them to get to their lead queues (active leads, inactive leads, or
expired leads). From there, the appropriate lead queue is displayed, and the marketer can
easily switch between the queues. The marketer will then click on the lead and edit the status
(upgrade/downgrade it) and add notes on the lead. Screenshots of those steps (in order) are
shown below.
30
CIS591: Analysis Report
31. Part III: Design & Implementation to Date
Database data
Some database tables (in my SQLite development database) are shown below.
LEADS_PERSON
1|Boyd|Kanenwisher|222 Susie Ln|Kearney|MO|64060|USA|816-628-6638
2|Len|Page|88 Northglen Rd|Provo|UT|38382|USA|837-356-2823
3|James|Phay|288 Southglen Dr|Salt Lake City|UT|89272|USA|827-363-5353
4|Cheryl|Johnson|326 Westglen Rd|Springfield|MO|65806|USA|924-384-9402
5|Zachary|Johnson|9293 East Terrace|Springfield|MO|65803|USA|984-848-4932
6|Richard|Shanks|23626 Sycamore Cir|Kearney|MS|64060|USA|816-628-3409
7|Chupa|Cabra|22 Goat Ln|Los Angeles|CA|90012|USA|939-303-0382
8|James|Jackson|262 Watchmaker Cir|Springfield|IL|03938|USA|892-839-4040
CIS591: Analysis Report
31
33. Part III: Design Implementation to Date
13|0.05
14|0.1
LEADS_MARKETER
15|0.15|2
16|0.1|3
17|0.05|4
LEADS_LEAD
1|2009-03-30 16:35:39.161002|2009-04-13 21:50:30.261194|4|1|1|b|1|1|2|15|inactive||
2|2009-03-30 16:39:07.886871|2009-04-13 21:46:08.141588|5|2|5|nb|1|1|2|15|active||
3|2009-03-30 16:39:25.507449|2009-04-13 16:39:25.507394|6|4|4|nb|1|1|2|15|active||
4|2009-03-30 16:39:41.502455|2009-04-13 16:39:41.502403|9|1|1|b|1|1|3|16|active||
5|2009-03-30 16:39:56.664563|2009-04-13 16:39:56.664501|10|2|2|b|1|1|4|17|active||
6|2009-03-30 16:40:12.931316|2009-04-13 16:40:12.931263|7|1|1|b|1|1|2|15|active||
7|2009-03-30 16:40:59.848908|2009-04-13 21:51:58.245409|8|4|4|nb|1|1|2|15|expired||
Python/Django source
My Python/Django source code for the project (used in the examples) is below.
views.py
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from birdie.leads.models import *
def leads_list(request, userid, status):
# Get user for that id
marketer = get_object_or_404(Marketer, userid=userid)
# Get leads for that marketer
leads = Lead.objects.filter(marketer=marketer.id, status=status)
count = leads.count()
context = {
'user': marketer,
'leads': leads,
'status': status,
'count': count,
}
return render_to_response(quot;leads/leads.htmlquot;, context)
def user_home(request, userid):
user = get_object_or_404(Marketer, userid=userid)
user.what = unicode(user.__class__.__name__)
context = {
'user': user,
}
return render_to_response(quot;leads/home.htmlquot;, context)
def lead_detail(request, userid, lead):
lead = int(lead)
user = get_object_or_404(Marketer, userid=userid)
CIS591: Analysis Report
33
34. Part III: Design Implementation to Date
lead = get_object_or_404(Lead, id=lead)
context = {
'lead': lead,
'user': user,
}
return render_to_response(quot;leads/lead_detail.htmlquot;, context)
def lead_update(request, userid, lead):
lead = int(lead)
user = get_object_or_404(Marketer, userid=userid)
lead = get_object_or_404(Lead, id=lead)
oldstatus = lead.status
lead.detail = request.POST['detail']
lead.status = request.POST['status']
lead.save()
return HttpResponseRedirect(reverse('birdie.leads.views.leads_list',
args=(user.userid,oldstatus,)))
urls.py
from django.conf.urls.defaults import *
from birdie.settings import *
from django.contrib import admin
admin.autodiscover()
# master urlpatterns
urlpatterns = patterns('',
(r'^admin/', include(admin.site.urls)),
(r'^_media/(?Ppath.*)$', 'django.views.static.serve', {'document_root': (SITE_ROOT + '/
_media')}),
)
# patterns from birdie... expect this one to get big
urlpatterns += patterns('birdie.leads.views',
(r'^main/$', 'main'),
(r'^user/(?Puseridw+)/(?Pstatusw+)_leads$', 'leads_list'),
(r'^user/(?Puseridw+)/leads/(?Pleadd+)/$', 'lead_detail'),
(r'^user/(?Puseridw+)/leads/(?Pleadd+)/update/$', 'lead_update'),
(r'^user/(?Puseridw+)/$', 'user_home'),
)
models.py
from django.db import models
from django.contrib.localflavor.us.models import USStateField, PhoneNumberField
from birdie.leads.constants import *
from birdie.settings import SITE_ROOT
import datetime
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
address = models.CharField(max_length=100)
34
CIS591: Analysis Report
35. Part III: Design Implementation to Date
city = models.CharField(max_length=60)
state = USStateField()
zip_code = models.CharField(max_length=10)
country = models.CharField(max_length=50, default='USA')
phone = PhoneNumberField()
def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)
class Customer(Person):
age = models.IntegerField(blank=True, null=True)
marital_status = models.CharField(blank=True, max_length=20)
num_children = models.IntegerField(blank=True, null=True)
assets = models.DecimalField(max_digits=12, decimal_places=2, blank=True,
null=True)
liabilities = models.DecimalField(max_digits=12, decimal_places=2, blank=True,
null=True)
class User(Person):
userid = models.CharField(blank=False, null=False, unique=True, max_length=16)
class Manager(User):
manager_type = models.CharField(max_length=50, choices=MANAGER_TYPES)
class Teamleader(User):
commission_rate = models.DecimalField(max_digits=5, decimal_places=2,
default=COMMISSION_RATE)
class LeadSource(models.Model):
company_name = models.CharField(max_length=100)
address = models.CharField(max_length=100)
city = models.CharField(max_length=60)
state = USStateField()
zip_code = models.CharField(max_length=10)
country = models.CharField(max_length=50)
phone = PhoneNumberField()
def __unicode__(self):
return self.company_name
class Promotion(models.Model):
name = models.CharField(max_length=100)
# Has to have a lead source!
source = models.ForeignKey(LeadSource)
def __unicode__(self):
return self.name
class SalesCompany(models.Model):
company_name = models.CharField(max_length=100)
address = models.CharField(max_length=100)
city = models.CharField(max_length=60)
state = USStateField()
zip_code = models.CharField(max_length=10)
country = models.CharField(max_length=50)
CIS591: Analysis Report
35
36. Part III: Design Implementation to Date
phone = PhoneNumberField()
is_internal = models.BooleanField(default=True)
# Has to have a manager!
manager = models.ForeignKey(Manager)
def __unicode__(self):
return self.company_name
class Division(models.Model):
name = models.CharField(max_length=100)
# Has to have a sales company!
company = models.ForeignKey(SalesCompany)
# Has to have a manager!
manager = models.ForeignKey(Manager)
def __unicode__(self):
return self.name
class Team(models.Model):
# Has to have a division!
division = models.ForeignKey(Division)
# Has to have a teamleader!
teamleader = models.ForeignKey(Teamleader)
def __unicode__(self):
return u'Team %s' % (self.teamleader.last_name)
class ProcessingRep(User):
# Has to have a manager!
manager = models.ForeignKey(Manager)
# Doesn't need to belong to a sales company.
sales_company = models.ForeignKey(SalesCompany, null=True)
class Marketer(User):
commission_rate = models.DecimalField(max_digits=5, decimal_places=2,
default=COMMISSION_RATE)
# Has to have a team!
team = models.ForeignKey(Team)
# The big one...
class Lead(models.Model):
# All foreign keys are optional (they can be filled in later), thus
# the 'null=True' argument
create_date = models.DateTimeField(auto_now_add=True)
expire_date = models.DateTimeField(blank=True, null=True)
customer = models.ForeignKey(Customer, null=True, blank=True)
source = models.ForeignKey(LeadSource, null=True, blank=True)
promotion = models.ForeignKey(Promotion, null=True, blank=True)
pipeline = models.CharField(blank=True, max_length=2, choices=PIPELINES)
sales_company = models.ForeignKey(SalesCompany, null=True, blank=True)
division = models.ForeignKey(Division, null=True, blank=True)
team = models.ForeignKey(Team, null=True, blank=True)
marketer = models.ForeignKey(Marketer, null=True, blank=True)
status = models.CharField(max_length=8, choices=LEAD_STATUSES, default='active')
change_date = models.DateTimeField(blank=True, null=True)
36
CIS591: Analysis Report
37. Part III: Design Implementation to Date
detail = models.TextField(blank=True)
def save(self, *args, **kwargs):
self.expire_date = (datetime.datetime.now() +
datetime.timedelta(days=LEAD_EXPIRE))
super(Lead, self).save(*args, **kwargs)
def __unicode__(self):
return u'[%d] %s %s %s %s %s' % (self.id, self.source, self.promotion,
self.pipeline, self.customer, self.create_date)
class Product(models.Model):
name = models.CharField(max_length=100)
# Must have lead source!
source = models.ForeignKey(LeadSource)
price = models.DecimalField(max_digits=12, decimal_places=2)
# Product needs a description.
description = models.TextField()
picture = models.ImageField(upload_to=(SITE_ROOT + quot;/_media/product_img/quot;),
height_field=None, width_field=None, blank=True)
def __unicode__(self):
return self.name
class Order(models.Model):
date = models.DateTimeField(auto_now_add=True)
# Must have associated order!
customer = models.ForeignKey(Customer)
# Associated with multiple products through OrderDetails
products = models.ManyToManyField(Product, through='OrderDetail')
total = models.DecimalField(max_digits=12, decimal_places=2, blank=True, null=True)
payment_method = models.CharField(max_length=10, choices=PAYMENT_METHODS)
due_date = models.DateTimeField(blank=True)
pay_date = models.DateTimeField(blank=True, null=True)
def __unicode__(self):
return u'%s, %s' % (self.customer, self.date)
def save(self, *args, **kwargs):
self.due_date = (datetime.datetime.now() +
datetime.timedelta(days=ORDER_DUE))
super(Order, self).save(*args, **kwargs)
class OrderDetail(models.Model):
# Must have an order and a product!
order = models.ForeignKey(Order)
product = models.ForeignKey(Product)
quantity = models.DecimalField(max_digits=12, decimal_places=2)
def __unicode__(self):
return u'%s / %s (%F)' % (self.order, self.product, self.quantity)
CIS591: Analysis Report
37
38. Part III: Design Implementation to Date
HTML template source
My HTML source (the template source code) is below.
index.html
!DOCTYPE html PUBLIC quot;-//W3C//DTD XHTML 1.1//ENquot;
quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtdquot;
html xmlns=quot;http://www.w3.org/1999/xhtmlquot;
head
meta http-equiv=quot;Content-typequot; content=quot;text/xhtml; charset=utf-8quot; /
titleBirdie :: {% block title %}{% endblock %}/title
link rel=quot;stylesheetquot; href=quot;/_media/css/screen.cssquot; type=quot;text/cssquot; /
/head
body
{% include 'includes/header.html' %}
div id=quot;contentquot;
div id=quot;breadcrumbquot;
p class=quot;rightquot;{% block breadcrumb_right %}{% endblock %}/p
p{% block breadcrumb %}{% endblock %}/p
/div
{% block main %}
{% endblock %}
div id=quot;subnavquot;
p class=quot;rightquot;{% block subnav_right %}{% endblock %}/p
p{% block subnav %}{% endblock %}
/div
/div
{% include 'includes/footer.html' %}
/body
/html
header.html
div id=quot;headquot;
div id=quot;wrapquot;
pWelcome, a href=quot;/user/{{ user.userid }}quot;{{ user.first_name }}/a. a href=quot;/
user/{{ user.userid }}/logoutquot;Logout?/a/p
h1a href=quot;/mainquot;img src=quot;/_media/images/logo.pngquot; //a/h1
/div
/div
footer.html
div id=quot;footerquot;
h4Copyright 2009 Kreeger Studios./h4
/div
home.html
{% extends quot;index.htmlquot; %}
{% block title %}
{{ user.first_name }} {{ user.last_name }}
38
CIS591: Analysis Report
39. Part III: Design Implementation to Date
{% endblock %}
{% block breadcrumb_right %}
breadcrumb_right
{% endblock %}
{% block breadcrumb %}
a href=quot;/mainquot;Home/a {{ user.first_name }} {{ user.last_name }} ({{ user.what }})
{% endblock %}
{% block main %}
div class=quot;homequot;
ul
{% ifequal user.what 'Marketer' %}
lia href=quot;active_leadsquot;My Active Leads/a/li
lia href=quot;inactive_leadsquot;My Inactive Leads/a/li
lia href=quot;expired_leadsquot;My Expired Leads/a/li
{% endifequal %}
{% ifequal user.what 'Manager' %}
liManager's links coming soon./li
{% endifequal %}
{% ifequal user.what 'ProcessingRep' %}
liProcessing rep's links coming soon./li
{% endifequal %}
{% ifequal user.what 'Teamleader' %}
lia href=quot;active_leadsquot;My Active Leads/a/li
{% endifequal %}
/ul
/div
{% endblock %}
leads.html
{% extends quot;index.htmlquot; %}
{% block title %}
My {{ status }} leads
{% endblock %}
{% block breadcrumb_right %}
You have {{ count }} {{ status }} leads.
{% endblock %}
{% block breadcrumb %}
a href=quot;/mainquot;Home/a a href=quot;/user/{{ user.userid }}quot;{{ user.first_name }}
{{ user.last_name }}/a My {{ status }} leads
{% endblock %}
{% block main %}
div class=quot;leadsquot;
ul
{% for lead in leads %}
lia href=quot;leads/{{ lead.id }}quot;{{ lead.create_date|date:'n/j/Y, g:sA' }}
{{ lead.source }}
{{ lead.promotion }}
{% ifequal lead.pipeline 'b' %}Buyer{% else %}Non-buyer{%
CIS591: Analysis Report
39