from odoo import models, fields, api from math import isnan class SOS_materials_expenditure(models.Model): _name = 'sos_materials_expenditure' _description = 'Materials Expenditure' _rec_name = 'plan_id' _order = 'id desc' plan_id = fields.Many2one('sos_travel_plan',string="Plan Id",required= True) mon_ref_no = fields.Many2one('sos_mon',string="MON Ref No",required= True) mrn_ref_no = fields.Many2one('sos_mrn',string="MRN Ref No",required= True) line_ids_material = fields.One2many('sos_materials_expenditure_material_lines', 'ref_id', string="Materials",copy=True) currency_id = fields.Many2one('res.currency', string='Currency') overall_total = fields.Monetary(store=True,compute='_compute_overall_total', string="Overall Total", currency_field='currency_id') @api.depends('line_ids_material.total_cost') def _compute_overall_total(self): for record in self: total_costs = sum( 0 if line.total_cost is None or isnan(line.total_cost) else line.total_cost for line in record.line_ids_material ) record.overall_total = total_costs @api.onchange('mon_ref_no') def _onchange_mon_ref_no(self): if self.mon_ref_no and self.mon_ref_no.line_ids_material: self.line_ids_material = [(5, 0, 0)] self.line_ids_material = [ (0, 0, { 'component_id': line.component_id.id, 'quantity': line.quantity }) for line in self.mon_ref_no.line_ids_material ] @api.onchange('mrn_ref_no') def _onchange_mrn_ref_no(self): if self.mrn_ref_no and self.line_ids_material: # Build a dict of returned quantities {component_id: returned_qty} return_quantities = {} for line in self.mrn_ref_no.line_ids_material: return_quantities[line.component_id.id] = line.quantity # Adjust existing materials for line in self.line_ids_material: returned_qty = return_quantities.get(line.component_id.id, 0) used_qty = line.quantity - returned_qty line.quantity = used_qty if used_qty > 0 else 0 line.total_cost = (line.approx_price or 0.0) * line.quantity class SOS_materials_expenditure_material_lines(models.Model): _name = 'sos_materials_expenditure_material_lines' _description = 'Materials Expenditure Material Lines' ref_id = fields.Many2one('sos_materials_expenditure', string="Materials", ondelete="cascade") component_id = fields.Many2one('sos_material', string="Part No") material_code = fields.Char(related='component_id.material_code',string="Material Code") quantity = fields.Integer(string="Quantity",required=True,default=1) company_id = fields.Many2one('res.company', store=True, copy=False, string="Company", default=lambda self: self.env.user.company_id.id) currency_id = fields.Many2one('res.currency', string="Currency", related='company_id.currency_id', default=lambda self: self.env.user.company_id.currency_id.id) approx_price = fields.Monetary(string="Price per Unit", compute='_compute_unit_price', store=True, readonly=False) total_cost = fields.Float(string="Total Cost", compute="_compute_total_cost", store=True) @api.depends('component_id.unit_price') def _compute_unit_price(self): for record in self: record.approx_price = record.component_id.unit_price @api.depends('quantity', 'approx_price') def _compute_total_cost(self): for record in self: record.total_cost = (record.quantity or 0.0) * (record.approx_price or 0.0)