diff --git a/CHANGELOG b/CHANGELOG index a611353c99..e4e20ef347 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Allow lost_found as output of production * Keep cost of unused input products * Use the shipment assign wizard for production * Rename production state from cancel to cancelled diff --git a/production.py b/production.py index 3beebf3a0f..5c9fca5c2c 100644 --- a/production.py +++ b/production.py @@ -131,7 +131,10 @@ class Production(ShipmentAssignMixin, Workflow, ModelSQL, ModelView): domain=[ ('shipment', '=', None), ('from_location', '=', Eval('location')), - ('to_location', 'child_of', [Eval('warehouse')], 'parent'), + ['OR', + ('to_location', 'child_of', [Eval('warehouse')], 'parent'), + ('to_location.waste_warehouses', '=', Eval('warehouse')), + ], ('company', '=', Eval('company', -1)), ], states={ @@ -545,6 +548,8 @@ class Production(ShipmentAssignMixin, Workflow, ModelSQL, ModelView): Decimal(str(input_.internal_quantity)) * cost_price) outputs = [] for output in production.outputs: + if output.to_location.type == 'lost_found': + continue product = output.product if input_quantities.get(output.product): cost_price = ( diff --git a/tests/scenario_production_waste.rst b/tests/scenario_production_waste.rst new file mode 100644 index 0000000000..6973e559f2 --- /dev/null +++ b/tests/scenario_production_waste.rst @@ -0,0 +1,92 @@ +========================= +Production Waste 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) + +Activate modules:: + + >>> config = activate_modules('production') + +Create company:: + + >>> _ = create_company() + >>> company = get_company() + +Create main product:: + + >>> ProductUom = Model.get('product.uom') + >>> unit, = ProductUom.find([('name', '=', 'Unit')]) + >>> ProductTemplate = Model.get('product.template') + + >>> template = ProductTemplate() + >>> template.name = 'product' + >>> template.default_uom = unit + >>> template.type = 'goods' + >>> template.producible = True + >>> template.list_price = Decimal(20) + >>> template.save() + >>> product, = template.products + +Create Component:: + + >>> template = ProductTemplate() + >>> template.name = 'component 1' + >>> template.default_uom = unit + >>> template.type = 'goods' + >>> template.list_price = Decimal(50) + >>> component, = template.products + >>> component.cost_price = Decimal(1) + >>> template.save() + >>> component, = template.products + +Configure locations:: + + >>> Location = Model.get('stock.location') + >>> lost_found_loc, = Location.find([('type', '=', 'lost_found')]) + >>> warehouse_loc, = Location.find([('type', '=', 'warehouse')]) + >>> warehouse_loc.waste_locations.append(lost_found_loc) + >>> warehouse_loc.save() + +Run the production:: + + >>> Production = Model.get('production') + >>> production = Production() + >>> input = production.inputs.new() + >>> input.quantity = 20.0 + >>> input.product = component + >>> input.from_location = warehouse_loc.storage_location + >>> input.to_location = production.location + >>> production.click('wait') + >>> production.click('assign_force') + >>> production.click('run') + +Create outputs including waste products:: + + >>> output = production.outputs.new() + >>> output.quantity = 1.0 + >>> output.product = product + >>> output.from_location = production.location + >>> output.to_location = warehouse_loc.storage_location + >>> output.unit_price = Decimal('0') + >>> waste_output = production.outputs.new() + >>> waste_output.quantity = 1.0 + >>> waste_output.product = product + >>> waste_output.from_location = production.location + >>> waste_output.to_location = lost_found_loc + >>> production.click('done') + >>> production.cost + Decimal('20.0000') + >>> output, = [o for o in production.outputs + ... if o.to_location.type != 'lost_found'] + >>> output.unit_price + Decimal('20.0000') + >>> waste_output, = [o for o in production.outputs + ... if o.to_location.type == 'lost_found'] + >>> waste_output.unit_price diff --git a/tests/test_production.py b/tests/test_production.py index 74dac25af3..4e7af79f3d 100644 --- a/tests/test_production.py +++ b/tests/test_production.py @@ -67,4 +67,8 @@ def suite(): tearDown=doctest_teardown, encoding='utf-8', checker=doctest_checker, optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) + suite.addTests(doctest.DocFileSuite('scenario_production_waste.rst', + tearDown=doctest_teardown, encoding='utf-8', + checker=doctest_checker, + optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) return suite