# -*- coding: utf-8 -*- # Copyright 2024-2026 Nexa Systems Inc. # License OPL-1 (Odoo Proprietary License v1.0) """Delivery / pickup rate card (separate from repair callouts). Per Westin's published rate card the DELIVERY / PICKUP CHARGES section is a distinct service from repair callouts. These are charged when we move equipment (drop-off of a sold unit, post-repair return delivery, removal of old equipment, etc.). """ from odoo import api, fields, models class FusionRepairDeliveryCharge(models.Model): _name = 'fusion.repair.delivery.charge' _description = 'Delivery / Pickup Rate Card' _order = 'sequence, charge_type, id' name = fields.Char(compute='_compute_name', store=True) sequence = fields.Integer(default=10) charge_type = fields.Selection( [ ('local', 'Local Service Area'), ('outside', 'Outside Local Area'), ('rush', 'Rush Pickup / Delivery'), ('lift_chair_install', 'Lift Chair Delivery and Set-Up'), ('hospital_bed_install', 'Hospital Bed Delivery and Set-Up'), ('stairlift_install', 'Stairlift Delivery and Set-Up'), ('stairlift_removal', 'Stairlift Removal'), ('other', 'Other'), ], string='Charge Type', required=True, ) amount = fields.Monetary( string='Amount', currency_field='currency_id', required=True, ) travel_per_km_fee = fields.Monetary( string='Per-km Fee (Rush, 2-way)', currency_field='currency_id', default=0.0, help='Only applies to rush pickups/deliveries. Per the published card: ' '$60 plus $0.70 per km x 2-way.', ) travel_distance_threshold_km = fields.Float( string='Free Travel Distance (km, 2-way)', default=0.0, help='Only applies to rush. Above this km, every additional km is ' 'charged travel_per_km_fee BOTH WAYS.', ) description = fields.Text(translate=True) currency_id = fields.Many2one( 'res.currency', default=lambda self: self.env.company.currency_id, ) company_id = fields.Many2one( 'res.company', default=lambda self: self.env.company, ) active = fields.Boolean(default=True) @api.depends('charge_type', 'amount') def _compute_name(self): for r in self: label = dict(self._fields['charge_type'].selection).get(r.charge_type) or '?' r.name = f'{label} - ${r.amount:.0f}' @api.model def get_charge(self, charge_type): """Return the active rate row for `charge_type`, empty recordset if none.""" return self.sudo().search([ ('charge_type', '=', charge_type), ('active', '=', True), ('company_id', 'in', self.env.companies.ids), ], limit=1) @api.model def quote_rush(self, distance_km): """Convenience: returns the total for a Rush Pickup / Delivery at `distance_km` one-way. Returns 0.0 if no rush row configured.""" rush = self.get_charge('rush') if not rush: return 0.0 over = max(distance_km - rush.travel_distance_threshold_km, 0.0) return rush.amount + (over * 2.0 * rush.travel_per_km_fee)