82 lines
2.9 KiB
Python
82 lines
2.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class FusionServiceRate(models.Model):
|
|
_name = 'fusion.service.rate'
|
|
_description = 'Field Service Rate'
|
|
_order = 'sequence, rate_kind, category, timing'
|
|
|
|
name = fields.Char(string='Name', required=True)
|
|
code = fields.Char(
|
|
string='Code', required=True, index=True,
|
|
help='Stable code used by the booking engine, e.g. callout_standard_normal, per_km.',
|
|
)
|
|
rate_kind = fields.Selection([
|
|
('callout', 'Service Call-out'),
|
|
('labour', 'Labour'),
|
|
('travel', 'Travel / per-km'),
|
|
('delivery', 'Delivery / Pickup'),
|
|
('other', 'Other'),
|
|
], string='Kind', required=True, default='callout')
|
|
category = fields.Selection([
|
|
('standard', 'Standard'),
|
|
('lift', 'Lift & Elevating'),
|
|
('na', 'N/A'),
|
|
], string='Category', default='na')
|
|
timing = fields.Selection([
|
|
('normal', 'Normal'),
|
|
('rush', 'Rush'),
|
|
('afterhours', 'After-Hours'),
|
|
('na', 'N/A'),
|
|
], string='Timing', default='na')
|
|
in_shop = fields.Boolean(string='In-Shop')
|
|
product_id = fields.Many2one(
|
|
'product.product', string='Invoice Product', required=True, ondelete='restrict',
|
|
help='Product used on the sale-order line (description, tax, income account).',
|
|
)
|
|
price = fields.Monetary(
|
|
string='Rate', required=True, currency_field='currency_id',
|
|
help='Editable price used on the SO line and the on-screen estimate.',
|
|
)
|
|
currency_id = fields.Many2one(
|
|
'res.currency', string='Currency',
|
|
default=lambda self: self.env.company.currency_id,
|
|
)
|
|
unit = fields.Selection([
|
|
('fixed', 'Flat'),
|
|
('per_hour', 'Per hour'),
|
|
('per_km', 'Per km'),
|
|
], string='Unit', required=True, default='fixed')
|
|
adds_per_km = fields.Boolean(
|
|
string='Adds per-km travel',
|
|
help='Call-outs billed as $X + per-km \xd7 2-way (rush / after-hours).',
|
|
)
|
|
included_labour_min = fields.Integer(
|
|
string='Included labour (min)', default=0,
|
|
help='Free labour minutes bundled into a service call (e.g. 30).',
|
|
)
|
|
active = fields.Boolean(string='Active', default=True)
|
|
sequence = fields.Integer(string='Sequence', default=10)
|
|
|
|
_unique_code = models.Constraint(
|
|
'UNIQUE(code)',
|
|
'A service-rate code must be unique.',
|
|
)
|
|
|
|
@api.model
|
|
def get_callout(self, category, timing, in_shop=False):
|
|
"""Active call-out rate for category+timing. Empty recordset when in-shop."""
|
|
if in_shop:
|
|
return self.browse()
|
|
return self.search([
|
|
('rate_kind', '=', 'callout'),
|
|
('category', '=', category),
|
|
('timing', '=', timing),
|
|
], limit=1)
|
|
|
|
@api.model
|
|
def get_rate(self, code):
|
|
"""Active rate row by code (e.g. 'per_km', 'labour_onsite')."""
|
|
return self.search([('code', '=', code)], limit=1)
|