diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/fleet/models/fleet_vehicle_cost.py | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/fleet/models/fleet_vehicle_cost.py')
| -rw-r--r-- | addons/fleet/models/fleet_vehicle_cost.py | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/addons/fleet/models/fleet_vehicle_cost.py b/addons/fleet/models/fleet_vehicle_cost.py new file mode 100644 index 00000000..266cf94a --- /dev/null +++ b/addons/fleet/models/fleet_vehicle_cost.py @@ -0,0 +1,189 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + +from dateutil.relativedelta import relativedelta + +class FleetVehicleLogContract(models.Model): + _inherit = ['mail.thread', 'mail.activity.mixin'] + _name = 'fleet.vehicle.log.contract' + _description = 'Vehicle Contract' + _order = 'state desc,expiration_date' + + def compute_next_year_date(self, strdate): + oneyear = relativedelta(years=1) + start_date = fields.Date.from_string(strdate) + return fields.Date.to_string(start_date + oneyear) + + vehicle_id = fields.Many2one('fleet.vehicle', 'Vehicle', required=True, help='Vehicle concerned by this log') + cost_subtype_id = fields.Many2one('fleet.service.type', 'Type', help='Cost type purchased with this cost', domain=[('category', '=', 'contract')]) + amount = fields.Monetary('Cost') + date = fields.Date(help='Date when the cost has been executed') + company_id = fields.Many2one('res.company', 'Company', default=lambda self: self.env.company) + currency_id = fields.Many2one('res.currency', related='company_id.currency_id') + name = fields.Char(string='Name', compute='_compute_contract_name', store=True) + active = fields.Boolean(default=True) + user_id = fields.Many2one('res.users', 'Responsible', default=lambda self: self.env.user, index=True) + start_date = fields.Date('Contract Start Date', default=fields.Date.context_today, + help='Date when the coverage of the contract begins') + expiration_date = fields.Date('Contract Expiration Date', default=lambda self: + self.compute_next_year_date(fields.Date.context_today(self)), + help='Date when the coverage of the contract expirates (by default, one year after begin date)') + days_left = fields.Integer(compute='_compute_days_left', string='Warning Date') + insurer_id = fields.Many2one('res.partner', 'Vendor') + purchaser_id = fields.Many2one(related='vehicle_id.driver_id', string='Current Driver') + ins_ref = fields.Char('Reference', size=64, copy=False) + state = fields.Selection([ + ('futur', 'Incoming'), + ('open', 'In Progress'), + ('expired', 'Expired'), + ('closed', 'Closed') + ], 'Status', default='open', readonly=True, + help='Choose whether the contract is still valid or not', + tracking=True, + copy=False) + notes = fields.Text('Terms and Conditions', help='Write here all supplementary information relative to this contract', copy=False) + cost_generated = fields.Monetary('Recurring Cost') + cost_frequency = fields.Selection([ + ('no', 'No'), + ('daily', 'Daily'), + ('weekly', 'Weekly'), + ('monthly', 'Monthly'), + ('yearly', 'Yearly') + ], 'Recurring Cost Frequency', default='monthly', help='Frequency of the recuring cost', required=True) + service_ids = fields.Many2many('fleet.service.type', string="Included Services") + + @api.depends('vehicle_id.name', 'cost_subtype_id') + def _compute_contract_name(self): + for record in self: + name = record.vehicle_id.name + if name and record.cost_subtype_id.name: + name = record.cost_subtype_id.name + ' ' + name + record.name = name + + @api.depends('expiration_date', 'state') + def _compute_days_left(self): + """return a dict with as value for each contract an integer + if contract is in an open state and is overdue, return 0 + if contract is in a closed state, return -1 + otherwise return the number of days before the contract expires + """ + for record in self: + if record.expiration_date and record.state in ['open', 'expired']: + today = fields.Date.from_string(fields.Date.today()) + renew_date = fields.Date.from_string(record.expiration_date) + diff_time = (renew_date - today).days + record.days_left = diff_time > 0 and diff_time or 0 + else: + record.days_left = -1 + + def write(self, vals): + res = super(FleetVehicleLogContract, self).write(vals) + if vals.get('expiration_date') or vals.get('user_id'): + self.activity_reschedule(['fleet.mail_act_fleet_contract_to_renew'], date_deadline=vals.get('expiration_date'), new_user_id=vals.get('user_id')) + return res + + def contract_close(self): + for record in self: + record.state = 'closed' + + def contract_draft(self): + for record in self: + record.state = 'futur' + + def contract_open(self): + for record in self: + record.state = 'open' + + @api.model + def scheduler_manage_contract_expiration(self): + # This method is called by a cron task + # It manages the state of a contract, possibly by posting a message on the vehicle concerned and updating its status + params = self.env['ir.config_parameter'].sudo() + delay_alert_contract = int(params.get_param('hr_fleet.delay_alert_contract', default=30)) + date_today = fields.Date.from_string(fields.Date.today()) + outdated_days = fields.Date.to_string(date_today + relativedelta(days=+delay_alert_contract)) + nearly_expired_contracts = self.search([('state', '=', 'open'), ('expiration_date', '<', outdated_days)]) + + for contract in nearly_expired_contracts.filtered(lambda contract: contract.user_id): + contract.activity_schedule( + 'fleet.mail_act_fleet_contract_to_renew', contract.expiration_date, + user_id=contract.user_id.id) + + expired_contracts = self.search([('state', 'not in', ['expired', 'closed']), ('expiration_date', '<',fields.Date.today() )]) + expired_contracts.write({'state': 'expired'}) + + futur_contracts = self.search([('state', 'not in', ['futur', 'closed']), ('start_date', '>', fields.Date.today())]) + futur_contracts.write({'state': 'futur'}) + + now_running_contracts = self.search([('state', '=', 'futur'), ('start_date', '<=', fields.Date.today())]) + now_running_contracts.write({'state': 'open'}) + + def run_scheduler(self): + self.scheduler_manage_contract_expiration() + +class FleetVehicleLogServices(models.Model): + _name = 'fleet.vehicle.log.services' + _inherit = ['mail.thread', 'mail.activity.mixin'] + _rec_name = 'service_type_id' + _description = 'Services for vehicles' + + active = fields.Boolean(default=True) + vehicle_id = fields.Many2one('fleet.vehicle', 'Vehicle', required=True, help='Vehicle concerned by this log') + amount = fields.Monetary('Cost') + description = fields.Char('Description') + odometer_id = fields.Many2one('fleet.vehicle.odometer', 'Odometer', help='Odometer measure of the vehicle at the moment of this log') + odometer = fields.Float(compute="_get_odometer", inverse='_set_odometer', string='Odometer Value', + help='Odometer measure of the vehicle at the moment of this log') + odometer_unit = fields.Selection(related='vehicle_id.odometer_unit', string="Unit", readonly=True) + date = fields.Date(help='Date when the cost has been executed', default=fields.Date.context_today) + company_id = fields.Many2one('res.company', 'Company', default=lambda self: self.env.company) + currency_id = fields.Many2one('res.currency', related='company_id.currency_id') + purchaser_id = fields.Many2one('res.partner', string="Driver", compute='_compute_purchaser_id', readonly=False, store=True) + inv_ref = fields.Char('Vendor Reference') + vendor_id = fields.Many2one('res.partner', 'Vendor') + notes = fields.Text() + service_type_id = fields.Many2one( + 'fleet.service.type', 'Service Type', required=True, + default=lambda self: self.env.ref('fleet.type_service_service_8', raise_if_not_found=False), + ) + state = fields.Selection([ + ('todo', 'To Do'), + ('running', 'Running'), + ('done', 'Done'), + ('cancelled', 'Cancelled'), + ], default='todo', string='Stage') + + def _get_odometer(self): + self.odometer = 0 + for record in self: + if record.odometer_id: + record.odometer = record.odometer_id.value + + def _set_odometer(self): + for record in self: + if not record.odometer: + raise UserError(_('Emptying the odometer value of a vehicle is not allowed.')) + odometer = self.env['fleet.vehicle.odometer'].create({ + 'value': record.odometer, + 'date': record.date or fields.Date.context_today(record), + 'vehicle_id': record.vehicle_id.id + }) + self.odometer_id = odometer + + @api.model_create_multi + def create(self, vals_list): + for data in vals_list: + if 'odometer' in data and not data['odometer']: + # if received value for odometer is 0, then remove it from the + # data as it would result to the creation of a + # odometer log with 0, which is to be avoided + del data['odometer'] + return super(FleetVehicleLogServices, self).create(vals_list) + + @api.depends('vehicle_id') + def _compute_purchaser_id(self): + for service in self: + service.purchaser_id = service.vehicle_id.driver_id |
