144 lines
6.4 KiB
Python
Executable File
144 lines
6.4 KiB
Python
Executable File
# -*- coding: utf-8 -*-
|
|
|
|
from odoo import models, fields, api
|
|
from odoo.exceptions import ValidationError
|
|
import logging
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
class MiscellaneousCost(models.Model):
|
|
_name = 'miscellaneous_items'
|
|
_description = 'Miscellaneous Items'
|
|
|
|
name = fields.Char(string='Name')
|
|
description = fields.Char(string='Description')
|
|
cost = fields.Float(string='Cost')
|
|
main_model_id = fields.Many2one('sos_fg_bom')
|
|
|
|
|
|
class SOS_Fg_Bom(models.Model):
|
|
_name = 'sos_fg_bom'
|
|
_description = 'BOM of Finished Goods'
|
|
|
|
name = fields.Char(string="Name", required=True)
|
|
currency_id = fields.Many2one('res.currency', string='Currency')
|
|
fg_bom_line_ids = fields.One2many('sos_fg_bom_line', 'bom_id', string='Material Lines',copy=True, ondelete="cascade")
|
|
overall_total = fields.Monetary(compute='_compute_overall_total', string="Estimated Cost", currency_field='currency_id', readonly=True)
|
|
sfg_cost = fields.Monetary(compute='_compute_sfg_cost', string="Total", currency_field='currency_id', readonly=True)
|
|
component_cost = fields.Monetary(compute='_compute_component_cost', string="Total", currency_field='currency_id', readonly=True)
|
|
miscellaneous_cost = fields.Monetary(compute='_compute_miscellaneous_cost', string="Total", currency_field='currency_id', readonly=True)
|
|
sfg_bom_line_ids = fields.One2many('sos_sfg_bom_line', 'fg_bom_id', string='BOM Lines',copy=True, ondelete='cascade')
|
|
fg_name = fields.Many2one('sos_fg', string='FG Name')
|
|
miscellaneous_ids = fields.One2many('miscellaneous_items', 'main_model_id', string='Miscellaneous Costs',copy=True, ondelete='cascade')
|
|
bom_version = fields.Char(string="BOM Version")
|
|
is_primary = fields.Boolean(string="Set as Primary",help="This BOM will be used in Indent Plan",copy=False)
|
|
responsible_person = fields.Many2many('res.users', string='Read Access allowed to')
|
|
def write(self, vals):
|
|
for record in self:
|
|
if 'is_primary' in vals and vals['is_primary']:
|
|
other_boms = self.env['sos_fg_bom'].search([
|
|
('fg_name', '=', record.fg_name.id),
|
|
('id', '!=', record.id)
|
|
])
|
|
|
|
other_boms.write({'is_primary': False})
|
|
self._sync_unit_price_with_fg()
|
|
result = super(SOS_Fg_Bom, self).write(vals)
|
|
return result
|
|
|
|
@api.returns('self', lambda value: value.id)
|
|
def copy(self, default=None):
|
|
if default is None:
|
|
default = {}
|
|
if 'bom_version' not in default:
|
|
default['bom_version'] = f"{self.bom_version} (copy)"
|
|
if 'name' not in default:
|
|
default['name'] = f"{self.name} (copy)"
|
|
if 'fg_name' not in default:
|
|
default['fg_name'] = self.fg_name.id
|
|
return super(SOS_Fg_Bom, self).copy(default)
|
|
|
|
@api.constrains('name', 'fg_name', 'bom_version')
|
|
def check_unique_values(self):
|
|
for record in self:
|
|
existing_records = self.search([
|
|
('name', '=', record.name),
|
|
('fg_name', '=', record.fg_name.id),
|
|
('bom_version', '=', record.bom_version),
|
|
('id', '!=', record.id)
|
|
])
|
|
if existing_records:
|
|
raise ValidationError("The combination of Name, FG Name, and BOM Version must be unique across all records.")
|
|
|
|
@api.depends('sfg_cost','component_cost', 'miscellaneous_cost')
|
|
def _compute_overall_total(self):
|
|
for record in self:
|
|
record.overall_total = record.sfg_cost + record.component_cost + record.miscellaneous_cost
|
|
record._sync_unit_price_with_fg()
|
|
|
|
@api.depends('sfg_bom_line_ids.unit_price')
|
|
def _compute_component_cost(self):
|
|
for record in self:
|
|
record.component_cost = sum(line.total_cost for line in record.sfg_bom_line_ids)
|
|
|
|
@api.depends('miscellaneous_ids.cost')
|
|
def _compute_miscellaneous_cost(self):
|
|
for record in self:
|
|
record.miscellaneous_cost = sum(line.cost for line in record.miscellaneous_ids)
|
|
|
|
|
|
@api.depends('fg_bom_line_ids.unit_price')
|
|
def _compute_sfg_cost(self):
|
|
for record in self:
|
|
record.sfg_cost = sum(line.unit_price for line in record.fg_bom_line_ids)
|
|
@api.model
|
|
def create(self, vals):
|
|
res = super(SOS_Fg_Bom, self).create(vals)
|
|
res._sync_unit_price_with_fg()
|
|
return res
|
|
|
|
|
|
|
|
def _sync_unit_price_with_fg(self):
|
|
sos_fg_obj = self.env['sos_fg']
|
|
for record in self:
|
|
fg_record = sos_fg_obj.search([('id', '=', record.fg_name.id)], limit=1)
|
|
if fg_record:
|
|
try:
|
|
fg_record.write({'unit_price': record.overall_total})
|
|
except Exception as e:
|
|
print("Error updating unit price:", e)
|
|
|
|
class SOS_Fg_Bom_Line(models.Model):
|
|
_name = 'sos_fg_bom_line'
|
|
_description = 'BOM of Finished Goods Lines'
|
|
|
|
bom_id = fields.Many2one('sos_fg_bom', string="fg BOM Reference")
|
|
primary_component_id = fields.Many2one('sos_material', string='Primary Part No')
|
|
sfg_bom_id = fields.Many2one('sos_sfg_bom', string='SFG BOM Reference', domain="[('fg_name', '=', parent.fg_name)]", required=False)
|
|
quantity = fields.Float(string="Qty", required=True,default=1)
|
|
currency_id = fields.Many2one('res.currency')
|
|
unit_price = fields.Monetary(compute='_compute_unit_price', string="Unit Price", currency_field='currency_id', readonly=True)
|
|
total_cost = fields.Monetary(compute='_compute_total_cost', string="Estimated Cost", currency_field='currency_id', readonly=True)
|
|
|
|
@api.onchange('bom_id')
|
|
def _onchange_bom_id(self):
|
|
if self.bom_id:
|
|
return {'domain': {'sfg_bom_id': [('fg_name', '=', self.bom_id.fg_name.id)]}}
|
|
else:
|
|
return {'domain': {'sfg_bom_id': []}}
|
|
|
|
|
|
@api.depends('primary_component_id.unit_price', 'sfg_bom_id.name', 'quantity')
|
|
def _compute_unit_price(self):
|
|
for record in self:
|
|
if record.primary_component_id:
|
|
record.unit_price = record.primary_component_id.unit_price
|
|
elif record.sfg_bom_id:
|
|
record.unit_price = record.sfg_bom_id.name.unit_price * record.quantity
|
|
else:
|
|
record.unit_price = 0
|
|
|
|
@api.depends('unit_price', 'quantity')
|
|
def _compute_total_cost(self):
|
|
for record in self:
|
|
record.total_cost = record.unit_price * record.quantity |