Kulcare Docs
DeveloperAuthentication Documentation04 featuresRevenue sharing commissions

Revenue Sharing & Commission System - Complete Backend Documentation

Last Updated: January 2025 Status: ✅ Implemented and Production Ready Version: 2.0 (Verified Implementation)


Table of Contents

  1. Overview
  2. Architecture
  3. Database Schema
  4. Core Models
  5. API Endpoints
  6. Business Logic (Interactors)
  7. Background Jobs & Automation
  8. Testing
  9. Deployment & Configuration
  10. Pending Features & Future Enhancements

Overview

The Revenue Sharing & Commission System provides comprehensive functionality for managing:

  • Doctor Commissions: Individual earnings based on consultations and services
  • Revenue Sharing: Multi-stakeholder business revenue distribution
  • Settlements: Monthly aggregation and payment processing
  • Commission Rules: Flexible percentage, fixed, and tiered commission structures
  • Analytics & Reporting: Comprehensive financial dashboards
  • Automated Workflows: Scheduled calculations and notifications

Verified Implemented Features

✅ Commission Management:

  • Commission rule management with percentage, fixed, and tiered types
  • Commission calculations (manual and automated)
  • Commission workflows (automated daily/weekly/monthly processing)
  • Commission dashboard with analytics
  • Approval workflow
  • Payment tracking
  • Export functionality

✅ Revenue Sharing:

  • Clinic stakeholder management
  • Revenue share configurations
  • Stakeholder distribution setup

✅ Financial Reports:

  • Revenue analysis reports
  • Period comparison reports
  • Location comparison reports
  • Consolidated reports
  • Export functionality (CSV/Excel/PDF)
  • Report export history

Architecture

Parts-Based Modular Structure

backend/
├── parts/
│   ├── clinic/
│   │   ├── models/          # Stakeholders, commission rules, configurations
│   │   ├── controllers/     # Stakeholder, configuration, rule management
│   │   ├── interactors/     # Business logic for clinic-level operations
│   │   └── serializers/     # JSON response formatting
│   └── billing/
│       ├── models/          # Calculations, settlements, distributions
│       ├── controllers/     # Dashboards, payments, reports
│       ├── interactors/     # Commission processing, settlements
│       └── serializers/     # Financial data formatting

Design Patterns

  1. Interactor Pattern: All business logic encapsulated in interactors
  2. Service Objects: Complex calculations in service classes
  3. Serializers: Consistent API response formatting
  4. Background Jobs: Sidekiq for async processing
  5. Pundit Policies: Authorization and access control

Database Schema

Core Tables

1. Clinic Stakeholders

create_table :clinic_stakeholders do |t|
  t.references :clinic, null: false, foreign_key: true
  t.references :user, null: true, foreign_key: true
  t.string :name, null: false
  t.string :email
  t.string :phone_number
  t.string :country_code, default: '+91'
  t.string :stakeholder_type # owner, partner, investor, referrer, platform
  t.string :status, default: 'active' # active, inactive, invited, pending
  t.timestamp :invited_at
  t.boolean :deleted, default: false
  t.timestamp :deleted_at
  t.string :photo
  t.timestamps
end

2. Clinic Revenue Share Configurations

create_table :clinic_revenue_share_configs do |t|
  t.references :clinic, null: false, foreign_key: true
  t.references :clinic_group, null: true, foreign_key: true
  t.string :configuration_name, null: false
  t.text :description
  t.jsonb :distribution_rules, null: false, default: {}
  t.jsonb :approval_workflow_config, default: {}
  t.datetime :effective_from, null: false
  t.datetime :effective_until
  t.string :status, default: 'draft' # draft, active, inactive, archived
  t.references :created_by_user, null: false
  t.references :updated_by_user
  t.references :approved_by_user
  t.datetime :approved_at
  t.timestamps
end

3. Clinic Revenue Stakeholders

create_table :clinic_revenue_stakeholders do |t|
  t.references :clinic_revenue_share_config, null: false
  t.references :clinic, null: false
  t.references :clinic_stakeholder, null: true # null for platform fees
  t.references :parent_stakeholder # for hierarchical distributions
  t.decimal :share_percentage, precision: 5, scale: 2
  t.decimal :share_amount, precision: 10, scale: 2
  t.decimal :minimum_amount, precision: 10, scale: 2, default: 0
  t.decimal :maximum_amount, precision: 10, scale: 2
  t.references :billing_account
  t.string :payout_method, default: 'bank_transfer'
  t.integer :priority, default: 0
  t.boolean :active, default: true
  t.timestamps
end

4. Commission Rules

create_table :clinic_commission_rules do |t|
  t.references :clinic, null: false
  t.references :clinic_group
  t.references :basic_commission_rule_type, null: false
  t.string :rule_name, null: false
  t.text :rule_description
  t.decimal :commission_percentage, precision: 5, scale: 2
  t.decimal :fixed_amount, precision: 10, scale: 2
  t.datetime :effective_from, null: false
  t.datetime :effective_to
  t.integer :priority, default: 0
  t.boolean :active, default: true
  t.boolean :applies_to_all_services, default: true
  t.references :created_by_user, null: false
  t.references :updated_by_user
  t.references :role
  t.boolean :deleted, default: false
  t.datetime :deleted_at
  t.timestamps
end

5. Commission Tiers (for tiered rules)

create_table :commission_tiers do |t|
  t.references :clinic_commission_rule, null: false
  t.string :tier_name, null: false
  t.decimal :min_amount, precision: 10, scale: 2, null: false
  t.decimal :max_amount, precision: 10, scale: 2
  t.decimal :commission_percentage, precision: 5, scale: 2
  t.decimal :commission_fixed_amount, precision: 10, scale: 2
  t.integer :tier_order, null: false
  t.boolean :active, default: true
  t.timestamps
end

6. Commission Calculations

create_table :commission_calculations do |t|
  t.references :clinic, null: false
  t.references :clinic_doctor, null: false
  t.references :appointment
  t.references :billing_payment
  t.references :clinic_patient_service
  t.references :clinic_commission_rule
  t.references :basic_service_type
  t.decimal :gross_amount, precision: 10, scale: 2, null: false
  t.decimal :commission_percentage_used, precision: 5, scale: 2
  t.decimal :fixed_amount_used, precision: 10, scale: 2
  t.decimal :calculated_commission, precision: 10, scale: 2, null: false
  t.string :status, default: 'CALCULATED' # CALCULATED, APPROVED, PAID, CANCELLED
  t.string :calculation_method # percentage, fixed, tiered
  t.datetime :calculated_at, null: false
  t.datetime :approved_at
  t.references :approved_by_user
  t.datetime :paid_at
  t.references :billing_transfer
  t.references :commission_settlement
  t.text :notes
  t.timestamps
end

7. Commission Settlements

create_table :commission_settlements do |t|
  t.references :clinic_doctor, null: false
  t.references :clinic, null: false
  t.references :clinic_group
  t.string :settlement_period, null: false # YYYY-MM
  t.date :period_start, null: false
  t.date :period_end, null: false
  t.decimal :total_earnings, precision: 10, scale: 2, null: false
  t.decimal :total_deductions, precision: 10, scale: 2, default: 0
  t.decimal :net_amount, precision: 10, scale: 2, null: false
  t.string :status, default: 'pending' # pending, approved, processing, paid, cancelled
  t.date :paid_on
  t.string :payment_reference
  t.text :notes
  t.references :approved_by_user
  t.datetime :approved_at
  t.references :billing_transfer
  t.references :commission_workflow
  t.timestamps
end

8. Commission Workflows

create_table :commission_workflows do |t|
  t.references :clinic, null: false
  t.string :commission_type, null: false # COMMISSION_CALCULATION, SETTLEMENT_GENERATION
  t.string :schedule_frequency, null: false # DAILY, WEEKLY, MONTHLY
  t.time :schedule_time
  t.date :last_run_date
  t.datetime :last_run_at
  t.string :current_status, default: 'RUNNING'
  t.boolean :enabled, default: true
  t.references :created_by_user
  t.timestamps
end

9. Revenue Distribution Queue

create_table :revenue_distribution_queue do |t|
  t.references :clinic, null: false
  t.references :clinic_group
  t.decimal :amount, precision: 10, scale: 2, null: false
  t.string :source_type, null: false # ClinicPatientPayment, etc.
  t.integer :source_id, null: false
  t.string :status, default: 'pending_distribution'
  t.datetime :revenue_date, null: false
  t.datetime :distributed_at
  t.text :notes
  t.timestamps
end

10. Revenue Share Calculations

create_table :revenue_share_calculations do |t|
  t.references :clinic_revenue_share_config, null: false
  t.references :clinic, null: false
  t.datetime :period_start, null: false
  t.datetime :period_end, null: false
  t.decimal :total_revenue, precision: 12, scale: 2, null: false
  t.decimal :distributable_revenue, precision: 12, scale: 2, null: false
  t.decimal :platform_fees, precision: 10, scale: 2, default: 0
  t.jsonb :calculation_details, default: {}
  t.jsonb :distribution_summary, default: {}
  t.string :status, default: 'calculated'
  t.datetime :calculated_at
  t.datetime :approved_at
  t.datetime :processed_at
  t.jsonb :error_details
  t.references :created_by_user
  t.timestamps
end

Reference Tables

Basic Commission Rule Types

create_table :basic_commission_rule_types do |t|
  t.string :name, null: false, unique: true
  t.string :display_name, null: false
  t.text :description
  t.boolean :requires_percentage, default: false
  t.boolean :requires_fixed_amount, default: false
  t.boolean :requires_tiers, default: false
  t.boolean :active, default: true
  t.timestamps
end

# Seeded values:
# - percentage: "Percentage Commission"
# - fixed: "Fixed Amount Commission"

Basic Service Types

create_table :basic_service_types do |t|
  t.string :name, null: false, unique: true
  t.string :display_name, null: false
  t.text :description
  t.boolean :active, default: true
  t.timestamps
end

# Seeded values:
# - consultation: "Consultation"
# - telemedicine: "Telemedicine"
# - others: "Others"

Database Schema Diagram

Entity Relationship Diagrams

Diagram 1: Core Entities & Master Data

Diagram 2: Stakeholders & Revenue Sharing

Diagram 3: Commission Rules & Tiers (VERIFIED: Tiered Support Implemented)

Diagram 4: Commission Calculations & Settlements

Key Tables Overview

Master Data (Reference Tables):

  • basic_commission_rule_types - Commission calculation methods (percentage, fixed, tiered)
  • basic_service_types - Medical service categories (consultation, procedure, lab_test, imaging, pharmacy, others)

Stakeholder Management:

  • clinic_stakeholders - All stakeholders (owners, partners, investors, referrers, platform)
  • clinic_revenue_share_configs - Revenue sharing configuration templates
  • clinic_revenue_stakeholders - Links stakeholders to configs with percentages

Commission System:

  • clinic_commission_rules - Commission calculation rules
  • commission_tiers - VERIFIED IMPLEMENTED - Tiered commission structures
  • commission_rule_service_types - Maps rules to service types
  • clinic_commission_assignments - Maps rules to doctors/staff (polymorphic)

Transaction Processing:

  • commission_calculations - Individual commission calculations per appointment
  • commission_settlements - Monthly settlement aggregations
  • commission_workflows - Automated workflow configurations
  • revenue_share_calculations - Revenue distribution calculations

Background Jobs (VERIFIED: Exist in codebase):

  • CommissionCalculationJob (parts/clinic/services/commission_calculation_job.rb)
  • CalculateCommissionJob (parts/clinic/services/calculate_commission_job.rb)
  • CommissionWorkflowExecutionJob (parts/billing/services/commission_workflow_execution_job.rb)
  • RunCommissionWorkflowsJob (parts/billing/services/run_commission_workflows_job.rb)

Schema Features

Verified Implemented:

  • Commission tiers table (migration: 20250901132225_create_commission_tiers.rb)
  • Tiered commission calculation with calculate_tiered_commission method
  • Commission workflows with DAILY/WEEKLY/MONTHLY scheduling
  • Revenue share stakeholders with hierarchical support (parent_stakeholder_id)
  • Polymorphic commission assignments for doctors and staff

Status Enumerations:

  • Commission Calculation: CALCULATED, APPROVED, PAID, CANCELLED
  • Commission Settlement: pending, approved, processing, paid, cancelled
  • Commission Workflow: RUNNING, SUCCESS, FAILED
  • Revenue Share Config: draft, active, inactive, archived
  • Stakeholder: active, inactive, invited, pending

Core Models

ClinicStakeholder

class ClinicStakeholder < ApplicationRecord
  belongs_to :clinic
  belongs_to :user, optional: true
  has_many :clinic_revenue_stakeholders, dependent: :destroy

  validates :name, presence: true
  validates :stakeholder_type, inclusion: { in: %w[owner partner investor referrer platform] }
  validates :status, inclusion: { in: %w[active inactive invited pending] }

  scope :active, -> { where(status: 'active', deleted: false) }
  scope :by_type, ->(type) { where(stakeholder_type: type) }

  def deactivate!
    update!(status: 'inactive')
    clinic_revenue_stakeholders.update_all(active: false)
  end
end

ClinicRevenueShareConfig

class ClinicRevenueShareConfig < ApplicationRecord
  belongs_to :clinic
  belongs_to :created_by_user, class_name: 'User'
  has_many :clinic_revenue_stakeholders, dependent: :destroy
  has_many :revenue_share_calculations, dependent: :restrict_with_error

  validates :configuration_name, presence: true, uniqueness: { scope: :clinic_id }
  validates :effective_from, presence: true
  validate :validate_stakeholder_percentages

  scope :active, -> { where(status: 'active') }
  scope :effective_on, ->(date) {
    active.where('effective_from <= ?', date)
          .where('effective_until IS NULL OR effective_until >= ?', date)
  }

  def activate!
    transaction do
      clinic.clinic_revenue_share_configs.where.not(id: id).active.update_all(status: 'inactive')
      update!(status: 'active', approved_at: Time.current)
    end
  end

  def total_percentage_allocated
    clinic_revenue_stakeholders.where(parent_stakeholder_id: nil).sum(:share_percentage)
  end

  def calculate_distribution(amount, context = {})
    # Returns hash of {stakeholder_id => {stakeholder:, amount:}}
  end
end

ClinicCommissionRule

class ClinicCommissionRule < ApplicationRecord
  belongs_to :clinic
  belongs_to :basic_commission_rule_type
  belongs_to :created_by_user, class_name: 'User'
  has_many :commission_rule_service_types, dependent: :destroy
  has_many :basic_service_types, through: :commission_rule_service_types
  has_many :clinic_commission_assignments, dependent: :destroy
  has_many :clinic_doctors, through: :clinic_commission_assignments
  has_many :commission_tiers, dependent: :destroy
  has_many :commission_calculations, dependent: :restrict_with_error

  after_create :ensure_commission_workflow_exists

  validates :rule_name, presence: true
  validates :effective_from, presence: true

  scope :active, -> { where(active: true, deleted: false) }
  scope :effective_on, ->(date) {
    active.where('effective_from <= ?', date)
          .where('effective_to IS NULL OR effective_to >= ?', date)
  }

  def calculate_commission(amount, service_type_id = nil)
    case basic_commission_rule_type.name
    when 'percentage' then calculate_percentage_commission(amount)
    when 'fixed' then fixed_amount
    when 'tiered' then calculate_tiered_commission(amount)
    else 0
    end
  end

  def percentage_type?
    basic_commission_rule_type&.name == 'percentage'
  end

  def fixed_type?
    basic_commission_rule_type&.name == 'fixed'
  end

  def tiered_type?
    basic_commission_rule_type&.name == 'tiered'
  end
end

CommissionCalculation

class CommissionCalculation < ApplicationRecord
  belongs_to :clinic
  belongs_to :clinic_doctor
  belongs_to :appointment, optional: true
  belongs_to :clinic_commission_rule, optional: true
  belongs_to :commission_settlement, optional: true

  validates :gross_amount, presence: true
  validates :calculated_commission, presence: true
  validates :status, inclusion: { in: %w[CALCULATED APPROVED PAID CANCELLED] }

  scope :calculated, -> { where(status: 'CALCULATED') }
  scope :approved, -> { where(status: 'APPROVED') }
  scope :paid, -> { where(status: 'PAID') }
  scope :pending_payment, -> { where(status: %w[CALCULATED APPROVED]) }

  def approve!(user)
    update!(status: 'APPROVED', approved_at: Time.current, approved_by_user: user)
  end

  def mark_as_paid!(billing_transfer)
    update!(status: 'PAID', paid_at: Time.current, billing_transfer: billing_transfer)
  end
end

CommissionSettlement

class CommissionSettlement < ApplicationRecord
  STATUSES = %w[pending approved processing paid cancelled].freeze

  belongs_to :clinic_doctor
  belongs_to :clinic
  has_many :commission_calculations

  validates :settlement_period, uniqueness: { scope: :clinic_doctor_id }
  validates :status, inclusion: { in: STATUSES }

  scope :pending_approval, -> { where(status: 'pending') }
  scope :approved, -> { where(status: 'approved') }
  scope :paid, -> { where(status: 'paid') }

  def self.generate_for_period(clinic_doctor, start_date, end_date)
    # Creates settlement and links calculations
  end

  def approve!(user)
    update!(status: 'approved', approved_at: Time.current, approved_by_user: user)
  end

  def mark_paid!(payment_reference, billing_transfer = nil)
    update!(status: 'paid', paid_on: Date.current, payment_reference: payment_reference)
    commission_calculations.update_all(status: 'PAID', paid_at: Time.current)
  end

  def can_be_paid?
    status == 'approved' && net_amount > 0
  end
end

API Endpoints

Clinic Stakeholders APIs

List Stakeholders

GET /clinics/:clinic_id/clinic_stakeholders

Response:

{
  "success": true,
  "data": {
    "clinic_stakeholders": [
      {
        "id": 1,
        "name": "Dr. John Doe",
        "email": "john@example.com",
        "phone_number": "9876543210",
        "country_code": "+91",
        "stakeholder_type": "owner",
        "status": "active"
      }
    ]
  }
}

Create Stakeholder

POST /clinics/:clinic_id/clinic_stakeholders
Content-Type: application/json

{
  "name": "Jane Smith",
  "email": "jane@example.com",
  "stakeholder_type": "partner",
  "phone_number": "9876543211"
}

Delete Stakeholder

DELETE /clinics/:clinic_id/clinic_stakeholders/:id

Revenue Share Configuration APIs

List Configurations

GET /clinics/:clinic_id/revenue_share_configurations

Response:

{
  "success": true,
  "data": {
    "revenue_share_configurations": [
      {
        "id": 1,
        "configuration_name": "Standard Revenue Distribution",
        "status": "active",
        "effective_from": "2025-01-01",
        "total_percentage_allocated": "100.0",
        "stakeholders": [
          {
            "id": 1,
            "stakeholder_name": "Kulcare Platform",
            "stakeholder_type": "platform",
            "share_percentage": "5.0"
          },
          {
            "id": 2,
            "stakeholder_name": "John Doe",
            "stakeholder_type": "owner",
            "share_percentage": "60.0"
          }
        ]
      }
    ]
  }
}

Create Configuration

POST /clinics/:clinic_id/revenue_share_configurations
Content-Type: application/json

{
  "configuration_name": "New Revenue Distribution",
  "description": "Updated revenue sharing model",
  "effective_from": "2025-02-01",
  "stakeholders": [
    {
      "stakeholder_id": 2,
      "share_percentage": 60.0
    },
    {
      "stakeholder_id": 3,
      "share_percentage": 40.0
    }
  ],
  "distribution_rules": {
    "distribution_frequency": "monthly",
    "auto_approval_threshold": 50000
  }
}

Activate Configuration

POST /clinics/:clinic_id/revenue_share_configurations/:id/activate

Commission Rules APIs

List Rules

GET /clinics/:clinic_id/commission_rules?page=1&per_page=20

Query Parameters:

  • page (optional): Page number
  • per_page (optional): Items per page
  • rule_type_id (optional): Filter by rule type
  • service_type_id (optional): Filter by service type
  • search_text (optional): Search in rule names

Response:

{
  "success": true,
  "data": {
    "commission_rules": [
      {
        "id": 1,
        "rule_name": "Standard Consultation",
        "commission_percentage": "30.0",
        "effective_from": "2024-01-01",
        "active": true,
        "basic_commission_rule_type": {
          "id": 1,
          "name": "percentage",
          "display_name": "Percentage Commission"
        },
        "basic_service_types": [...],
        "clinic_doctors": [...]
      }
    ]
  },
  "total_records": 5,
  "total_pages": 1
}

Create Rule (Percentage)

POST /clinics/:clinic_id/commission_rules
Content-Type: application/json

{
  "basic_commission_rule_type_id": 1,
  "rule_name": "Senior Doctor Commission",
  "commission_percentage": 80.0,
  "applies_to_all_services": false,
  "basic_service_type_ids": [1, 2],
  "clinic_doctor_ids": [456, 789],
  "priority": 1
}

Create Rule (Tiered)

POST /clinics/:clinic_id/commission_rules
Content-Type: application/json

{
  "basic_commission_rule_type_id": 3,
  "rule_name": "Tiered Revenue Commission",
  "tiers": [
    {
      "tier_name": "Bronze",
      "min_amount": 0,
      "max_amount": 25000,
      "commission_percentage": 15.0
    },
    {
      "tier_name": "Silver",
      "min_amount": 25001,
      "max_amount": 50000,
      "commission_percentage": 20.0
    },
    {
      "tier_name": "Gold",
      "min_amount": 50001,
      "max_amount": null,
      "commission_percentage": 25.0
    }
  ],
  "clinic_doctor_ids": [123, 456]
}

Commission Calculations APIs

List Calculations

GET /clinics/:clinic_id/commission_calculations?start_date=2025-01-01&end_date=2025-01-31

Query Parameters:

  • start_date (required): Start date (YYYY-MM-DD)
  • end_date (required): End date (YYYY-MM-DD)
  • clinic_doctor_id (optional): Filter by doctor
  • status (optional): Filter by status
  • page (optional): Page number
  • per_page (optional): Items per page

Calculate Batch

POST /clinics/:clinic_id/commission_calculations/calculate_batch
Content-Type: application/json

{
  "start_date": "2025-01-01",
  "end_date": "2025-01-31",
  "clinic_doctor_ids": [1, 2, 3],
  "recalculate": false
}

Commission Dashboard APIs

Overview

GET /clinics/:clinic_id/commission_dashboard

Response:

{
  "success": true,
  "data": {
    "summary": {
      "total_revenue": 150000.0,
      "total_commission": 45000.0,
      "appointment_count": 120,
      "average_commission_rate": 30.0
    },
    "period": {
      "start": "2025-01-01",
      "end": "2025-01-31"
    },
    "calculations": [...],
    "pagination": {...}
  }
}

Analytics

GET /clinics/:clinic_id/commission_analytics?period=2025-01

Settlement APIs

List Settlements

GET /clinics/:clinic_id/settlements?period=2025-01&status=pending

Response:

{
  "success": true,
  "data": {
    "settlements": [
      {
        "id": 1,
        "settlement_period": "2025-01",
        "clinic_doctor_id": 7,
        "doctor_name": "Dr. Smith",
        "total_earnings": "35000.0",
        "net_amount": "35000.0",
        "status": "pending",
        "calculation_count": 45
      }
    ],
    "pending_amount": "100000.0",
    "approved_amount": "50000.0"
  }
}

Generate Monthly Settlements

POST /settlements/generate
Content-Type: application/json

{
  "clinic_id": 123,
  "period": "2025-01"
}

Approve Settlement

POST /settlements/:id/approve
Content-Type: application/json

{
  "notes": "Approved after review"
}

Process Payment

POST /settlements/:id/process_payment
Content-Type: application/json

{
  "payment_method": "bank_transfer",
  "notes": "Payment processed via NEFT"
}

Commission Workflows APIs

List Workflows

GET /clinics/:clinic_id/commission_workflows

Response:

{
  "success": true,
  "data": {
    "commission_workflows": [
      {
        "id": 1,
        "commission_type": "COMMISSION_CALCULATION",
        "schedule_frequency": "DAILY",
        "schedule_time": "06:00:00",
        "current_status": "RUNNING",
        "enabled": true,
        "last_run_at": "2025-01-15T06:00:00Z"
      }
    ]
  }
}

Update Workflow

PUT /clinics/:clinic_id/commission_workflows/:id
Content-Type: application/json

{
  "enabled": true,
  "schedule_time": "08:00:00"
}

Revenue Distribution Queue APIs

List Queue Entries

GET /clinics/:clinic_id/revenue_distribution_queue?status=pending&page=1

Export Queue

GET /clinics/:clinic_id/revenue_distribution_queue/export?format=csv

Revenue Share Calculations APIs

List Calculations

GET /clinics/:clinic_id/revenue_share_calculations?period=2025-01

Show Calculation Details

GET /clinics/:clinic_id/revenue_share_calculations/:id

Meta Data APIs

Get Basic Service Types

GET /basic_service_types

Response:

{
  "success": true,
  "data": [
    {
      "id": 1,
      "name": "consultation",
      "display_name": "Consultation",
      "active": true
    }
  ]
}

Get Basic Commission Rule Types

GET /basic_commission_rule_types

Business Logic (Interactors)

Commission Calculation Flow

# parts/billing/interactors/commissions/calculate_batch.rb
module Commissions
  class CalculateBatch < BaseInteractor
    def call
      require_context(:clinic_id, :start_date, :end_date)

      validate_inputs
      create_job_record
      process_calculations
      generate_summaries
    end

    private

    def process_calculations
      appointments.find_each do |appointment|
        CommissionCalculationService.calculate_for_appointment(appointment)
      end
    end
  end
end

Settlement Generation Flow

# parts/billing/interactors/settlements/generate_monthly.rb
module Settlements
  class GenerateMonthly < BaseInteractor
    def call
      require_context(:clinic_id)

      validate_inputs
      generate_commission_settlements
      generate_revenue_share_calculations
    end

    private

    def generate_commission_settlements
      clinic_doctors.each do |clinic_doctor|
        settlement = CommissionSettlement.generate_for_period(
          clinic_doctor, period_start, period_end
        )
        context.commission_settlements << settlement if settlement
      end
    end
  end
end

Revenue Share Configuration Flow

# parts/clinic/interactors/revenue_share/create_configuration.rb
module RevenueShare
  class CreateConfiguration < BaseInteractor
    def call
      require_context(:clinic_id, :configuration_name, :stakeholders)

      validate_clinic
      validate_stakeholders
      create_configuration
      create_stakeholder_assignments
    end
  end
end

Background Jobs & Automation

Daily Commission Calculation

# lib/tasks/daily_revenue_calculation.rake
namespace :revenue do
  desc "Calculate daily commissions for all active clinics"
  task calculate_daily_commissions: :environment do
    Clinic.active.where(commission_enabled: true).find_each do |clinic|
      Commissions::CalculateBatch.call(
        clinic_id: clinic.id,
        start_date: Date.yesterday,
        end_date: Date.yesterday,
        current_user: system_user
      )
    end
  end
end

# Scheduled via cron: Daily at 6 AM

Monthly Settlement Generation

# lib/tasks/settlements_generate_monthly.rake
namespace :settlements do
  desc "Generate monthly settlements for all clinics"
  task generate_monthly: :environment do
    period = ENV['PERIOD'] || 1.month.ago.strftime('%Y-%m')

    Clinic.active.find_each do |clinic|
      Settlements::GenerateMonthly.call(
        clinic_id: clinic.id,
        period: period,
        current_user: system_user
      )
    end
  end
end

# Scheduled via cron: Monthly on 1st at 12:01 AM

Commission Workflow Scheduler

# lib/tasks/schedule_commission_workflows.rake
namespace :commission_workflows do
  desc "Process scheduled commission workflows"
  task process: :environment do
    CommissionWorkflow.enabled.find_each do |workflow|
      next unless workflow.should_run_today?

      CommissionWorkflows::Execute.call(
        workflow_id: workflow.id,
        current_user: system_user
      )
    end
  end
end

# Scheduled via cron: Every hour

Testing

RSpec Examples

# spec/models/clinic_commission_rule_spec.rb
RSpec.describe ClinicCommissionRule, type: :model do
  describe '#calculate_commission' do
    context 'percentage type' do
      let(:rule) { create(:commission_rule, :percentage, commission_percentage: 30) }

      it 'calculates 30% commission' do
        expect(rule.calculate_commission(1000)).to eq(300.0)
      end
    end

    context 'tiered type' do
      let(:rule) { create(:commission_rule, :tiered) }

      before do
        create(:commission_tier, rule: rule, min: 0, max: 10000, percentage: 10)
        create(:commission_tier, rule: rule, min: 10001, max: nil, percentage: 15)
      end

      it 'applies correct tier' do
        expect(rule.calculate_commission(15000)).to eq(2250.0)
      end
    end
  end
end

# spec/interactors/settlements/generate_monthly_spec.rb
RSpec.describe Settlements::GenerateMonthly do
  let(:clinic) { create(:clinic) }
  let(:doctor) { create(:clinic_doctor, clinic: clinic) }

  it 'generates settlement for doctor with calculations' do
    create_list(:commission_calculation, 5, clinic_doctor: doctor)

    result = described_class.call(
      clinic_id: clinic.id,
      period: '2025-01',
      current_user: create(:user)
    )

    expect(result).to be_success
    expect(doctor.commission_settlements.count).to eq(1)
  end
end

Deployment & Configuration

Environment Variables

# Required
DATABASE_URL=postgresql://...
REDIS_URL=redis://...

# Optional
COMMISSION_CALCULATION_ENABLED=true
SETTLEMENT_GENERATION_ENABLED=true
COMMISSION_WORKFLOW_ENABLED=true

Database Seeds

# Seed basic reference data
bundle exec rails db:seed

# This seeds:
# - basic_commission_rule_types (percentage, fixed, tiered)
# - basic_service_types (consultation, procedure, etc.)

Rake Tasks

# One-time setup
bundle exec rake db:migrate
bundle exec rake db:seed

# Daily operations
bundle exec rake revenue:calculate_daily_commissions
bundle exec rake commission_workflows:process

# Monthly operations
bundle exec rake settlements:generate_monthly PERIOD=2025-01

# Monitoring
bundle exec rake commission_workflows:status

Cron Schedule

# config/schedule.rb (whenever gem)

# Daily commission calculation - 6 AM
every 1.day, at: '6:00 am' do
  rake "revenue:calculate_daily_commissions"
end

# Hourly workflow processing
every 1.hour do
  rake "commission_workflows:process"
end

# Monthly settlement generation - 1st of month at 12:01 AM
every '0 1 1 * *' do
  rake "settlements:generate_monthly"
end

API Error Handling

All APIs return consistent error responses:

{
  "success": false,
  "error": {
    "message": "Error description",
    "details": {
      "field": ["validation error"]
    }
  }
}

HTTP Status Codes:

  • 200: Success
  • 201: Created
  • 400: Bad Request
  • 401: Unauthorized
  • 403: Forbidden
  • 404: Not Found
  • 422: Validation Error
  • 500: Server Error

Performance Considerations

  1. Batch Processing: Use find_each for large datasets
  2. Database Indexing: All foreign keys and query fields indexed
  3. Caching: Redis caching for analytics dashboards
  4. Background Jobs: Sidekiq for async processing
  5. Query Optimization: Use includes to avoid N+1 queries

Security & Authorization

  • Pundit Policies: All controllers protected by Pundit authorization
  • Role-Based Access: Clinic owners, admins, finance managers
  • Audit Logging: All financial operations logged in system_logs
  • Data Encryption: Sensitive financial data encrypted at rest

Pending Features & Future Enhancements

This section documents features that were planned in the original PRD and implementation documents but are not yet fully implemented. These are organized by priority and complexity.

High Priority - Pending Implementation

1. Revenue Share Calculation Automation

Status: 🔄 Partially Implemented

What exists:

  • Database schema (revenue_share_calculations table)
  • Model associations
  • Basic controller endpoints
  • Background jobs already exist:
    • CommissionCalculationJob (parts/clinic/services/commission_calculation_job.rb)
    • CalculateCommissionJob (parts/clinic/services/calculate_commission_job.rb)
    • CommissionWorkflowExecutionJob (parts/billing/services/commission_workflow_execution_job.rb)
    • RunCommissionWorkflowsJob (parts/billing/services/run_commission_workflows_job.rb)

What's missing:

  • Revenue share calculation interactor with full business logic
  • Integration between existing jobs and revenue share calculations
  • Distribution breakdown by stakeholder
  • Platform fee calculation logic

Implementation needed:

# Create: RevenueSharing::CalculateDistribution interactor
# Update: Existing jobs (CommissionWorkflowExecutionJob) to handle revenue share calculations
# Logic: Calculate monthly revenue, apply active config, distribute by percentages

APIs to implement:

POST /clinics/:clinic_id/revenue_share_calculations/calculate
GET  /clinics/:clinic_id/revenue_share_calculations/dashboard (needs full implementation)

2. Revenue Share Payout Processing

Status: ❌ Not Implemented

What exists:

  • Revenue distribution queue table
  • Basic tracking structure

What's missing:

  • Payout workflow (approve, process, mark paid)
  • Integration with payment gateways
  • Payout status tracking
  • Payout history and audit trail
  • Multi-stakeholder batch payouts

Implementation needed:

# Model: RevenueSharePayout (new)
# Interactor: RevenueSharing::ProcessPayout (new)
# Controller: RevenueSharePayoutsController (enhance existing)

APIs to implement:

POST /clinics/:clinic_id/revenue_share_distributions/:id/approve
POST /clinics/:clinic_id/revenue_share_distributions/:id/process_payment
GET  /clinics/:clinic_id/revenue_share_distributions/:id/history

3. Commission Settlement Workflow Completion

Status: 🔄 Partially Implemented

What exists:

  • CommissionSettlement model
  • Basic settlement generation method
  • Database schema
  • Background jobs already exist:
    • CommissionCalculationJob (parts/clinic/services/commission_calculation_job.rb)
    • CalculateCommissionJob (parts/clinic/services/calculate_commission_job.rb)
    • CommissionWorkflowExecutionJob (parts/billing/services/commission_workflow_execution_job.rb)
    • RunCommissionWorkflowsJob (parts/billing/services/run_commission_workflows_job.rb)

What's missing:

  • Integration of existing jobs with settlement generation
  • Settlement approval workflow UI integration
  • Settlement payment processing integration
  • Settlement export functionality
  • Settlement reconciliation tools

Implementation needed:

# Create: Commissions::GenerateMonthlySettlements interactor
# Update: Existing jobs (CommissionWorkflowExecutionJob) to trigger settlement generation
# Create: CommissionSettlementsController (full CRUD)

APIs to implement:

GET    /clinics/:clinic_id/commission_settlements
GET    /clinics/:clinic_id/commission_settlements/:id
POST   /clinics/:clinic_id/commission_settlements/generate
POST   /clinics/:clinic_id/commission_settlements/:id/approve
POST   /clinics/:clinic_id/commission_settlements/:id/process_payment
DELETE /clinics/:clinic_id/commission_settlements/:id/cancel
POST   /clinics/:clinic_id/commission_settlements/export

4. Commission Workflow - Settlement Generation Type

Status: 🔄 Partially Implemented

What exists:

  • CommissionWorkflow model supports SETTLEMENT_GENERATION type
  • Workflow scheduler framework

What's missing:

  • Actual settlement generation workflow processor
  • Monthly settlement job integration
  • Workflow logs for settlement generation
  • Error handling and retry logic

Implementation needed:

# Update: CommissionWorkflowProcessorJob
# Add: Handle SETTLEMENT_GENERATION workflow type
# Logic: Generate settlements for all doctors on schedule

Medium Priority - Future Enhancements

5. Performance-Based Bonuses

Status: ❌ Not Implemented

Planned features:

  • Performance metrics tracking (patient_satisfaction, revenue_target, appointment_count, conversion_rate)
  • Performance bonus rules configuration
  • Automated bonus calculations based on achievement percentages
  • Bonus approval workflow
  • Performance dashboards

Database schema needed:

# Tables to create:
# - performance_metrics
# - performance_bonus_rules
# - performance_bonus_calculations

Models to create:

# - PerformanceMetric
# - PerformanceBonusRule
# - PerformanceBonusCalculation

6. Advanced Payment Methods

Status: ❌ Not Implemented

Planned features:

  • UPI payment integration
  • Digital wallet support (Paytm, PhonePe, Google Pay)
  • International payment methods
  • Multi-currency support
  • Payment method preferences per stakeholder

Implementation needed:

# Service: PaymentGatewayService
# Models: PaymentMethod, PaymentTransaction
# Integration with Razorpay/Stripe for multiple methods

7. Bulk Operations

Status: ❌ Not Implemented

Planned features:

  • Bulk commission approval (exists in frontend, needs backend completion)
  • Bulk settlement generation
  • Bulk payment processing
  • Bulk calculation recalculation
  • Batch export operations

APIs to implement:

POST /clinics/:clinic_id/commission_calculations/bulk_approve
POST /clinics/:clinic_id/commission_settlements/bulk_generate
POST /clinics/:clinic_id/commission_settlements/bulk_process
POST /clinics/:clinic_id/commission_calculations/bulk_recalculate

8. Advanced Analytics & Reporting

Status: 🔄 Partially Implemented

What exists:

  • Basic commission dashboard analytics
  • Revenue analysis reports
  • Period comparison reports
  • Location comparison reports
  • Consolidated reports

What's missing:

  • Revenue share analytics dashboard
  • Stakeholder performance comparison
  • Forecast and projections
  • Trend analysis over multiple periods
  • Custom report builder
  • Scheduled report generation
  • Report subscriptions (email reports)

Implementation needed:

# Controllers:
# - RevenueShareAnalyticsController
# - AdvancedReportsController
#
# Features:
# - Predictive analytics for revenue trends
# - Commission forecast based on historical data
# - Stakeholder ROI calculations
# - Comparative performance across clinics

9. Audit Trail & Compliance Tools

Status: 🔄 Partially Implemented

What exists:

  • System logs association on CommissionCalculation
  • System logs association on CommissionSettlement
  • Basic audit trail tracking

What's missing:

  • Complete audit trail UI
  • Detailed change tracking (before/after values)
  • Audit report generation
  • Compliance reports (tax, regulatory)
  • Audit log export
  • Audit log search and filtering
  • User action history

APIs to implement:

GET  /clinics/:clinic_id/audit_trail
GET  /clinics/:clinic_id/audit_trail/commissions
GET  /clinics/:clinic_id/audit_trail/settlements
GET  /clinics/:clinic_id/audit_trail/revenue_shares
POST /clinics/:clinic_id/audit_trail/export
GET  /users/:user_id/activity_log

10. Hierarchical Revenue Distribution

Status: ❌ Not Implemented

Planned features:

  • Multi-level stakeholder hierarchy
  • Parent-child revenue distribution
  • Cascading percentage calculations
  • Hierarchical approval workflows

What exists:

  • parent_stakeholder_id column in clinic_revenue_stakeholders table

What's missing:

  • Business logic for hierarchical calculations
  • Recursive distribution algorithms
  • Hierarchy visualization
  • Multi-level approval workflows

Low Priority - Nice to Have

11. GraphQL API Support

Status: ❌ Not Implemented

Planned features:

  • GraphQL schema for commissions and revenue sharing
  • Real-time subscriptions for calculation updates
  • Flexible querying capabilities
  • Mobile app optimized endpoints

12. Webhook System

Status: ❌ Not Implemented

Planned features:

  • Webhooks for commission calculations
  • Webhooks for settlement approvals
  • Webhooks for payment processing
  • Webhook configuration UI
  • Webhook delivery status tracking
  • Webhook retry mechanism

13. Commission Forecasting

Status: ❌ Not Implemented

Planned features:

  • Predict future commissions based on historical data
  • Revenue forecasting for stakeholders
  • Budget vs actual comparisons
  • What-if scenario analysis
  • Commission rule impact analysis

14. Multi-Currency & International Support

Status: ❌ Not Implemented

Planned features:

  • Multi-currency commission rules
  • Exchange rate management
  • International payment methods
  • Tax compliance for multiple jurisdictions
  • Region-specific regulatory compliance

15. Mobile App Optimizations

Status: ❌ Not Implemented

Planned features:

  • Lightweight mobile-optimized API endpoints
  • Push notifications for commission updates
  • Offline data sync capabilities
  • Mobile-specific analytics
  • QR code payment integration

Implementation Roadmap

Phase 1 (Q1 2025) - High Priority

  • Complete revenue share calculation automation
  • Implement revenue share payout processing
  • Complete commission settlement workflow
  • Add settlement generation workflow type

Phase 2 (Q2 2025) - Medium Priority

  • Performance-based bonuses
  • Advanced analytics dashboards
  • Bulk operations
  • Complete audit trail system

Phase 3 (Q3 2025) - Future Enhancements

  • Advanced payment methods
  • Hierarchical revenue distribution
  • Commission forecasting
  • Webhook system

On this page

Table of ContentsOverviewVerified Implemented FeaturesArchitectureParts-Based Modular StructureDesign PatternsDatabase SchemaCore Tables1. Clinic Stakeholders2. Clinic Revenue Share Configurations3. Clinic Revenue Stakeholders4. Commission Rules5. Commission Tiers (for tiered rules)6. Commission Calculations7. Commission Settlements8. Commission Workflows9. Revenue Distribution Queue10. Revenue Share CalculationsReference TablesBasic Commission Rule TypesBasic Service TypesDatabase Schema DiagramEntity Relationship DiagramsKey Tables OverviewSchema FeaturesCore ModelsClinicStakeholderClinicRevenueShareConfigClinicCommissionRuleCommissionCalculationCommissionSettlementAPI EndpointsClinic Stakeholders APIsList StakeholdersCreate StakeholderDelete StakeholderRevenue Share Configuration APIsList ConfigurationsCreate ConfigurationActivate ConfigurationCommission Rules APIsList RulesCreate Rule (Percentage)Create Rule (Tiered)Commission Calculations APIsList CalculationsCalculate BatchCommission Dashboard APIsOverviewAnalyticsSettlement APIsList SettlementsGenerate Monthly SettlementsApprove SettlementProcess PaymentCommission Workflows APIsList WorkflowsUpdate WorkflowRevenue Distribution Queue APIsList Queue EntriesExport QueueRevenue Share Calculations APIsList CalculationsShow Calculation DetailsMeta Data APIsGet Basic Service TypesGet Basic Commission Rule TypesBusiness Logic (Interactors)Commission Calculation FlowSettlement Generation FlowRevenue Share Configuration FlowBackground Jobs & AutomationDaily Commission CalculationMonthly Settlement GenerationCommission Workflow SchedulerTestingRSpec ExamplesDeployment & ConfigurationEnvironment VariablesDatabase SeedsRake TasksCron ScheduleAPI Error HandlingPerformance ConsiderationsSecurity & AuthorizationPending Features & Future EnhancementsHigh Priority - Pending Implementation1. Revenue Share Calculation Automation2. Revenue Share Payout Processing3. Commission Settlement Workflow Completion4. Commission Workflow - Settlement Generation TypeMedium Priority - Future Enhancements5. Performance-Based Bonuses6. Advanced Payment Methods7. Bulk Operations8. Advanced Analytics & Reporting9. Audit Trail & Compliance Tools10. Hierarchical Revenue DistributionLow Priority - Nice to Have11. GraphQL API Support12. Webhook System13. Commission Forecasting14. Multi-Currency & International Support15. Mobile App OptimizationsImplementation RoadmapPhase 1 (Q1 2025) - High PriorityPhase 2 (Q2 2025) - Medium PriorityPhase 3 (Q3 2025) - Future Enhancements