Slink/sos_inventory/models/sos_fg_bom.py

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