From fb9f01e23e911e07571a1673dfa305d4ec27ce40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 21 Dec 2020 00:18:02 +0100 Subject: [PATCH] Allow shipment cost price to be edited issue9911 review329841002 --- CHANGELOG | 2 + sale.py | 21 ++-- ...enario_sale_shipment_cost_modify_price.rst | 116 ++++++++++++++++++ tests/test_sale_shipment_cost.py | 5 + 4 files changed, 136 insertions(+), 8 deletions(-) create mode 100644 tests/scenario_sale_shipment_cost_modify_price.rst diff --git a/CHANGELOG b/CHANGELOG index 83a3f3c6ce..c2dcbda33f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +* Allow shipment cost price to be edited + Version 5.8.0 - 2020-11-02 * Bug fixes (see mercurial logs for details) * Remove support for Python 3.5 diff --git a/sale.py b/sale.py index fd93f00b47..4a6e654974 100644 --- a/sale.py +++ b/sale.py @@ -1,5 +1,7 @@ # 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 trytond import backend from trytond.i18n import gettext from trytond.model import ModelView, Workflow, fields @@ -206,23 +208,23 @@ class Sale(metaclass=PoolMeta): return 0 def set_shipment_cost(self): - cost_line = None cost = self.compute_shipment_cost() - if cost: - cost_line = self.get_shipment_cost_line(cost) - removed = [] + unit_price = None lines = list(self.lines or []) for line in self.lines: if line.type == 'line' and line.shipment_cost: + if line.shipment_cost == cost: + unit_price = line.unit_price * Decimal(str(line.quantity)) lines.remove(line) removed.append(line) - if cost_line: - lines.append(cost_line) + if cost: + lines.append(self.get_shipment_cost_line( + cost, unit_price=unit_price)) self.lines = lines return removed - def get_shipment_cost_line(self, cost): + def get_shipment_cost_line(self, cost, unit_price=None): pool = Pool() SaleLine = pool.get('sale.line') @@ -245,7 +247,10 @@ class Sale(metaclass=PoolMeta): shipment_cost=shipment_cost, ) cost_line.on_change_product() - cost_line.unit_price = round_price(cost) + if unit_price is not None: + cost_line.unit_price = round_price(unit_price) + else: + cost_line.unit_price = round_price(cost) cost_line.amount = cost_line.on_change_with_amount() return cost_line diff --git a/tests/scenario_sale_shipment_cost_modify_price.rst b/tests/scenario_sale_shipment_cost_modify_price.rst new file mode 100644 index 0000000000..5df93eeaf2 --- /dev/null +++ b/tests/scenario_sale_shipment_cost_modify_price.rst @@ -0,0 +1,116 @@ +======================================== +Sale Shipment Cost Modify Price Scenario +======================================== + +Imports:: + + >>> from decimal import Decimal + >>> from proteus import Model + >>> from trytond.tests.tools import activate_modules + >>> from trytond.modules.company.tests.tools import ( + ... create_company, get_company) + +Activate modules:: + + >>> config = activate_modules('sale_shipment_cost') + +Create company:: + + >>> _ = create_company() + >>> company = get_company() + +Create customer:: + + >>> Party = Model.get('party.party') + >>> customer = Party(name='Customer') + >>> customer.save() + +Create account category:: + + >>> ProductCategory = Model.get('product.category') + >>> account_category = ProductCategory(name="Account Category") + >>> account_category.accounting = True + >>> account_category.save() + +Create product:: + + >>> ProductUom = Model.get('product.uom') + >>> ProductTemplate = Model.get('product.template') + >>> unit, = ProductUom.find([('name', '=', 'Unit')]) + + >>> template = ProductTemplate() + >>> template.name = 'Product' + >>> template.default_uom = unit + >>> template.type = 'goods' + >>> template.salable = True + >>> template.list_price = Decimal('20') + >>> template.account_category = account_category + >>> template.save() + >>> product, = template.products + + >>> carrier_template = ProductTemplate() + >>> carrier_template.name = 'Carrier Product' + >>> carrier_template.default_uom = unit + >>> carrier_template.type = 'service' + >>> carrier_template.salable = True + >>> carrier_template.list_price = Decimal('3') + >>> carrier_template.account_category = account_category + >>> carrier_template.save() + >>> carrier_product, = carrier_template.products + +Create carrier:: + + >>> Carrier = Model.get('carrier') + >>> carrier = Carrier() + >>> party = Party(name='Carrier') + >>> party.save() + >>> carrier.party = party + >>> carrier.carrier_product = carrier_product + >>> carrier.save() + +Make a quote:: + + >>> Sale = Model.get('sale.sale') + >>> sale = Sale() + >>> sale.party = customer + >>> sale.carrier = carrier + >>> sale_line = sale.lines.new() + >>> sale_line.product = product + >>> sale_line.quantity = 5.0 + >>> sale.click('quote') + >>> cost_line = sale.lines[-1] + >>> cost_line.product == carrier_product + True + >>> cost_line.quantity + 1.0 + >>> cost_line.amount + Decimal('3.00') + +Change the shipment cost price:: + + >>> sale.click('draft') + >>> cost_line = sale.lines[-1] + >>> cost_line.unit_price = Decimal('2.00') + >>> sale.click('quote') + >>> cost_line = sale.lines[-1] + >>> cost_line.product == carrier_product + True + >>> cost_line.quantity + 1.0 + >>> cost_line.amount + Decimal('2.00') + +Change the carrier price reset the cost line:: + + >>> carrier_template.list_price = Decimal('4') + >>> carrier_template.save() + + >>> sale.click('draft') + >>> sale.click('quote') + >>> cost_line = sale.lines[-1] + >>> cost_line.product == carrier_product + True + >>> cost_line.quantity + 1.0 + >>> cost_line.amount + Decimal('4.00') diff --git a/tests/test_sale_shipment_cost.py b/tests/test_sale_shipment_cost.py index 4ee0aa07ca..ab5edc426f 100644 --- a/tests/test_sale_shipment_cost.py +++ b/tests/test_sale_shipment_cost.py @@ -22,4 +22,9 @@ def suite(): tearDown=doctest_teardown, encoding='utf-8', checker=doctest_checker, optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) + suite.addTests(doctest.DocFileSuite( + 'scenario_sale_shipment_cost_modify_price.rst', + tearDown=doctest_teardown, encoding='utf-8', + checker=doctest_checker, + optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) return suite