97 lines
3.5 KiB
Python
97 lines
3.5 KiB
Python
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
|
# this repository contains the full copyright notices and license terms.
|
|
from decimal import Decimal
|
|
from datetime import datetime, date
|
|
|
|
from trytond.pool import Pool, PoolMeta
|
|
from trytond.modules.product import round_price
|
|
from trytond.model import fields, ModelSQL, ModelView
|
|
|
|
|
|
class BOM(metaclass=PoolMeta):
|
|
__name__ = 'production.bom'
|
|
direct_costs = fields.One2Many('production.bom.direct_cost', 'bom',
|
|
'Direct Costs')
|
|
is_subproduction = fields.Boolean('Is Subproduction')
|
|
|
|
@classmethod
|
|
def calc_cost_ldm(cls):
|
|
# This method is temporal for CRON sync for a specific customer
|
|
ProductLdm = Pool().get('production.bom')
|
|
ProductLdmOut = Pool().get('production.bom.output')
|
|
Product = Pool().get('product.product')
|
|
Uom = Pool().get('product.uom')
|
|
|
|
current_date = datetime.combine(date.today(), datetime.min.time())
|
|
ldm_outs = ProductLdmOut.search_read([], fields_names=['id', 'product'])
|
|
products_ldm = [p['product'] for p in ldm_outs]
|
|
products = Product.search([
|
|
('active', '=', True),
|
|
('template.producible', '=', True),
|
|
('write_date', '<', current_date),
|
|
('id', 'in', products_ldm)
|
|
], limit=30)
|
|
prd_ids = [p.id for p in products]
|
|
products_ldm = ProductLdm.search([
|
|
('active', '=', True),
|
|
('output_products', 'in', prd_ids)
|
|
])
|
|
uom_compute_qty = Uom.compute_qty
|
|
for ldm in products_ldm:
|
|
output = ldm.outputs[0]
|
|
if not ldm.outputs or not ldm.inputs:
|
|
continue
|
|
cost = ldm.get_cost_ldm(uom_compute_qty)
|
|
if cost > 0:
|
|
cost = round(cost / Decimal(output.quantity), 4)
|
|
Product.write([output.product], {'cost_price': cost})
|
|
|
|
def compute_unit_cost(self):
|
|
Product = Pool().get('product.product')
|
|
total_cost = self.get_cost_ldm()
|
|
cost = 0
|
|
for output in self.outputs:
|
|
if output.quantity > 0:
|
|
cost = round(total_cost / Decimal(output.quantity), 4)
|
|
Product.write([output.product], {'cost_price': cost})
|
|
return cost
|
|
|
|
def get_cost_ldm(self):
|
|
Uom = Pool().get('product.uom')
|
|
compute_qty = Uom.compute_qty
|
|
res = []
|
|
for input_ in self.inputs:
|
|
quantity = compute_qty(
|
|
input_.uom, input_.quantity,
|
|
input_.product.default_uom)
|
|
cost_price = input_.product.cost_price
|
|
res.append(Decimal(str(quantity)) * cost_price)
|
|
|
|
return round_price(sum(res))
|
|
|
|
|
|
class BOMDirectCost(ModelSQL, ModelView):
|
|
"BOMDirectCost"
|
|
__name__ = "production.bom.direct_cost"
|
|
bom = fields.Many2One('production.bom', 'BOM', required=True,
|
|
ondelete='CASCADE')
|
|
product = fields.Many2One('product.product', 'Product', required=True,
|
|
domain=[('type', '!=', 'active')])
|
|
uom = fields.Many2One('product.uom', 'UoM')
|
|
quantity = fields.Float('Quantity', required=True, digits=(16, 2))
|
|
notes = fields.Char('Notes')
|
|
kind = fields.Selection([
|
|
('labour', 'Labour'),
|
|
('indirect', 'Indirect'),
|
|
('service', 'Service'),
|
|
], 'Kind')
|
|
|
|
@staticmethod
|
|
def default_kind():
|
|
return 'labour'
|
|
|
|
@fields.depends('product', 'uom')
|
|
def on_change_with_uom(self, name=None):
|
|
if self.product:
|
|
return self.product.default_uom.id
|