BDS commission is a two-part flow: admins upload commission rules (Excel) per insurer, month, and department; partner/BDS systems then call an API to calculate payout for a policy using those rules.

Overview

flowchart LR A["Upload rules Excel"] --> B["Save JSON on disk"] B --> C["Edit rules in UI"] D["Policy data POST"] --> E["Load matching JSON"] E --> F["Match rule and return payout"]

In short:

Key files

PartFile
Upload list UIapp/Views/commission_file_upload.php
Rules editor UIapp/Views/commission_rules_list.php
Upload and editor APIapp/Controllers/RuleImportController.php
Excel parsingruleImportService (via Config\Services::ruleImportService())
Payout calculation APIapp/Controllers/InsuranceCommissionController.php
Upload metadata DBcommission_files (CommissionFilesModel)

Routes

Admin (commission group):

RouteHandler
GET/POST commission/listcommissionFileUploadList
POST commission/uploadupload
GET commission/sample_fileSample CSV download
GET commission/downloadErrorFileAnnotated error Excel
GET commission/checkSameEntryDuplicate insurer + month + department check
GET commission/rules/list/(:id)ruleList — rules editor page
POST commission/rules/save/saveRule
POST commission/rules/remove/removeRule
GET commission/checkRuleUsageWhether rule is used on partner policies
GET commission/deleteCommissionData/(:id)Soft-delete file + mark rules deleted

Runtime API:

POST getCommission
  → InsuranceCommissionController::initiateCommissionCalc
  → filter: CommissionApiFilter

How to build the commission file

Use the template from the upload screen (Download sample file) or copy from public/sample_excel/sample_commission.csv. Dev copies also live under writable/uploads/commission/files/ (e.g. sample_commission.csv, Sample_commission_file-New.xlsx). After a successful import, see the generated JSON under writable/uploads/commission/rules/{MONYYYY}/ (example: NOV2025/1_motor.json).

!
Use the current column layout Some older CSVs in writable/uploads/commission/files/ use legacy headers (Rule Name, Commission Params(TP:OD:PA)). The importer expects the S.No layout below (RuleImportService). Wrong headers fail with “Missing required columns”.

Required columns (row 1 headers)

Header text must match exactly (one row per rule, starting row 2). Empty cells are allowed and simply skip that condition.

ColumnPurposeExample
S.NoSerial (not used in logic)1
Premium TypeMaps to policy_typeOD, TP, COM
Vehicle Typevehicle_type; comma = multiple (IN)Two Wheeler, Four Wheeler
Vehicle Sub Typevehicle_sub_typeCar, PCV
Make / ModelVehicle make and modelHonda, i10
CC Min / CC MaxCubic capacity range1000, 3000
Fuel TypeComma-separated fuelsPetrol, Diesel
Vehicle Age Min / MaxVehicle age range (years)1, 5
Vehicle Weight Min / MaxWeight range (kg)2000, 3000
RTO State / RTO Codegeo_rto_state, geo_rto_cityRJ, 41
Renewal Typerenewal_typeOnline, Cash, Card
Commission Typepercentage, composite, flat, tieredpercentage
Commission Value% or flat amount (required for percentage / flat)15 or 500
Commission Params (TP)Composite: % on TP premium18
Commission Params (OD)Composite: % on OD premium10
Commission Params (PA)Composite: % on PA premium0 or empty

Commission types (what to fill)

TypeFill in sheetBecomes in JSON
percentage Commission Value = e.g. 10 10% of premium
composite Leave Value empty; set TP / OD / PA param columns (percent each) Split % on tp_premium, od_premium, pa_premium
flat Commission Value = fixed rupee amount e.g. 500 Fixed payout on premium

Sample rows (from project files)

Template header + rows (public/sample_excel/sample_commission.csv):

S.No,Premium Type,Vehicle Type,...,Commission Type,Commission Value,Commission Params (TP),Commission Params (OD),Commission Params (PA)
1,OD,Car,...,percentage,15,,,
2,TP,Two Wheeler,...,composite,,18,10,
3,COM,PCV,...,percentage,25,,,
4,COM,GCV,...,composite,,,10,

Example A — composite two-wheeler (from writable/.../rules/NOV2025/1_motor.json):

Example B — percentage four-wheeler:

Example C — composite TP-only:

Example D — flat amount:

Tips:

Rule upload

From commission_file_upload.php the user picks insurer, commission month, department (motor / health), and an Excel/CSV file.

  1. checkSameEntry — if a successful upload already exists for the same trio, SweetAlert offers Overwrite or Append (overwrite=1 or 0 on POST).
  2. upload — stores file under writable/uploads/commission/files/, inserts commission_files row (pending).
  3. ruleImportService->processUpload() — validates Excel rows; on success returns rules array; on failure returns annotated_file for download.
  4. On success — writes JSON to rules/{MONYYYY}/{insurer_id}_{department}.json; sets file_status=success and rules_count.
  5. On failure — file_status=failed; user downloads annotated_{filename} via downloadErrorFile.

Rules editor

For successful uploads, action View Rules opens commission/rules/list/{file_id} (commission_rules_list.php).

Rule JSON shape

Each rule is roughly:

{
  "id": "rule_…",
  "name": "Rule name",
  "department": "motor",
  "file_id": 12,
  "is_deleted": false,
  "conditions": [
    { "field": "vehicle_type", "operator": "==", "value": "car" }
  ],
  "calculation": {
    "type": "percentage",
    "value": 10,
    "on": "premium"
  }
}

Calculation types in InsuranceCommissionController: percentage, composite, fixed. Conditions support ==, !=, >, >=, <, <=, between, in.

Commission calculation API

initiateCommissionCalc() expects POST/JSON including at least:

flowchart TD A["POST getCommission"] --> B{"Required fields present?"} B -->|No| C["Validation error"] B -->|Yes| D["Load rules JSON for month, insurer, department"] D --> E{"File exists?"} E -->|No| F["Rules file not found"] E -->|Yes| G["Find first rule where all conditions match"] G --> H{"Rule found?"} H -->|No| I["No matching rules"] H -->|Yes| J["Apply calculation type"] J --> K["Return payout and rule"]

Rules with is_deleted: false are loaded; the first matching rule wins (no priority field yet).

Developer steps

  1. Open /commission/list (logged-in admin).
  2. Download sample file, fill rules for insurer + month + department, upload.
  3. If validation fails, download the annotated error file and fix the sheet.
  4. Use View Rules to tweak conditions or calculation without re-uploading the whole file.
  5. Test payout: POST getCommission with the same insurer, department, and a policy_issue_date in that commission month.

Common pitfalls