Open Source CRM developed on Django framework with REST API for contact, lead, account, and opportunity management
Sales opportunity tracking with deal stages, probability management, and revenue forecasting. Opportunities represent specific sales deals being pursued with accounts and contacts.
List opportunities with filtering by various criteria.
def list_opportunities(name: str = None, account: str = None, stage: str = None,
lead_source: str = None, tags: str = None,
limit: int = 10, offset: int = 0) -> dict:
"""
List opportunities with filtering.
Args:
name (str, optional): Filter by opportunity name
account (str, optional): Filter by account name
stage (str, optional): Filter by sales stage
lead_source (str, optional): Filter by lead source
tags (str, optional): Filter by tags
limit (int): Results per page (default: 10)
offset (int): Results to skip (default: 0)
Returns:
dict: Paginated opportunities with metadata
Headers Required:
Authorization: Bearer <access_token>
organization-id: <org_uuid>
Example:
GET /api/opportunities/?stage=QUALIFICATION&limit=5
Response:
{
"count": 20,
"next": "/api/opportunities/?limit=5&offset=5",
"previous": null,
"results": [
{
"id": "opp-uuid",
"name": "Enterprise Software Deal",
"account": "ACME Corporation",
"stage": "QUALIFICATION",
"amount": "75000.00",
"currency": "USD",
"probability": 25,
"expected_close_date": "2023-03-15",
"lead_source": "Cold Call",
"created_on": "2023-01-15T10:30:00Z",
"assigned_to": ["user1-uuid"],
"tags": ["enterprise", "software"]
}
],
"accounts_list": [...],
"contacts_list": [...],
"users": [...],
"teams": [...]
}
"""Create new sales opportunities with comprehensive details.
def create_opportunity(opportunity_data: dict) -> dict:
"""
Create new opportunity.
Args:
opportunity_data (dict): Opportunity information and associations
Returns:
dict: Created opportunity details
Headers Required:
Authorization: Bearer <access_token>
organization-id: <org_uuid>
Content-Type: multipart/form-data (if including attachments)
Example:
POST /api/opportunities/
{
"name": "Q1 Software License Deal",
"account": "account-uuid",
"stage": "NEEDS ANALYSIS",
"amount": "125000.00",
"currency": "USD",
"probability": 40,
"expected_close_date": "2023-04-30",
"lead_source": "Referral",
"description": "Annual software licensing opportunity",
"contacts": ["contact1-uuid", "contact2-uuid"],
"assigned_to": ["user1-uuid"],
"teams": ["sales-team-uuid"],
"tags": ["software", "annual-contract"]
}
Response:
{
"id": "new-opp-uuid",
"name": "Q1 Software License Deal",
...opportunity details...
}
"""Get comprehensive opportunity information and perform updates.
def get_opportunity(pk: str) -> dict:
"""
Get detailed opportunity information.
Args:
pk (str): Opportunity UUID
Returns:
dict: Complete opportunity details
Headers Required:
Authorization: Bearer <access_token>
organization-id: <org_uuid>
Example:
GET /api/opportunities/opp-uuid/
Response:
{
"opportunity_obj": {
"id": "opp-uuid",
"name": "Enterprise Software Deal",
"account": "account-uuid",
"stage": "VALUE PROPOSITION",
"amount": "75000.00",
"currency": "USD",
"probability": 60,
"expected_close_date": "2023-03-15",
"actual_close_date": null,
"lead_source": "Cold Call",
"description": "Enterprise software solution for 200+ users",
"created_on": "2023-01-15T10:30:00Z",
"created_by": "user-uuid"
},
"account_obj": {...account details...},
"contacts": [...associated contacts...],
"assigned_to": [...assigned users...],
"teams": [...assigned teams...],
"comments": [...opportunity comments...],
"attachments": [...opportunity attachments...],
"users_mention": [...users for @mentions...],
"tags": ["enterprise", "software"]
}
"""
def update_opportunity(pk: str, opportunity_data: dict) -> dict:
"""
Update opportunity information.
Args:
pk (str): Opportunity UUID
opportunity_data (dict): Updated opportunity information
Returns:
dict: Updated opportunity details
Headers Required:
Authorization: Bearer <access_token>
organization-id: <org_uuid>
Example:
PUT /api/opportunities/opp-uuid/
{
"stage": "PROPOSAL/QUOTATION",
"probability": 75,
"amount": "80000.00"
}
"""
def delete_opportunity(pk: str) -> None:
"""
Delete an opportunity.
Args:
pk (str): Opportunity UUID
Returns:
None: 204 No Content on success
Headers Required:
Authorization: Bearer <access_token>
organization-id: <org_uuid>
Example:
DELETE /api/opportunities/opp-uuid/
"""Manage opportunity activity and supporting documents.
def add_opportunity_comment_or_attachment(pk: str, comment: str = None,
attachment: file = None) -> dict:
"""
Add comment or attachment to opportunity.
Args:
pk (str): Opportunity UUID
comment (str, optional): Comment text
attachment (file, optional): File to attach
Returns:
dict: Success response
Headers Required:
Authorization: Bearer <access_token>
organization-id: <org_uuid>
Content-Type: multipart/form-data (for attachments)
Example:
POST /api/opportunities/opp-uuid/
{
"comment": "Proposal submitted, awaiting client review"
}
"""
def edit_opportunity_comment(pk: str, comment: str) -> dict:
"""Edit an opportunity comment."""
def delete_opportunity_comment(pk: str) -> None:
"""Delete an opportunity comment."""
def delete_opportunity_attachment(pk: str) -> None:
"""Delete an opportunity attachment."""class Opportunity:
"""Opportunity model for sales deals"""
id: str # UUID
name: str # Opportunity name (required)
account: str # Account UUID (required)
stage: str # Sales stage
amount: decimal # Deal value
currency: str # Currency code (default: USD)
probability: int # Win probability (0-100%)
expected_close_date: date # Projected close date
actual_close_date: date # Actual close date (when closed)
lead_source: str # Original lead source
description: str # Opportunity details
# Metadata
created_on: datetime
created_by: str # User UUID
org: str # Organization UUID
# Associations
contacts: list[str] # Contact UUIDs
assigned_to: list[str] # User UUIDs
teams: list[str] # Team UUIDs
tags: list[str] # Tag names
class OpportunityStage:
"""Sales stages for opportunity pipeline"""
QUALIFICATION: str = "QUALIFICATION"
NEEDS_ANALYSIS: str = "NEEDS ANALYSIS"
VALUE_PROPOSITION: str = "VALUE PROPOSITION"
PROPOSAL_QUOTATION: str = "PROPOSAL/QUOTATION"
NEGOTIATION_REVIEW: str = "NEGOTIATION/REVIEW"
CLOSED_WON: str = "CLOSED WON"
CLOSED_LOST: str = "CLOSED LOST"
class Currency:
"""Supported currencies"""
USD: str = "USD"
EUR: str = "EUR"
GBP: str = "GBP"
# Additional currencies as configured
class OpportunityComment:
"""Comments on opportunities"""
id: str # UUID
comment: str
opportunity: str # Opportunity UUID
commented_on: datetime
commented_by: str # User UUID
class OpportunityAttachment:
"""File attachments on opportunities"""
id: str # UUID
attachment: str # File path/URL
opportunity: str # Opportunity UUID
created_on: datetime
created_by: str # User UUIDOpportunities follow a structured sales process:
Each stage typically corresponds to increasing probability percentages and advancing close dates.
Opportunities support revenue forecasting through:
Weighted forecasting can be calculated as: Amount × Probability = Weighted Value
Install with Tessl CLI
npx tessl i tessl/pypi-django-crm