summaryrefslogtreecommitdiff
path: root/addons/fleet/models/fleet_vehicle_cost.py
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/fleet/models/fleet_vehicle_cost.py
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/fleet/models/fleet_vehicle_cost.py')
-rw-r--r--addons/fleet/models/fleet_vehicle_cost.py189
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