How the premium gets calculated
GIRateEngine loads every Motor Comprehensive tariff table into memory once, then prices every quote from Aggregators, the website, POS, and the mobile app entirely in RAM — no database call on the request path. This is the plain-language walkthrough of what it computes today, and an honest map of what's still outstanding.
Three pieces make up a quote
A Motor Comprehensive premium is the Basic Premium, minus discounts down to a protected floor, plus whatever Additional Covers the customer selects, plus VAT. GIRateEngine now computes all three pieces.
%%{init: {'theme':'base', 'themeVariables': {'primaryColor':'#e4f0ee','primaryBorderColor':'#0d6b63','primaryTextColor':'#0d6b63','lineColor':'#8a8272','fontFamily':'Georgia, serif','fontSize':'15px'}}}%%
flowchart LR
A["Basic Premium
tariff + 13 loadings + TPL floor"]:::book --> C{"Discounts +
Minimum-Premium Floor"}:::blend
C --> D["NetGross
base policy premium"]:::mid
D --> E["+ Additional Covers
priced per eligible cover"]:::book
E --> V["+ VAT
flat % per product"]:::book
V --> F["Final Premium
what the customer pays"]:::final
classDef book fill:#e4f0ee,stroke:#0d6b63,color:#0d6b63,stroke-width:1.5px
classDef blend fill:#fdfcf9,stroke:#6b6255,color:#201c16,stroke-width:1.5px
classDef mid fill:#fdfcf9,stroke:#6b6255,color:#201c16,stroke-width:1.5px
classDef final fill:#201c16,stroke:#201c16,color:#f7f4ec,stroke-width:1.5px
"Basic Premium" here means the mandatory base policy cost — third-party + own-damage cover on the vehicle itself. It is not optional. Additional Covers are everything the customer chooses to add on top: Personal Accident benefits, geographic driving extensions, replacement-vehicle cover, and similar.
NetGross, protected by a floor Implemented
Seven discount types subtract from Gross. If stacking all of them would push the premium below the scheme's minimum, the engine doesn't just clip the total — it reproduces the SP's own proportional shrink-back algorithm.
| Discount | Trigger |
|---|---|
| No-Claims Discount (NCD) | Claim-free years |
| Scheme, falling back to User | Scheme code, or the individual user if the scheme has none |
| Loyalty (LD) | Caller-supplied eligibility flag |
| Driver | Caller-declared: a female driver exists on the policy |
| Promo | Caller-supplied percentage |
| Other | Caller-supplied percentage |
| Entity | Caller-supplied percentage |
Several of these — Loyalty, Driver, Promo, Other, Entity — are trusted from the request rather than computed from a lookup the way the SP does it (the SP re-derives Loyalty from an actual prior-policy history check, and aggregator "Other" discounts from an aggregator-specific master table). This is fine as long as every calling channel is independently computing the correct value before it calls the engine — worth confirming with each channel team.
Driver Age top-up
A further loading applies against (Gross − NCD − Loyalty) for young/inexperienced drivers, netted against whatever Insured-Age loading was already applied in §2 so the same risk factor isn't charged twice:
Minimum-premium floor — the reverse calculation
If NetGross would fall below the cached minimum premium for this Product / Vehicle Group / Region / Claim-Free-Years combination, the engine doesn't simply raise the price back up. It first checks which discount types are marked non-adjustable for this scheme, then shrinks only the adjustable ones proportionally until the floor is exactly met:
This is one of the more intricate pieces of the SP, and it's been ported faithfully — the C# even carries the SP's own illustrative comment forward: 800 (Gross) − 450 (Min Premium) = 350 ÷ (20% + 10% + 5%) = 10.
Optional add-on covers Implemented
Every optional cover a customer can attach to a Comprehensive policy is now priced, checked for eligibility, loaded, and floored — exactly like the Basic Premium above but run a second time per cover, and returned alongside it in the same response.
%%{init: {'theme':'base', 'themeVariables': {'primaryColor':'#f6ecdd','primaryBorderColor':'#a8621a','primaryTextColor':'#a8621a','lineColor':'#a8621a','fontFamily':'Georgia, serif','fontSize':'14px'}}}%%
flowchart TD
A1["Customer selects one or more Additional Covers"]
A2["Eligibility filter
Make · Model · Vehicle-Age · Deductible-band · Business-Type"]
A3["Rate lookup, per cover
Fixed amount / per-seat —or— rated by Region×BodyType×Nationality×
VehicleGroup×Usage×Deductible×InsuredAge×ManufactureYear"]
A4["Re-run applicable loadings
(cover-specific subset of the same 13-factor chain)"]
A5["Cover's own minimum premium, then VAT"]
A6["= price for this cover"]
A1 --> A2 --> A3 --> A4 --> A5 --> A6
What's priced, for Comprehensive
| Cover | Pricing shape |
|---|---|
| Personal Accident — Driver | Rated per policy, own loading chain |
| Personal Accident — Passengers | Rated per seat (seating capacity × rate) |
| Zero Depreciation — Total Loss | % of Gross, vehicle-age gated |
| Zero Depreciation — Partial Loss | % of Gross, vehicle-age gated |
| Admin Fee and similar Fixed-rate covers | Flat fee per policy |
Excluded by design: Geographical Extension covers (GCC/Bahrain/Egypt) and Replacement Vehicle — see the callout below for why.
Why this was more than "one more lookup table"
Three things made this a second pipeline rather than a quick add — all three are now handled:
| Complication | How it's handled |
|---|---|
| Two pricing mechanisms | Some covers are a flat/per-seat "Fixed" rate; others are "Applicable at Cover level" — rated from an 8-dimension lookup table (region, body type, nationality, vehicle group, usage, deductible band, insured-age band, manufacture-year band). Both are cached and priced. |
| Per-vehicle eligibility rules | A separate whitelist table can restrict specific covers to specific Make/Model/Vehicle-Age/Deductible-band/Business-Type combinations — checked before a non-mandatory cover is offered. |
| The loading chain runs again | Each cover has its own data-driven map of which of the 13 loadings actually apply to it. The engine reuses the percentages already computed for the Basic Premium rather than re-querying — verified this map is currently empty for all Motor Comp products, so it's a correct no-op today. |
Deliberately excluded, matching what production's live quote flow actually exercises (not what it theoretically supports): geographic-extension covers (Bahrain/Egypt/GCC/Other) and Replacement Cover — the reference SP always calls its additional-covers logic with no geographic-extension period selected, and its own Replacement Cover block is commented out in production. Sourced via 6 new stored procedures added to Acig_Limra_Db, following the same _RateEngine naming convention as the 8 already wired into MastersCache.
Found while reviewing the SP Mixed
Additional Covers and VAT (§4, and the reference table below) are now closed. Comparing the engine line-by-line against the production SP surfaced five more differences — none as large, but worth a deliberate decision before or shortly after go-live.
| Gap | Direction of error | Notes |
|---|---|---|
| Comprehensive premium CAP | Overstated (if activated) | Ceiling on Basic Premium by make/model/region/etc. Currently zero active rows in production — dormant, but live code in the SP. |
| Minimum-premium keying | Understated (edge cases) | Engine keys on Product/Vehicle-Group/Region/Claim-Years only; the SP also keys on Policy Type, Make, Model, Nationality, Manufacture Year, Repair Type. |
| Cross-Sell & Multi-Vehicle Discount | Overstated (discount withheld) | Both require a live per-customer "how many existing policies" lookup — structurally in tension with a pure in-memory cache. See Project Details.md §5.4 for options. |
| Motor Scheme Discount cap | Understated | A per-scheme ceiling on total stacked discount % is not enforced — a customer stacking several discounts could be quoted below what the scheme actually allows. |
| Region resolution | Could pick wrong tariff row | The SP's algorithm is materially richer (aggregator vs. non-aggregator branches, majority-vote across three region codes); the engine only handles the single-duplicate case. |
Full detail, verbatim SQL references, and a phased remediation plan for each of these live in Project Details.md.
Basic Premium, start to finish
Illustrative figures at realistic Saudi Comprehensive magnitude — not real master data. Shown here is the Basic Premium chain through VAT; Additional Covers are priced separately per eligible cover and returned alongside this total (see §4).
Tariff Rate = 6.24% of Sum Insured → 90,000 × 6.24 / 100 = 5,616.00 TPL-floor premium = 1,180 × 1.05 (min-premium config) = 1,239.00 Tariff Min Premium = 4,200.00 Basic Premium = MAX(5,616.00, 1,239.00, 4,200.00) = 5,616.00 Loadings on Basic Premium (5,616.00): Marital Status +8% → 449.28 Insured Age +5% → 280.80 Repair Type +11% → 617.76 Region +3% → 168.48 Deductible +4% → 224.64 NCD (loading) -2% → -112.32 (all other loadings 0% for this profile) Σ Loadings = 1,628.64 NRP = 5,616.00 + 1,628.64 = 7,244.64 Applicable Loading % = 12% Gross = 7,244.64 ÷ (100 − 12) × 100 = 8,232.55 Discounts on Gross (8,232.55): NCD Discount -20% → -1,646.51 Scheme Discount -5% → -411.63 NetGross = 8,232.55 − 1,646.51 − 411.63 = 6,174.41 Minimum-Premium check: floor for this Product/Group/Region/NCD = 5,900.00 NetGross (6,174.41) already clears the floor → no reverse-calculation needed VAT (flat 15%) = 6,174.41 × 15% = 926.16 Final Basic Premium incl. VAT = 7,100.57
Formula reference
| Stage | Formula | Status |
|---|---|---|
| Basic Premium | MAX(Rate × SI ÷ 100, TPL-floor × (1+MinCfg%), Tariff Min Premium) | Live |
| NRP | Basic Premium + Σ(13 loadings) + Accident Loading | Live |
| Gross | NRP ÷ (100 − Applicable Loading %) × 100 | Live |
| NetGross | Gross − (NCD + Scheme/User + Loyalty + Driver + Promo + Other + Entity) | Live |
| Driver Age top-up | MAX((Gross−NCD−LD) × DriverAge% − InsAgeLoadingAmt, 0) | Live |
| Minimum-premium floor | Shrink adjustable discounts proportionally, else gross back up | Live |
| VAT | NetGross × VAT% (flat 15% today) | Live |
| Comprehensive CAP | MIN(Basic Premium, CAP amount or % of SI) | Missing (dormant in prod) |
| Additional Covers | Per-cover: eligibility → rate → loadings → min premium → VAT | Live |
| Cross-Sell / Multi-Vehicle Discount | Needs live per-customer existing-policy lookup | Missing |
| Motor Scheme Discount cap | Clip total stacked discount % to the scheme's ceiling | Missing |