feat(fusion_repairs): Bundle 10 - align pricing to Westin's printed rate card
User shared their actual published service-rate card. Bundle 9's seeded
numbers were placeholders that no longer match. Realigned the rate card,
added the LIFT & ELEVATING SERVICE class, added the in-shop labour
rate path, added the delivery / pickup charge model, added rush as a
proper tier (distinct from after-hours), and added 30-min increment
rounding on top of the existing 1-hour minimum.
EQUIPMENT CLASS
fusion.repair.product.category gets a new x_fc_equipment_class
selection: 'standard' vs 'lift_elevating'. The published card splits
pricing into two service classes - lift_elevating has higher rates
($160 callout vs $95, $110/h vs $85).
Categories marked lift_elevating in seed:
stairlift, porch_lift, lift_chair (new)
New 'Lift Chair' category seeded (power recliner / lift chair).
CALLOUT RATE CARD
fusion.repair.callout.rate gets:
- equipment_class field (standard / lift_elevating)
- in_shop_labor_rate field (separate $75 vs $85 on-site)
- 'rush' tier value (was missing - rush was implicit via emergency
surcharge from Bundle 8; now a proper tier matching the printed
rate card row 'Rush Service Calls $120')
Re-seeded with the PUBLISHED Westin rate card (exact values):
STANDARD SERVICE
regular $95 callout / $85/h on-site / $75/h in-shop
rush $120 callout / $85/h / $75/h
after_hours $140 callout / $85/h / $75/h
weekend $180 callout / $85/h / $75/h (extension)
holiday $220 callout / $85/h / $75/h (extension)
LIFT & ELEVATING SERVICE
regular $160 callout / $110/h on-site / $110/h in-shop
rush $200 callout / $110/h / $110/h (extension)
after_hours $240 callout / $110/h / $110/h (extension)
weekend $300 callout / $110/h / $110/h (extension)
holiday $360 callout / $110/h / $110/h (extension)
Travel: $0.70 per km, BOTH WAYS, past 25 km, per technician
(matches the per-card '$0.70 per km x 2-way' footnote).
get_for_tier(tier, equipment_class) now resolves with a fallback:
tries (tier, lift_elevating) first, falls back to (tier, standard)
if no lift-specific row exists - so an admin can leave standard rows
as the catch-all and only customise lift for the exceptions.
DELIVERY / PICKUP RATE CARD
New fusion.repair.delivery.charge model + seed of all 7 items from
the printed card:
Local Service Area (within Brampton) ........ $35
Outside Local Area .......................... $60
Rush Pickups / Delivery ..................... $60 + $0.70/km x 2-way
Lift Chair Delivery and Set-Up .............. $120
Hospital Bed Delivery and Set-Up ............ $120
Stairlift Delivery and Set-Up ............... $300
Stairlift Removal ........................... $300
quote_rush(distance_km) helper for the office's delivery scheduling.
New menu: Configuration > Delivery / Pickup Charges.
PRICING ENGINE UPDATES (repair.order._compute_callout_quote)
- Class-aware rate lookup (uses category.equipment_class).
- In-shop mode (x_fc_in_shop=True): skips callout fee + extra-tech +
travel; charges in_shop_labor_rate * hours * techs only. Per the
rate-card footnote 'In-Shop Labour Rate'.
- 30-min increment rounding ON TOP of the 1-hour floor:
billable_h = max(ceil(actual * 2) / 2, min_hours)
-> 20-min work bills 1.0 h
-> 75-min work bills 1.5 h
-> 95-min work bills 2.0 h
- Improved breakdown text shows the rate-card row name + class +
pro-ration math so the client can see how the total was computed.
NEW FIELDS
repair.order:
x_fc_in_shop (Boolean) - flip to switch the quote engine to
in-shop mode.
x_fc_callout_tier now includes 'rush' as a value (was missing).
visit-report wizard:
callout_in_shop related field - tech can flip the mode on-site if
the work was actually done in-store after pickup.
MIGRATION SCRIPT
migrations/19.0.2.1.0/post-migration.py runs once on existing
installs:
1. Updates stairlift / porch_lift / lift_chair categories
equipment_class -> lift_elevating
2. Wipes the 4 Bundle 9 rate-card xml_ids so the new noupdate=1
seed creates them with the correct printed values.
Fresh installs get the right values directly from the seed XML.
Admin-created custom rate rows (no xml_id) are NEVER touched.
VERIFIED END-TO-END (0 bugs across 28 checks)
Rate card matches printed values exactly:
regular/standard = $95/$85h/$75h PASS
rush/standard = $120/$85h/$75h PASS
after_hours/standard = $140/$85h/$75h PASS
regular/lift = $160/$110h/$110h PASS
Six end-to-end quote scenarios:
A. Standard 12km 20-min -> $180 ($95 + 1h*$85)
B. Lift 12km 20-min -> $270 ($160 + 1h*$110)
C. Rush 30km 1.2h -> $254.50
($120 + ceil(2.4)/2=1.5h * $85 + 5km*2*$0.70 = $7)
D. After-hours lift 2-tech 35km 2.6h -> $928.00
($240 + ceil(5.2)/2=3.0h * $110 * 2 + 10km*2*$0.70*2)
E. In-shop standard 2h -> $150 (2h * $75 in-shop, no callout)
F. In-shop lift 1.5h -> $165 (1.5h * $110 in-shop)
Seven delivery rates loaded with correct amounts; rush 40km calc
= $81 ($60 base + 15km*2*$0.70).
Stairlift / Porch Lift / Lift Chair categories correctly marked
lift_elevating; rest stay standard.
Bumped to 19.0.2.1.0.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,58 +1,161 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Default service callout rate card - 3 tiers + Westin Healthcare defaults.
|
||||
Office can edit these in Configuration -> Callout Rate Card. noupdate=1
|
||||
so site admin tweaks survive module upgrade.
|
||||
Westin Healthcare published rate card (from the official client-facing
|
||||
service-rates flyer / QR card). noupdate=1 so site admin tweaks survive
|
||||
module upgrade.
|
||||
|
||||
STANDARD SERVICE:
|
||||
Service Calls (includes 30 min labour) ........ $95
|
||||
Hourly Labour Rate (on-site, per tech) ........ $85
|
||||
In-Shop Labour Rate (per tech) ................ $75
|
||||
Rush Service Call ............................. $120 + $0.70/km x 2-way
|
||||
After Hours Service Call ...................... $140 + $0.70/km x 2-way
|
||||
|
||||
LIFT & ELEVATING SERVICE (stairlifts, porch lifts, lift chairs):
|
||||
Service Calls (includes 30 min labour) ........ $160
|
||||
Hourly Labour Rate (on-site, per tech) ........ $110
|
||||
In-Shop Labour Rate (per tech) ................ $110
|
||||
(Rush / After-hours / Weekend tiers follow the same multipliers as
|
||||
Standard, applied to the higher base rate.)
|
||||
|
||||
Travel: $0.70 per km past 25 km, BOTH WAYS, per technician.
|
||||
Footnote 2: "If multiple technicians are required, rates will apply per technician."
|
||||
-->
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
<!-- ============== STANDARD SERVICE TIER ROWS ================== -->
|
||||
<record id="callout_rate_regular" model="fusion.repair.callout.rate">
|
||||
<field name="tier">regular</field>
|
||||
<field name="base_callout_fee">120.00</field>
|
||||
<field name="second_tech_fee">60.00</field>
|
||||
<field name="additional_tech_fee">60.00</field>
|
||||
<field name="hourly_labor_rate">95.00</field>
|
||||
<field name="equipment_class">standard</field>
|
||||
<field name="base_callout_fee">95.00</field>
|
||||
<field name="second_tech_fee">0.0</field>
|
||||
<field name="additional_tech_fee">0.0</field>
|
||||
<field name="hourly_labor_rate">85.00</field>
|
||||
<field name="in_shop_labor_rate">75.00</field>
|
||||
<field name="minimum_labor_hours">1.0</field>
|
||||
<field name="travel_distance_threshold_km">25.0</field>
|
||||
<field name="travel_per_km_fee">0.85</field>
|
||||
<field name="description">Standard business hours (Mon-Fri 9 AM - 5 PM). Base fee includes the first 30 minutes for inspection / report.</field>
|
||||
<field name="travel_per_km_fee">0.70</field>
|
||||
<field name="description">STANDARD - regular business hours. Service Call ($95) includes the first 30 min of labour. Hourly Rate ($85/h on-site, $75/h in-shop) applies past 30 min, per tech, pro-rated in 30-min increments with a 1-hour minimum.</field>
|
||||
</record>
|
||||
|
||||
<record id="callout_rate_rush" model="fusion.repair.callout.rate">
|
||||
<field name="tier">rush</field>
|
||||
<field name="equipment_class">standard</field>
|
||||
<field name="base_callout_fee">120.00</field>
|
||||
<field name="second_tech_fee">0.0</field>
|
||||
<field name="additional_tech_fee">0.0</field>
|
||||
<field name="hourly_labor_rate">85.00</field>
|
||||
<field name="in_shop_labor_rate">75.00</field>
|
||||
<field name="minimum_labor_hours">1.0</field>
|
||||
<field name="travel_distance_threshold_km">25.0</field>
|
||||
<field name="travel_per_km_fee">0.70</field>
|
||||
<field name="description">STANDARD - rush. $120 plus $0.70 per km (2-way, past 25 km).</field>
|
||||
</record>
|
||||
|
||||
<record id="callout_rate_after_hours" model="fusion.repair.callout.rate">
|
||||
<field name="tier">after_hours</field>
|
||||
<field name="base_callout_fee">180.00</field>
|
||||
<field name="second_tech_fee">90.00</field>
|
||||
<field name="additional_tech_fee">90.00</field>
|
||||
<field name="hourly_labor_rate">140.00</field>
|
||||
<field name="equipment_class">standard</field>
|
||||
<field name="base_callout_fee">140.00</field>
|
||||
<field name="second_tech_fee">0.0</field>
|
||||
<field name="additional_tech_fee">0.0</field>
|
||||
<field name="hourly_labor_rate">85.00</field>
|
||||
<field name="in_shop_labor_rate">75.00</field>
|
||||
<field name="minimum_labor_hours">1.0</field>
|
||||
<field name="travel_distance_threshold_km">25.0</field>
|
||||
<field name="travel_per_km_fee">1.10</field>
|
||||
<field name="description">Weekday evenings 5 PM - 9 PM. Higher base + higher labour + travel always billed past 25 km.</field>
|
||||
<field name="travel_per_km_fee">0.70</field>
|
||||
<field name="description">STANDARD - after-hours (weekday evenings). $140 plus $0.70 per km (2-way, past 25 km).</field>
|
||||
</record>
|
||||
|
||||
<record id="callout_rate_weekend" model="fusion.repair.callout.rate">
|
||||
<field name="tier">weekend</field>
|
||||
<field name="base_callout_fee">240.00</field>
|
||||
<field name="second_tech_fee">120.00</field>
|
||||
<field name="additional_tech_fee">120.00</field>
|
||||
<field name="hourly_labor_rate">170.00</field>
|
||||
<field name="equipment_class">standard</field>
|
||||
<field name="base_callout_fee">180.00</field>
|
||||
<field name="second_tech_fee">0.0</field>
|
||||
<field name="additional_tech_fee">0.0</field>
|
||||
<field name="hourly_labor_rate">85.00</field>
|
||||
<field name="in_shop_labor_rate">75.00</field>
|
||||
<field name="minimum_labor_hours">1.0</field>
|
||||
<field name="travel_distance_threshold_km">25.0</field>
|
||||
<field name="travel_per_km_fee">1.35</field>
|
||||
<field name="description">Saturday + Sunday. Premium tier.</field>
|
||||
<field name="travel_per_km_fee">0.70</field>
|
||||
<field name="description">STANDARD - weekend (extension of published card). $180 callout.</field>
|
||||
</record>
|
||||
|
||||
<record id="callout_rate_holiday" model="fusion.repair.callout.rate">
|
||||
<field name="tier">holiday</field>
|
||||
<field name="base_callout_fee">300.00</field>
|
||||
<field name="second_tech_fee">150.00</field>
|
||||
<field name="additional_tech_fee">150.00</field>
|
||||
<field name="hourly_labor_rate">200.00</field>
|
||||
<field name="equipment_class">standard</field>
|
||||
<field name="base_callout_fee">220.00</field>
|
||||
<field name="second_tech_fee">0.0</field>
|
||||
<field name="additional_tech_fee">0.0</field>
|
||||
<field name="hourly_labor_rate">85.00</field>
|
||||
<field name="in_shop_labor_rate">75.00</field>
|
||||
<field name="minimum_labor_hours">1.0</field>
|
||||
<field name="travel_distance_threshold_km">25.0</field>
|
||||
<field name="travel_per_km_fee">1.50</field>
|
||||
<field name="description">Statutory holidays. Highest tier.</field>
|
||||
<field name="travel_per_km_fee">0.70</field>
|
||||
<field name="description">STANDARD - statutory holiday (extension of published card). $220 callout.</field>
|
||||
</record>
|
||||
|
||||
<!-- ============== LIFT & ELEVATING SERVICE TIER ROWS ========== -->
|
||||
<record id="callout_rate_regular_lift" model="fusion.repair.callout.rate">
|
||||
<field name="tier">regular</field>
|
||||
<field name="equipment_class">lift_elevating</field>
|
||||
<field name="base_callout_fee">160.00</field>
|
||||
<field name="second_tech_fee">0.0</field>
|
||||
<field name="additional_tech_fee">0.0</field>
|
||||
<field name="hourly_labor_rate">110.00</field>
|
||||
<field name="in_shop_labor_rate">110.00</field>
|
||||
<field name="minimum_labor_hours">1.0</field>
|
||||
<field name="travel_distance_threshold_km">25.0</field>
|
||||
<field name="travel_per_km_fee">0.70</field>
|
||||
<field name="description">LIFT & ELEVATING SERVICE - regular business hours. $160 callout includes 30 min. $110/h labour past 30 min, per tech.</field>
|
||||
</record>
|
||||
|
||||
<record id="callout_rate_rush_lift" model="fusion.repair.callout.rate">
|
||||
<field name="tier">rush</field>
|
||||
<field name="equipment_class">lift_elevating</field>
|
||||
<field name="base_callout_fee">200.00</field>
|
||||
<field name="hourly_labor_rate">110.00</field>
|
||||
<field name="in_shop_labor_rate">110.00</field>
|
||||
<field name="minimum_labor_hours">1.0</field>
|
||||
<field name="travel_distance_threshold_km">25.0</field>
|
||||
<field name="travel_per_km_fee">0.70</field>
|
||||
<field name="description">LIFT & ELEVATING - rush. $200 callout plus $0.70/km (2-way, past 25 km).</field>
|
||||
</record>
|
||||
|
||||
<record id="callout_rate_after_hours_lift" model="fusion.repair.callout.rate">
|
||||
<field name="tier">after_hours</field>
|
||||
<field name="equipment_class">lift_elevating</field>
|
||||
<field name="base_callout_fee">240.00</field>
|
||||
<field name="hourly_labor_rate">110.00</field>
|
||||
<field name="in_shop_labor_rate">110.00</field>
|
||||
<field name="minimum_labor_hours">1.0</field>
|
||||
<field name="travel_distance_threshold_km">25.0</field>
|
||||
<field name="travel_per_km_fee">0.70</field>
|
||||
<field name="description">LIFT & ELEVATING - after-hours. $240 callout plus $0.70/km (2-way, past 25 km).</field>
|
||||
</record>
|
||||
|
||||
<record id="callout_rate_weekend_lift" model="fusion.repair.callout.rate">
|
||||
<field name="tier">weekend</field>
|
||||
<field name="equipment_class">lift_elevating</field>
|
||||
<field name="base_callout_fee">300.00</field>
|
||||
<field name="hourly_labor_rate">110.00</field>
|
||||
<field name="in_shop_labor_rate">110.00</field>
|
||||
<field name="minimum_labor_hours">1.0</field>
|
||||
<field name="travel_distance_threshold_km">25.0</field>
|
||||
<field name="travel_per_km_fee">0.70</field>
|
||||
<field name="description">LIFT & ELEVATING - weekend. $300 callout.</field>
|
||||
</record>
|
||||
|
||||
<record id="callout_rate_holiday_lift" model="fusion.repair.callout.rate">
|
||||
<field name="tier">holiday</field>
|
||||
<field name="equipment_class">lift_elevating</field>
|
||||
<field name="base_callout_fee">360.00</field>
|
||||
<field name="hourly_labor_rate">110.00</field>
|
||||
<field name="in_shop_labor_rate">110.00</field>
|
||||
<field name="minimum_labor_hours">1.0</field>
|
||||
<field name="travel_distance_threshold_km">25.0</field>
|
||||
<field name="travel_per_km_fee">0.70</field>
|
||||
<field name="description">LIFT & ELEVATING - statutory holiday. $360 callout.</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
||||
73
fusion_repairs/data/delivery_charge_data.xml
Normal file
73
fusion_repairs/data/delivery_charge_data.xml
Normal file
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Westin Healthcare DELIVERY / PICKUP CHARGES from the published rate card.
|
||||
|
||||
Local Service Area (within Brampton) .................. $35
|
||||
Outside Local Area .................................... $60
|
||||
Rush Pickups / Delivery ............................... $60 + $0.70/km x 2-way
|
||||
Lift Chair Delivery and Set-Up ........................ $120
|
||||
Hospital Bed Delivery and Set-Up ...................... $120
|
||||
Stairlift Delivery and Set-Up ......................... $300
|
||||
Stairlift Removal ..................................... $300
|
||||
|
||||
Footnote 3: "Westin Healthcare Delivery includes the drop-off of any
|
||||
product or material to a client's home office, facility or
|
||||
predetermined location by one of the staff members. This includes
|
||||
the return of equipment post-repair."
|
||||
-->
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="delivery_local" model="fusion.repair.delivery.charge">
|
||||
<field name="charge_type">local</field>
|
||||
<field name="amount">35.00</field>
|
||||
<field name="sequence">10</field>
|
||||
<field name="description">Within the Brampton service area.</field>
|
||||
</record>
|
||||
|
||||
<record id="delivery_outside" model="fusion.repair.delivery.charge">
|
||||
<field name="charge_type">outside</field>
|
||||
<field name="amount">60.00</field>
|
||||
<field name="sequence">20</field>
|
||||
<field name="description">Outside the local service area (per the published card).</field>
|
||||
</record>
|
||||
|
||||
<record id="delivery_rush" model="fusion.repair.delivery.charge">
|
||||
<field name="charge_type">rush</field>
|
||||
<field name="amount">60.00</field>
|
||||
<field name="travel_per_km_fee">0.70</field>
|
||||
<field name="travel_distance_threshold_km">25.0</field>
|
||||
<field name="sequence">30</field>
|
||||
<field name="description">Rush pickup or delivery. $60 plus $0.70 per km, both ways, past 25 km.</field>
|
||||
</record>
|
||||
|
||||
<record id="delivery_lift_chair" model="fusion.repair.delivery.charge">
|
||||
<field name="charge_type">lift_chair_install</field>
|
||||
<field name="amount">120.00</field>
|
||||
<field name="sequence">40</field>
|
||||
<field name="description">Lift Chair delivery and on-site set-up.</field>
|
||||
</record>
|
||||
|
||||
<record id="delivery_hospital_bed" model="fusion.repair.delivery.charge">
|
||||
<field name="charge_type">hospital_bed_install</field>
|
||||
<field name="amount">120.00</field>
|
||||
<field name="sequence">50</field>
|
||||
<field name="description">Hospital Bed delivery and on-site assembly / set-up.</field>
|
||||
</record>
|
||||
|
||||
<record id="delivery_stairlift_install" model="fusion.repair.delivery.charge">
|
||||
<field name="charge_type">stairlift_install</field>
|
||||
<field name="amount">300.00</field>
|
||||
<field name="sequence">60</field>
|
||||
<field name="description">Stairlift delivery and full set-up at client home.</field>
|
||||
</record>
|
||||
|
||||
<record id="delivery_stairlift_removal" model="fusion.repair.delivery.charge">
|
||||
<field name="charge_type">stairlift_removal</field>
|
||||
<field name="amount">300.00</field>
|
||||
<field name="sequence">70</field>
|
||||
<field name="description">Removal of an old stairlift from client home.</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -35,6 +35,7 @@
|
||||
<field name="icon">fa-arrows-v</field>
|
||||
<field name="description">Straight and curved indoor stairlifts. Annual safety inspection required in many jurisdictions.</field>
|
||||
<field name="safety_critical" eval="True"/>
|
||||
<field name="equipment_class">lift_elevating</field>
|
||||
</record>
|
||||
|
||||
<record id="category_porch_lift" model="fusion.repair.product.category">
|
||||
@@ -44,6 +45,17 @@
|
||||
<field name="icon">fa-arrow-up</field>
|
||||
<field name="description">Vertical platform lifts for porches, decks, and accessible building entrances.</field>
|
||||
<field name="safety_critical" eval="True"/>
|
||||
<field name="equipment_class">lift_elevating</field>
|
||||
</record>
|
||||
|
||||
<!-- Bundle 10: Lift Chair is its own category (power recliner / lift chair). -->
|
||||
<record id="category_lift_chair" model="fusion.repair.product.category">
|
||||
<field name="name">Lift Chair</field>
|
||||
<field name="code">lift_chair</field>
|
||||
<field name="sequence">55</field>
|
||||
<field name="icon">fa-chair</field>
|
||||
<field name="description">Powered recliner / lift chairs (Pride, Golden, MedLift). Falls under Lift & Elevating Service per rate card.</field>
|
||||
<field name="equipment_class">lift_elevating</field>
|
||||
</record>
|
||||
|
||||
<record id="category_walker" model="fusion.repair.product.category">
|
||||
|
||||
Reference in New Issue
Block a user