CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-django-crm

Open Source CRM developed on Django framework with REST API for contact, lead, account, and opportunity management

Overview
Eval results
Files

leads.mddocs/

Lead Management

Lead tracking and qualification system for potential customers. Leads represent prospective business opportunities that need to be qualified and potentially converted to accounts and opportunities.

Capabilities

External Lead Creation

Create leads from external websites using API key authentication.

def create_lead_from_site(lead_data: dict, api_key: str) -> dict:
    """
    Create lead from external website or system.

    Args:
        lead_data (dict): Lead information
        api_key (str): API key for authentication (passed as query parameter)

    Returns:
        dict: Created lead details

    Authentication:
        API Key (query parameter: apikey)

    Example:
        POST /api/leads/create-from-site/?apikey=your-api-key
        {
            "first_name": "John",
            "last_name": "Prospect",
            "email": "john@prospect.com",
            "phone": "+1234567890",
            "account_name": "Prospect Company",
            "source": "Website Form",
            "title": "Interested in Product Demo"
        }

        Response:
        {
            "id": "new-lead-uuid",
            "first_name": "John",
            "last_name": "Prospect",
            ...lead details...
        }
    """

Lead Listing and Search

List leads with comprehensive filtering, excluding converted leads.

def list_leads(name: str = None, title: str = None, source: str = None,
              assigned_to: str = None, status: str = None, tags: str = None,
              city: str = None, email: str = None,
              limit: int = 10, offset: int = 0) -> dict:
    """
    List leads with filtering (excludes converted leads).

    Args:
        name (str, optional): Filter by first or last name
        title (str, optional): Filter by lead title
        source (str, optional): Filter by lead source
        assigned_to (str, optional): Filter by assigned user UUID
        status (str, optional): Filter by status ('assigned', 'in process', 'recycled', 'closed')
        tags (str, optional): Filter by tags
        city (str, optional): Filter by city
        email (str, optional): Filter by email
        limit (int): Results per page (default: 10)
        offset (int): Results to skip (default: 0)

    Returns:
        dict: Paginated leads with metadata

    Headers Required:
        Authorization: Bearer <access_token>
        organization-id: <org_uuid>

    Example:
        GET /api/leads/?status=assigned&source=website&limit=5

        Response:
        {
            "open_leads": [
                {
                    "id": "lead-uuid",
                    "title": "Product Demo Request",
                    "first_name": "Jane",
                    "last_name": "Prospect",
                    "email": "jane@prospect.com",
                    "phone": "+1987654321",
                    "status": "assigned",
                    "source": "Website Form",
                    "account_name": "Prospect Corp",
                    "opportunity_amount": "50000.00",
                    "created_on": "2023-01-15T10:30:00Z",
                    "assigned_to": ["user1-uuid"],
                    "tags": ["demo", "qualified"]
                }
            ],
            "closed_leads": [],
            "open_leads_count": 15,
            "closed_leads_count": 3,
            "contacts": [...],
            "users": [...],
            "source_list": ["Website Form", "Cold Call", "Referral", "Trade Show"],
            "tags": [...],
            "status": [...available status options...]
        }
    """

Lead Creation and Auto-Conversion

Create leads with optional automatic conversion to accounts.

def create_lead(lead_data: dict, auto_convert: bool = False) -> dict:
    """
    Create new lead with optional auto-conversion to account.

    Args:
        lead_data (dict): Lead information and associations
        auto_convert (bool): Whether to automatically convert to account

    Returns:
        dict: Created lead (and account if auto-converted)

    Headers Required:
        Authorization: Bearer <access_token>
        organization-id: <org_uuid>
        Content-Type: multipart/form-data (if including attachments)

    Example:
        POST /api/leads/
        {
            "title": "Enterprise Software Inquiry",
            "first_name": "Robert",
            "last_name": "Johnson",
            "email": "robert@bigcorp.com",
            "phone": "+1555987654",
            "status": "assigned",
            "source": "Cold Call",
            "account_name": "Big Corp Industries",
            "website": "https://bigcorp.com",
            "description": "Interested in enterprise solution for 500+ users",
            "opportunity_amount": "75000.00",
            "contacts": ["contact1-uuid"],
            "assigned_to": ["user1-uuid"],
            "teams": ["sales-team-uuid"],
            "tags": ["enterprise", "qualified"],
            "address_line": "789 Corporate Blvd",
            "city": "Dallas",
            "state": "TX",
            "postcode": "75201",
            "country": "USA"
        }

        Response:
        {
            "id": "new-lead-uuid",
            "title": "Enterprise Software Inquiry",
            ...lead details...,
            "converted_account": null  # or account details if auto-converted
        }
    """

Lead Details and Operations

Get comprehensive lead information and perform updates.

def get_lead(pk: str) -> dict:
    """
    Get detailed lead information.

    Args:
        pk (str): Lead UUID

    Returns:
        dict: Complete lead details

    Headers Required:
        Authorization: Bearer <access_token>
        organization-id: <org_uuid>

    Example:
        GET /api/leads/lead-uuid/

        Response:
        {
            "lead_obj": {
                "id": "lead-uuid",
                "title": "Product Demo Request",
                "first_name": "Jane",
                "last_name": "Prospect",
                "email": "jane@prospect.com",
                "phone": "+1987654321",
                "status": "in process",
                "source": "Website Form",
                "account_name": "Prospect Corp",
                "website": "https://prospect.com",
                "description": "Interested in our premium features",
                "opportunity_amount": "50000.00",
                "address_line": "456 Business St",
                "city": "Seattle",
                "state": "WA",
                "postcode": "98101",
                "country": "USA",
                "created_on": "2023-01-15T10:30:00Z",
                "created_by": "user-uuid"
            },
            "address_obj": {...address details...},
            "assigned_to": [...assigned users...],
            "teams": [...assigned teams...],
            "comments": [...lead comments...],
            "attachments": [...lead attachments...],
            "contacts": [...associated contacts...],
            "users_mention": [...users for @mentions...],
            "tags": ["demo", "qualified"]
        }
    """

def update_lead(pk: str, lead_data: dict) -> dict:
    """
    Update lead information.

    Args:
        pk (str): Lead UUID
        lead_data (dict): Updated lead information

    Returns:
        dict: Updated lead details

    Headers Required:
        Authorization: Bearer <access_token>
        organization-id: <org_uuid>

    Example:
        PUT /api/leads/lead-uuid/
        {
            "status": "in process",
            "opportunity_amount": "60000.00",
            "description": "Updated after discovery call"
        }
    """

def delete_lead(pk: str) -> None:
    """
    Delete a lead.

    Args:
        pk (str): Lead UUID

    Returns:
        None: 204 No Content on success

    Headers Required:
        Authorization: Bearer <access_token>
        organization-id: <org_uuid>

    Example:
        DELETE /api/leads/lead-uuid/
    """

Lead Comments and Attachments

Manage lead activity and documentation.

def add_lead_comment_or_attachment(pk: str, comment: str = None,
                                  attachment: file = None) -> dict:
    """
    Add comment or attachment to lead.

    Args:
        pk (str): Lead 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/leads/lead-uuid/
        {
            "comment": "Discovery call scheduled for next Tuesday"
        }
    """

def edit_lead_comment(pk: str, comment: str) -> dict:
    """Edit a lead comment."""

def delete_lead_comment(pk: str) -> None:
    """Delete a lead comment."""

def delete_lead_attachment(pk: str) -> None:
    """Delete a lead attachment."""

Bulk Lead Import

Import multiple leads from file upload.

def upload_leads(leads_file: file) -> dict:
    """
    Bulk upload leads from file.

    Args:
        leads_file (file): CSV or Excel file containing lead data

    Returns:
        dict: Import results and statistics

    Headers Required:
        Authorization: Bearer <access_token>
        organization-id: <org_uuid>
        Content-Type: multipart/form-data

    Example:
        POST /api/leads/upload/
        Form Data:
            leads_file: <file_object>

        Response:
        {
            "status": "success",
            "imported_count": 25,
            "failed_count": 2,
            "errors": [...validation errors for failed rows...]
        }
    """

Company Management

Manage companies associated with leads.

def list_companies() -> dict:
    """
    List companies from leads.

    Returns:
        dict: Companies list

    Headers Required:
        Authorization: Bearer <access_token>
        organization-id: <org_uuid>

    Example:
        GET /api/leads/companies/

        Response:
        {
            "companies": [
                {
                    "id": "company-uuid",
                    "name": "Tech Corp",
                    "industry": "Technology",
                    "website": "https://techcorp.com"
                }
            ]
        }
    """

def create_company(company_data: dict) -> dict:
    """
    Create new company.

    Args:
        company_data (dict): Company information

    Returns:
        dict: Created company details

    Headers Required:
        Authorization: Bearer <access_token>
        organization-id: <org_uuid>

    Example:
        POST /api/leads/companies/
        {
            "name": "New Tech Startup",
            "industry": "Software",
            "website": "https://newtechstartup.com"
        }
    """

def get_company(pk: str) -> dict:
    """
    Get company details.

    Args:
        pk (str): Company UUID

    Returns:
        dict: Company information

    Headers Required:
        Authorization: Bearer <access_token>

    Example:
        GET /api/leads/company/company-uuid/
    """

Lead Data Types

class Lead:
    """Lead model for potential customers"""
    id: str  # UUID
    title: str  # Lead title/subject
    first_name: str  # Required
    last_name: str  # Required
    email: str  # Contact email
    phone: str  # Contact phone
    status: str  # Lead status
    source: str  # How lead was acquired
    account_name: str  # Prospective company name
    website: str  # Company website
    description: str  # Lead details
    opportunity_amount: decimal  # Potential deal value

    # Address information
    address_line: str
    street: str
    city: str
    state: str
    postcode: str
    country: str

    # 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 LeadStatus:
    """Lead status options"""
    ASSIGNED: str = "assigned"
    IN_PROCESS: str = "in process"
    CONVERTED: str = "converted"  # Converted to account (filtered from lists)
    RECYCLED: str = "recycled"
    CLOSED: str = "closed"

class LeadSource:
    """Common lead sources"""
    WEBSITE: str = "Website Form"
    COLD_CALL: str = "Cold Call"
    REFERRAL: str = "Referral"
    TRADE_SHOW: str = "Trade Show"
    EMAIL_CAMPAIGN: str = "Email Campaign"
    SOCIAL_MEDIA: str = "Social Media"
    ADVERTISEMENT: str = "Advertisement"

class Company:
    """Company information from leads"""
    id: str  # UUID
    name: str  # Company name
    industry: str  # Industry type
    website: str  # Company website
    created_from_lead: str  # Lead UUID that created company

Lead Lifecycle

  1. Lead Creation: From external forms, manual entry, or imports
  2. Assignment: Assign to sales team members
  3. Qualification: Update status to "in process" and gather information
  4. Conversion: Convert qualified leads to accounts and opportunities
  5. Closure: Mark unqualified leads as "closed" or "recycled"

Converted leads are filtered out of standard lead lists but remain in the system for historical tracking.

Integration Features

  • External API: Allows website forms and other systems to create leads
  • Bulk Import: CSV/Excel import for large lead lists
  • Auto-Conversion: Automatic account creation for qualified leads
  • Tag System: Custom categorization and organization
  • Assignment Rules: Distribute leads to appropriate team members

Install with Tessl CLI

npx tessl i tessl/pypi-django-crm

docs

accounts.md

authentication.md

cases.md

contacts.md

documents.md

events.md

index.md

invoices.md

leads.md

opportunities.md

tasks.md

teams.md

tile.json