Price Flow Documentation: Vehicle Service Contract & Vehicle Loss Protection
#Overview
Both Vehicle Service Contract (WARRANTY) and Vehicle Loss Protection (VLP) are owned by Assurance and fetched through the PEN (ProvenNet) service.
#Flow: Vehicle Service Contract (WARRANTY / Vehicle Repair Contract)
#Step 1: API Request Entry Point
File: routes/src/main/kotlin/com/detroitlabs/products/routes/FIRoutes.kt
- Endpoint:
GET /estimator/fi-products - Handler:
FIHandler.getEstimatedFIProducts()
#Step 2: Request Handler
File: routes/src/main/kotlin/com/detroitlabs/products/handlers/FIHandler.kt
- Extracts query parameters:
userZip,userState,vehicleId,paymentSelection - If
userStateis missing, fetches it from geocoding service - Calls
FIService.getEstimatedFIProducts()
#Step 3: FI Service - Main Orchestration
File: library/src/main/kotlin/com/detroitlabs/products/services/fi/FIService.kt
- Method:
getEstimatedFIProducts()(line 45) - Determines which product types to fetch based on
paymentSelection - For WARRANTY: included in CASH, FINANCE, and null payment selections
- Calls
getFIProducts()which merges Lithia and PEN products
#Step 4: PEN Product Fetching
File: library/src/main/kotlin/com/detroitlabs/products/services/fi/FIService.kt
- Method:
getPenProducts()(line 131) - First checks cache (
CachedFIProducts) for existing rates - If cache miss or expired, calls
getPenRates()(line 184) - Method:
getVehicleServiceContractPenProduct()(line 244)- Calls
penMediator.getVehicleServiceContractRate() - Price Calculation (line 250-255):
if (it.rateExist) {it.copy(totalInCents = if (vehicle.dealershipState in productsMarkUpConfig.vehicleServiceContract.retailPriceOverrideForStates)it.retailPriceInCentselse(it.dealerCostInCents?.plus(productsMarkUpConfig.vehicleServiceContract.markupAmount)))}
- Uses
retailPriceInCentsif state is in override list (FL) - Otherwise:
dealerCostInCents + markupAmount(currently $1400 = 140000 cents)
- Calls
#Step 5: PEN Mediator - Rate Book Code Management
File: library/src/main/kotlin/com/detroitlabs/products/services/pen/PenMediator.kt
- Method:
getVehicleServiceContractRate()(line 121) - Checks if rate book code is cached (valid for today)
- If not cached, calls
penService.getRateBookCodes()to fetch and cache it - Then calls
getPENWarrantyRate()(line 211)
#Step 6: PEN Mediator - Warranty Rate Fetching
File: library/src/main/kotlin/com/detroitlabs/products/services/pen/PenMediator.kt
- Method:
getPENWarrantyRate()(line 211) - Builds DSIProductInfo with:
- Coverage: "Platinum"
- Deductible: "250"
- Product ID from
penDealer.provider.vehicleServiceContract.id - Rate book code from cached dealer config
- Calls
penService.getASBRates()(line 212) - Price Calculation (line 232-243):
if (it.rateExist) {it.copy(totalInCents = if (vehicle.dealershipState in productsMarkUpConfig.vehicleServiceContract.retailPriceOverrideForStates)it.retailPriceInCentselseit.dealerCostInCents?.plus(productsMarkUpConfig.vehicleServiceContract.markupAmount))}
- Same logic as FIService: retail price override OR dealer cost + markup
#Step 7: PEN Service - SOAP Call to PEN API
File: library/src/main/kotlin/com/detroitlabs/products/services/pen/PenService.kt
- Method:
getASBRates()(line 210) - Creates SOAP envelope with vehicle details, deal info, and product info
- Makes POST request to PEN API endpoint:
GetRates - Parses response and extracts:
retailPriceInCents- from PEN responsedealerCostInCents- from PEN response
- Returns
PenFiProductwith raw prices from PEN
#Step 8: Response Mapping
File: library/src/main/kotlin/com/detroitlabs/products/models/dtos/EstimatedFIProductDto.kt
PenFiProductis converted toEstimatedFIProductDtototalInCentsfield is included in the response
#Flow: Vehicle Loss Protection (VLP)
#Step 1-3: Same as Vehicle Service Contract
- Entry point:
GET /estimator/fi-products - Handler:
FIHandler.getEstimatedFIProducts() - Service:
FIService.getEstimatedFIProducts() - VLP is included when
paymentSelectionis FINANCE or null
#Step 4: PEN Product Fetching for VLP
File: library/src/main/kotlin/com/detroitlabs/products/services/fi/FIService.kt
- Method:
getVehicleLossProtectionPenProduct()(line 269) - Calls
penMediator.getVehicleLossProtectionRate() - Price Calculation (line 275-278):
if (penFiProduct.rateExist) {val vlpPrice = productsMarkUpConfig.vehicleLossProtection.fixedAmountpenFiProduct.copy(totalInCents = vlpPrice)}
- Uses fixed amount from config:
fixedAmount(currently $995 = 99500 cents) - Does NOT use dealer cost or retail price from PEN
- Uses fixed amount from config:
#Step 5: PEN Mediator - Rate Book Code Management
File: library/src/main/kotlin/com/detroitlabs/products/services/pen/PenMediator.kt
- Method:
getVehicleLossProtectionRate()(line 71) - Checks if rate book code is cached (valid for today)
- If not cached, calls
penService.getRateBookCodes()to fetch and cache it - Then calls
getPENVLPRate()(line 147)
#Step 6: PEN Mediator - VLP Rate Fetching
File: library/src/main/kotlin/com/detroitlabs/products/services/pen/PenMediator.kt
- Method:
getPENVLPRate()(line 147) - Builds DSIProductInfo with:
- Coverage: "LOAN $0 - $150K"
- Term Months: 60
- Product ID from
penDealer.provider.vehicleLossProtection.id - Rate book code from cached dealer config
- Calls
penService.getASBRates()(line 148) - Price Calculation (line 167-175):
if (it.rateExist) {it.copy(totalInCents = productsMarkUpConfig.vehicleLossProtection.fixedAmount)}
- Overrides with fixed amount - ignores PEN retail/dealer prices
#Step 7: PEN Service - SOAP Call to PEN API
File: library/src/main/kotlin/com/detroitlabs/products/services/pen/PenService.kt
- Method:
getASBRates()(line 210) - Same SOAP call process as WARRANTY
- Returns
PenFiProductwith raw prices from PEN (but these are overridden)
#Step 8: Response Mapping
- Same as WARRANTY -
totalInCentsis included in response
#Configuration
File: library/src/main/resources/application.yml (lines 112-123)
products:cost:vehicle-service-contract:markup-amount: 140000 # $1400 over cost (in cents)retail-price-override-for-states:- "FL"vehicle-loss-protection:fixed-amount: 99500 # fixed price of $995 (in cents)
Config Class: library/src/main/kotlin/com/detroitlabs/products/services/Config.kt (lines 88-95)
#Summary: Where Prices Are Set
#Vehicle Service Contract (WARRANTY)
- PEN API returns
retailPriceInCentsanddealerCostInCents - PenMediator.getPENWarrantyRate() (line 236-240) calculates:
- If state in override list → use
retailPriceInCents - Otherwise →
dealerCostInCents + markupAmount(140000 cents = $1400)
- If state in override list → use
- FIService.getVehicleServiceContractPenProduct() (line 252-254) applies same logic again
#Vehicle Loss Protection (VLP)
- PEN API returns
retailPriceInCentsanddealerCostInCents(but ignored) - PenMediator.getPENVLPRate() (line 171) sets:
totalInCents = fixedAmount(99500 cents = $995)
- FIService.getVehicleLossProtectionPenProduct() (line 277-278) applies same fixed amount
#To Increase Prices by $100 (10000 cents)
#Option 1: Update Configuration (Recommended)
Update application.yml:
- Vehicle Service Contract: Increase
markup-amountfrom140000to150000(+$100) - Vehicle Loss Protection: Increase
fixed-amountfrom99500to109500(+$100)
#Option 2: Update Code Logic
Add +10000 cents in the price calculation methods:
- Vehicle Service Contract: In
FIService.getVehicleServiceContractPenProduct()andPenMediator.getPENWarrantyRate() - Vehicle Loss Protection: In
FIService.getVehicleLossProtectionPenProduct()andPenMediator.getPENVLPRate()
Note: Both services have price calculation in TWO places (FIService and PenMediator), so changes need to be made in both locations for consistency.