diff --git a/__init__.py b/__init__.py index 2363da1..da4686b 100644 --- a/__init__.py +++ b/__init__.py @@ -6,13 +6,6 @@ from . import production def register(): Pool.register( production.BOM, - production.Lot, production.Production, - production.StockMove, - module='production_lot_cost', type_='model') - Pool.register( - production.LotCostLine, - production.Operation, - depends=['production_operation'], module='production_lot_cost', type_='model') diff --git a/production.py b/production.py index 6b34b83..b4b4fd6 100644 --- a/production.py +++ b/production.py @@ -2,13 +2,7 @@ # copyright notices and license terms. from decimal import Decimal from trytond.model import fields -from trytond.pool import Pool, PoolMeta -from trytond.transaction import Transaction -from trytond.exceptions import UserError -from trytond.i18n import gettext -from trytond.modules.product import price_digits, round_price - -__all__ = ['BOM', 'Lot', 'Production', 'StockMove', 'LotCostLine', 'Operation'] +from trytond.pool import PoolMeta class BOM(metaclass=PoolMeta): @@ -18,22 +12,6 @@ class BOM(metaclass=PoolMeta): help='Infrastructure cost per lot unit') -class Lot(metaclass=PoolMeta): - __name__ = 'stock.lot' - - def _on_change_product_cost_lines(self): - pool = Pool() - Move = pool.get('stock.move') - - context = Transaction().context - if context.get('from_move'): - move = Move(context['from_move']) - if getattr(move, 'production_output', False): - return {} - - return super(Lot, self)._on_change_product_cost_lines() - - class Production(metaclass=PoolMeta): __name__ = 'production' @@ -66,208 +44,3 @@ class Production(metaclass=PoolMeta): cost += (Decimal(str(output.internal_quantity)) * self.infrastructure_cost) return cost - - #def explode_bom(self): - #super(Production, self).explode_bom() - #outputs = self.outputs - #for move in outputs: - #if self.infrastructure_cost and move.product == self.product: - #move.unit_price += self.infrastructure_cost - - @classmethod - def set_cost(cls, productions): - pool = Pool() - Lot = pool.get('stock.lot') - CostLot = pool.get('stock.lot.cost_line') - try: - Operation = pool.get('production.operation') - except: - pass - - super(Production, cls).set_cost(productions) - - to_save = [] - to_check = [] - for production in productions: - output_quantity = sum([x.internal_quantity for x in - production.outputs if x.product == production.product]) - - if hasattr(production, 'operations') and hasattr(cls, 'lot'): - ops = [] - for output in production.outputs: - ops += [x for x in production.operations if - output.lot and x.lot == output.lot] - - for output in production.outputs: - cost_lines = [] - if not output.lot: - continue - if not output.lot.cost_lines: - cost_lines = output._get_production_output_lot_cost_lines() - if hasattr(production, 'operations') and hasattr(cls, 'lot'): - operations = [x for x in production.operations if - output.lot and x.lot == output.lot] - cost_lines += Operation._get_operation_lot_cost_line( - operations, output.internal_quantity, output) - operations = [x for x in production.operations if - (x.lot is None or x not in ops)] - cost_lines += Operation._get_operation_lot_cost_line( - operations, output_quantity, output) - to_save += cost_lines - to_check.append((output, output.lot)) - - if to_save: - CostLot.save(to_save) - if to_check: - for move, lot in to_check: - move.check_lot_cost(lot) - -class LotCostLine(metaclass=PoolMeta): - __name__ = 'stock.lot.cost_line' - - @classmethod - def _get_origin(cls): - return super()._get_origin() + ['production.operation',] - - -class Operation(metaclass=PoolMeta): - __name__ = 'production.operation' - - @classmethod - def _get_operation_lot_cost_line(cls, operations, quantity, move): - pool = Pool() - Category = pool.get('stock.lot.cost_category') - LotCostLine = pool.get('stock.lot.cost_line') - - categories = dict((x.name, x) for x in Category.search([])) - - vals = {} - for operation in operations: - cat = operation.operation_type.name - if cat not in categories: - category = Category(name=cat) - category.save() - categories[cat] = category - else: - category = categories[cat] - if category not in vals: - vals[category] = 0 - - vals[category] += operation.cost - - cost_lines = [] - for category, cost in vals.items(): - cost_line = LotCostLine( - category=category.id, - lot = move.lot, - unit_price=Decimal(float(cost)/quantity if quantity else 0), - origin=str(move), - ) - cost_lines += [cost_line] - return cost_lines - - -class StockMove(metaclass=PoolMeta): - __name__ = 'stock.move' - - def check_lot_cost(self, lot): - ''' - If production output quantity is changed manually, it cannot be - computed the lot cost, so lot must be created manually. - ''' - production = self.production_output - - if self.uom != production.uom: - unit_price = self.uom.compute_price(self.uom, self.unit_price, - production.uom) - else: - unit_price = self.unit_price - - cost_price = round_price(lot.cost_price) - unit_price = round_price(unit_price) - - if unit_price != cost_price: - raise UserError(gettext('production_lot_cost.msg_uneven_costs', - move=self.rec_name, - move_unit_price=self.unit_price, - lot=self.lot, - lot_unit_price=lot.cost_price, - )) - - def get_production_output_lot(self): - lot = super(StockMove, self).get_production_output_lot() - if lot: - cost_lines = self._get_production_output_lot_cost_lines() - if cost_lines and not getattr(lot, 'cost_lines', False): - lot.cost_lines = cost_lines - return lot - - def _get_production_output_lot_cost_lines(self): - ''' - Return a list of unpersistent stock.lot.cost_line instances to be - writen in cost_lines field of output_move's lot (the returned lines - doesn't have the lot's field) - ''' - pool = Pool() - ModelData = pool.get('ir.model.data') - - inputs_category_id = ModelData.get_id('production_lot_cost', - 'cost_category_inputs_cost') - infrastructure_category_id = ModelData.get_id('production_lot_cost', - 'cost_category_infrastructure_cost') - - # Unit price of cost_line should not include infrastructure_cost but - # as production.cost computed method is overriden and it includes this - # cost, here we must compute the original production cost again - production = self.production_output - cost = Decimal(0) - for input_ in production.inputs: - if input_.lot and input_.lot.cost_price: - cost_price = input_.lot.cost_price - elif input_.cost_price is not None: - cost_price = input_.cost_price - else: - cost_price = input_.product.cost_price - cost += (Decimal(str(input_.internal_quantity)) * cost_price) - - factor = 1 - res = [] - if production.bom: - factor = production.bom.compute_factor(production.product, - production.quantity or 0, production.uom) - for output in production.bom and production.bom.outputs or []: - quantity = output.compute_quantity(factor) - if output.product == self.product and quantity: - res.append( - self._get_production_output_lot_cost_line( - inputs_category_id, - Decimal(cost / Decimal(str(quantity))), self.lot) - ) - - elif (self.product == production.product and self.quantity): - quantity = production.output_qty - if quantity: - res.append( - self._get_production_output_lot_cost_line( - inputs_category_id, - Decimal(cost / Decimal(str(quantity))), self.lot) - ) - - if (self.product == production.product and - production.infrastructure_cost): - infrastructure_cost = self._get_production_output_lot_cost_line( - infrastructure_category_id, production.infrastructure_cost, - self.lot) - res.append(infrastructure_cost) - - return res - - def _get_production_output_lot_cost_line(self, category_id, cost, lot): - pool = Pool() - LotCostLine = pool.get('stock.lot.cost_line') - return LotCostLine( - category=category_id, - unit_price=cost, - origin=str(self), - lot=lot, - ) diff --git a/tests/scenario_production_lot_cost.rst b/tests/scenario_production_lot_cost.rst index 211cbc3..16616b6 100644 --- a/tests/scenario_production_lot_cost.rst +++ b/tests/scenario_production_lot_cost.rst @@ -211,8 +211,6 @@ Make a production with infrastructure cost:: >>> output, = production.outputs >>> output.state 'done' - >>> len(output.lot.cost_lines) - 2 >>> production.cost == Decimal('27') True >>> output, = production.outputs diff --git a/tests/scenario_production_lot_cost_with_output_lot.rst b/tests/scenario_production_lot_cost_with_output_lot.rst index 001db0c..0f86ece 100644 --- a/tests/scenario_production_lot_cost_with_output_lot.rst +++ b/tests/scenario_production_lot_cost_with_output_lot.rst @@ -183,8 +183,6 @@ production is Running:: >>> output, = production.outputs >>> output.state 'done' - >>> len(output.lot.cost_lines) - 2 >>> production.cost == Decimal('27') True >>> output.unit_price @@ -231,7 +229,5 @@ production is done:: True >>> output.unit_price Decimal('13.5000') - >>> len(output.lot.cost_lines) - 2 >>> output.lot.cost_price == Decimal('13.5') True diff --git a/tryton.cfg b/tryton.cfg index e882b5e..aef7737 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -5,7 +5,6 @@ depends: stock_lot_cost extras_depend: production_output_lot - production_operation xml: production.xml message.xml