From c1c8b4a8d3ee1fa31c319e5f3a20017692c3f48e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sat, 13 Mar 2021 23:43:51 +0100 Subject: [PATCH] Simplify manual alteration of shipment cost issue10142 review340111002 --- CHANGELOG | 1 + sale.py | 12 -- stock.py | 161 ++++++++++++++++++++------ tests/scenario_sale_shipment_cost.rst | 14 +-- view/shipment_out_form.xml | 20 ++-- 5 files changed, 144 insertions(+), 64 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 151276fc81..9a4e3cab17 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Simplify manual alteration of shipment cost * Use purchase carrier price as cost for shipment * Allow shipment costs to not be sold * Add carrier on shipment list view diff --git a/sale.py b/sale.py index a8dad4f114..dc8825e488 100644 --- a/sale.py +++ b/sale.py @@ -268,23 +268,11 @@ class Sale(metaclass=PoolMeta): def create_shipment(self, shipment_type): pool = Pool() Shipment = pool.get('stock.shipment.out') - Currency = pool.get('currency.currency') shipments = super(Sale, self).create_shipment(shipment_type) if shipment_type == 'out' and shipments and self.carrier: for shipment in shipments: shipment.carrier = self.carrier - with Transaction().set_context( - shipment.get_carrier_context()): - cost, currency_id = self.carrier.get_purchase_price() - shipment.cost = round_price(Currency.compute( - Currency(currency_id), cost, shipment.company.currency, - round=False)) - with Transaction().set_context( - shipment.get_carrier_context()): - cost_sale, currency_id = self.carrier.get_sale_price() - shipment.cost_sale = round_price(cost_sale) - shipment.cost_sale_currency = currency_id Shipment.save(shipments) return shipments diff --git a/stock.py b/stock.py index 9036e0fee0..b409d28a41 100644 --- a/stock.py +++ b/stock.py @@ -1,7 +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 trytond.i18n import gettext -from trytond.model import fields +from trytond.model import ModelView, Workflow, fields from trytond.pyson import Eval, Bool from trytond.transaction import Transaction from trytond.pool import Pool, PoolMeta @@ -17,27 +17,62 @@ class ShipmentOut(metaclass=PoolMeta): 'picked', 'packed']), }, depends=['state']) - cost = fields.Numeric("Cost", - digits=price_digits, states={ - 'invisible': ~Eval('carrier'), + + cost_used = fields.Function(fields.Numeric( + "Cost", digits=price_digits, + states={ + 'invisible': ~Eval('carrier') | Eval('cost_edit', False), + }, + depends=['carrier', 'cost_edit']), + 'on_change_with_cost_used') + cost = fields.Numeric( + "Cost", digits=price_digits, + states={ + 'invisible': ~Eval('carrier') | ~Eval('cost_edit', False), 'readonly': ~Eval('state').in_( - ['draft', 'waiting', 'assigned', 'packed']), - }, depends=['carrier', 'state']) + ['draft', 'waiting', 'assigned', 'picked', 'packed']), + }, + depends=['carrier', 'state']) + cost_sale_currency_used = fields.Function(fields.Many2One( + 'currency.currency', "Cost Sale Currency", + states={ + 'invisible': ~Eval('carrier') | Eval('cost_edit', False), + }, + depends=['carrier', 'cost_edit']), + 'on_change_with_cost_sale_currency_used') cost_sale_currency = fields.Many2One( 'currency.currency', "Cost Sale Currency", states={ - 'invisible': ~Eval('carrier'), - 'required': Bool(Eval('carrier')), + 'invisible': ~Eval('carrier') | ~Eval('cost_edit', False), + 'required': Bool(Eval('cost_sale')), + 'readonly': ~Eval('state').in_( + ['draft', 'waiting', 'assigned', 'picked', 'packed']), + }, depends=['carrier', 'cost_sale', 'state']) + cost_sale_used = fields.Function(fields.Numeric( + "Cost Sale", digits=price_digits, + states={ + 'invisible': ~Eval('carrier') | Eval('cost_edit', False), + }, + depends=['carrier', 'cost_edit']), + 'on_change_with_cost_sale_used') + cost_sale = fields.Numeric( + "Cost Sale", digits=price_digits, + states={ + 'invisible': ~Eval('carrier') | ~Eval('cost_edit', False), 'readonly': ~Eval('state').in_( ['draft', 'waiting', 'assigned', 'picked', 'packed']), }, depends=['carrier', 'state']) - cost_sale = fields.Numeric( - "Cost Sale", digits=price_digits, + + cost_edit = fields.Boolean( + "Edit Cost", states={ 'invisible': ~Eval('carrier'), 'readonly': ~Eval('state').in_( ['draft', 'waiting', 'assigned', 'picked', 'packed']), - }, depends=['carrier', 'state']) + }, + depends=['carrier', 'state'], + help="Check to edit the cost.") + cost_invoice_line = fields.Many2One('account.invoice.line', 'Cost Invoice Line', readonly=True) @@ -59,31 +94,59 @@ class ShipmentOut(metaclass=PoolMeta): def get_carrier_context(self): return self._get_carrier_context() - @fields.depends(methods=['on_change_inventory_moves']) - def on_change_carrier(self): - self.on_change_inventory_moves() - @fields.depends('carrier', 'company', methods=['_get_carrier_context']) - def on_change_inventory_moves(self): + def _compute_costs(self): pool = Pool() Currency = pool.get('currency.currency') - try: - super(ShipmentOut, self).on_change_inventory_moves() - except AttributeError: - pass - if not self.carrier: - self.cost = None - self.cost_sale = None - self.cost_sale_currency = None - return - with Transaction().set_context(self._get_carrier_context()): - cost, currency_id = self.carrier.get_purchase_price() - cost_sale, sale_currency_id = self.carrier.get_sale_price() - self.cost = round_price(Currency.compute( - Currency(currency_id), cost, self.company.currency, - round=False)) - self.cost_sale = round_price(cost_sale) - self.cost_sale_currency = sale_currency_id + costs = { + 'cost': None, + 'cost_sale': None, + 'cost_sale_currency': None, + } + if self.carrier: + with Transaction().set_context(self._get_carrier_context()): + cost, currency_id = self.carrier.get_purchase_price() + cost_sale, sale_currency_id = self.carrier.get_sale_price() + if cost is not None: + cost = Currency.compute( + Currency(currency_id), cost, self.company.currency, + round=False) + costs['cost'] = round_price(cost) + if cost_sale is not None: + costs['cost_sale'] = round_price(cost_sale) + costs['cost_sale_currency'] = sale_currency_id + return costs + + @fields.depends('state', 'cost', 'cost_edit', methods=['_compute_costs']) + def on_change_with_cost_used(self, name=None): + if not self.cost_edit and self.state not in {'cancelled', 'done'}: + return self._compute_costs()['cost'] + else: + return self.cost + + @fields.depends( + 'state', 'cost_sale', 'cost_edit', methods=['_compute_costs']) + def on_change_with_cost_sale_used(self, name=None): + if not self.cost_edit and self.state not in {'cancelled', 'done'}: + return self._compute_costs()['cost_sale'] + else: + return self.cost_sale + + @fields.depends( + 'state', 'cost_sale_currency', 'cost_edit', methods=['_compute_costs']) + def on_change_with_cost_sale_currency_used(self, name=None): + if not self.cost_edit and self.state not in {'cancelled', 'done'}: + return self._compute_costs()['cost_sale_currency'] + elif self.cost_sale_currency: + return self.cost_sale_currency.id + + @fields.depends( + 'cost_edit', 'cost_used', 'cost_sale_used', 'cost_sale_currency_used') + def on_change_cost_edit(self): + if self.cost_edit: + self.cost = self.cost_used + self.cost_sale = self.cost_sale_used + self.cost_sale_currency = self.cost_sale_currency_used def _get_cost_tax_rule_pattern(self): 'Get tax rule pattern for invoice line' @@ -95,7 +158,7 @@ class ShipmentOut(metaclass=PoolMeta): Currency = pool.get('currency.currency') InvoiceLine = pool.get('account.invoice.line') - if not self.cost_sale: + if not self.cost_sale_used: return invoice_line = InvoiceLine() product = self.carrier.carrier_product @@ -111,11 +174,11 @@ class ShipmentOut(metaclass=PoolMeta): invoice_line.quantity = 1 # XXX invoice_line.unit = product.sale_uom.id - cost = self.cost_sale - if invoice.currency != self.cost_sale_currency: + cost = self.cost_sale_used + if invoice.currency != self.cost_sale_currency_used: with Transaction().set_context(date=invoice.currency_date): cost = Currency.compute( - self.cost_sale_currency, cost, + self.cost_sale_currency_used, cost, invoice.currency, round=False) invoice_line.unit_price = round_price(cost) invoice_line.currency = invoice.currency @@ -148,5 +211,27 @@ class ShipmentOut(metaclass=PoolMeta): def _get_shipment_cost(self): cost = super()._get_shipment_cost() if all(not m.sale.shipment_cost_method for m in self.outgoing_moves): - cost += self.cost + cost += self.cost_used return cost + + @classmethod + @ModelView.button + @Workflow.transition('done') + def done(cls, shipments): + for shipment in shipments: + shipment.cost = shipment.cost_used + shipment.cost_sale = shipment.cost_sale_used + shipment.cost_sale_currency = shipment.cost_sale_currency_used + cls.save(shipments) + super().done(shipments) + + @classmethod + @ModelView.button + @Workflow.transition('cancelled') + def cancel(cls, shipments): + for shipment in shipments: + shipment.cost = None + shipment.cost_sale = None + shipment.cost_sale_currency = None + cls.save(shipments) + super().cancel(shipments) diff --git a/tests/scenario_sale_shipment_cost.rst b/tests/scenario_sale_shipment_cost.rst index 8b23dda083..bc0d1dd655 100644 --- a/tests/scenario_sale_shipment_cost.rst +++ b/tests/scenario_sale_shipment_cost.rst @@ -141,17 +141,17 @@ Send products:: >>> shipment, = sale.shipments >>> shipment.carrier == carrier True - >>> shipment.cost + >>> shipment.cost_used Decimal('2.0000') - >>> shipment.cost_sale + >>> shipment.cost_sale_used Decimal('3.0000') - >>> shipment.cost_sale_currency == company.currency + >>> shipment.cost_sale_currency_used == company.currency True >>> move, = shipment.inventory_moves >>> move.quantity = 4 - >>> shipment.cost_sale + >>> shipment.cost_sale_used Decimal('3.0000') - >>> shipment.cost_sale_currency == company.currency + >>> shipment.cost_sale_currency_used == company.currency True >>> shipment.state 'waiting' @@ -299,9 +299,9 @@ Check no customer invoice:: Send products:: >>> shipment, = sale.shipments - >>> shipment.cost + >>> shipment.cost_used Decimal('2.0000') - >>> shipment.cost_sale + >>> shipment.cost_sale_used Decimal('3.0000') >>> shipment.click('assign_force') >>> shipment.click('pick') diff --git a/view/shipment_out_form.xml b/view/shipment_out_form.xml index 0d311c76e9..2c47f20b21 100644 --- a/view/shipment_out_form.xml +++ b/view/shipment_out_form.xml @@ -5,12 +5,18 @@ this repository contains the full copyright notices and license terms. -->