From 6dce79287b4566cd538da2cc0d45662fe6aee2d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 2 Feb 2017 12:12:19 +0100 Subject: [PATCH] Ceil input and floor output quantities This is a more realistic behaviour for a production. issue2956 review33791002 --- CHANGELOG | 1 + bom.py | 5 +- setup.py | 1 + tests/scenario_production_rounding.rst | 105 +++++++++++++++++++++++++ tests/test_production.py | 4 + 5 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 tests/scenario_production_rounding.rst diff --git a/CHANGELOG b/CHANGELOG index 7fd0fc925e..e7c144ed97 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Ceil input and floor output quantities * Add producible to product template Version 4.2.0 - 2016-11-28 diff --git a/bom.py b/bom.py index 056841848e..73c384d7b7 100644 --- a/bom.py +++ b/bom.py @@ -121,7 +121,7 @@ class BOMInput(ModelSQL, ModelView): self.product.check_bom_recursion() def compute_quantity(self, factor): - return self.uom.round(self.quantity * factor) + return self.uom.ceil(self.quantity * factor) class BOMOutput(BOMInput): @@ -129,6 +129,9 @@ class BOMOutput(BOMInput): __name__ = 'production.bom.output' _table = 'production_bom_output' # Needed to override BOMInput._table + def compute_quantity(self, factor): + return self.uom.floor(self.quantity * factor) + @classmethod def delete(cls, outputs): pool = Pool() diff --git a/setup.py b/setup.py index 487145f5aa..e50c122ad8 100644 --- a/setup.py +++ b/setup.py @@ -124,5 +124,6 @@ setup(name=name, use_2to3=True, convert_2to3_doctests=[ 'tests/scenario_production.rst', + 'tests/scenario_production_rounding.rst', ], ) diff --git a/tests/scenario_production_rounding.rst b/tests/scenario_production_rounding.rst new file mode 100644 index 0000000000..4fc4118e90 --- /dev/null +++ b/tests/scenario_production_rounding.rst @@ -0,0 +1,105 @@ +============================ +Production Rounding Scenario +============================ + +Imports:: + + >>> from decimal import Decimal + >>> from proteus import Model, Wizard + >>> from trytond.tests.tools import activate_modules + >>> from trytond.modules.company.tests.tools import create_company, \ + ... get_company + +Install production Module:: + + >>> config = activate_modules('production') + +Create company:: + + >>> _ = create_company() + >>> company = get_company() + +Create product:: + + >>> ProductUom = Model.get('product.uom') + >>> unit, = ProductUom.find([('name', '=', 'Unit')]) + >>> ProductTemplate = Model.get('product.template') + >>> Product = Model.get('product.product') + >>> product = Product() + >>> template = ProductTemplate() + >>> template.name = 'product' + >>> template.default_uom = unit + >>> template.type = 'goods' + >>> template.producible = True + >>> template.list_price = Decimal(30) + >>> template.cost_price = Decimal(20) + >>> template.save() + >>> product.template = template + >>> product.save() + +Create component:: + + >>> component = Product() + >>> template = ProductTemplate() + >>> template.name = 'component' + >>> template.default_uom = unit + >>> template.type = 'goods' + >>> template.list_price = Decimal(5) + >>> template.cost_price = Decimal(1) + >>> template.save() + >>> component.template = template + >>> component.save() + +Create residual:: + + >>> residual = Product() + >>> template = ProductTemplate() + >>> template.name = 'residual' + >>> template.default_uom = unit + >>> template.type = 'goods' + >>> template.list_price = Decimal(0) + >>> template.cost_price = Decimal(0) + >>> template.save() + >>> residual.template = template + >>> residual.save() + +Create Bill of Material with rational ratio:: + + >>> BOM = Model.get('production.bom') + >>> bom = BOM(name='product') + >>> input = bom.inputs.new() + >>> input.product = component + >>> input.quantity = 4 + >>> output = bom.outputs.new() + >>> output.product = product + >>> output.quantity = 9 + >>> output = bom.outputs.new() + >>> output.product = residual + >>> output.quantity = 8 + >>> bom.save() + +Make a production with rounding:: + + >>> Production = Model.get('production') + >>> production = Production() + >>> production.product = product + >>> production.bom = bom + >>> production.quantity = 3 + +Check component is ceiled:: + + >>> input, = production.inputs + >>> input.quantity + 2.0 + +Check product quantity:: + + >>> output, = [o for o in production.outputs if o.product == product] + >>> output.quantity + 3.0 + +Check residual is floored:: + + >>> output, = [o for o in production.outputs if o.product == residual] + >>> output.quantity + 2.0 diff --git a/tests/test_production.py b/tests/test_production.py index 0adcffceab..2bcf2ec596 100644 --- a/tests/test_production.py +++ b/tests/test_production.py @@ -50,4 +50,8 @@ def suite(): tearDown=doctest_teardown, encoding='utf-8', checker=doctest_checker, optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) + suite.addTests(doctest.DocFileSuite('scenario_production_rounding.rst', + tearDown=doctest_teardown, encoding='utf-8', + checker=doctest_checker, + optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) return suite