changeset ea4abbc22660 in modules/sale_shipment_cost:default
details: 
https://hg.tryton.org/modules/sale_shipment_cost?cmd=changeset;node=ea4abbc22660
description:
        Simplify manual alteration of shipment cost

        issue10142
        review340111002
diffstat:

 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(-)

diffs (322 lines):

diff -r 54aa4fef671c -r ea4abbc22660 CHANGELOG
--- a/CHANGELOG Wed Mar 03 09:44:37 2021 +0100
+++ b/CHANGELOG Sat Mar 13 23:43:51 2021 +0100
@@ -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 -r 54aa4fef671c -r ea4abbc22660 sale.py
--- a/sale.py   Wed Mar 03 09:44:37 2021 +0100
+++ b/sale.py   Sat Mar 13 23:43:51 2021 +0100
@@ -268,23 +268,11 @@
     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 -r 54aa4fef671c -r ea4abbc22660 stock.py
--- a/stock.py  Wed Mar 03 09:44:37 2021 +0100
+++ b/stock.py  Sat Mar 13 23:43:51 2021 +0100
@@ -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 @@
                     '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 @@
     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 @@
         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 @@
 
         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 @@
     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 -r 54aa4fef671c -r ea4abbc22660 tests/scenario_sale_shipment_cost.rst
--- a/tests/scenario_sale_shipment_cost.rst     Wed Mar 03 09:44:37 2021 +0100
+++ b/tests/scenario_sale_shipment_cost.rst     Sat Mar 13 23:43:51 2021 +0100
@@ -141,17 +141,17 @@
     >>> 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 @@
 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 -r 54aa4fef671c -r ea4abbc22660 view/shipment_out_form.xml
--- a/view/shipment_out_form.xml        Wed Mar 03 09:44:37 2021 +0100
+++ b/view/shipment_out_form.xml        Sat Mar 13 23:43:51 2021 +0100
@@ -5,12 +5,18 @@
     <xpath expr="/form/notebook" position="after">
         <label name="carrier"/>
         <field name="carrier"/>
-        <label name="cost"/>
-        <field name="cost"/>
-
-        <label name="cost_sale"/>
-        <field name="cost_sale"/>
-        <label name="cost_sale_currency"/>
-        <field name="cost_sale_currency"/>
+        <group id="costs" col="-1" colspan="2">
+            <label name="cost"/>
+            <label name="cost_used"/>
+            <field name="cost"/>
+            <field name="cost_used"/>
+            <label name="cost_sale"/>
+            <label name="cost_sale_used"/>
+            <field name="cost_sale"/>
+            <field name="cost_sale_used"/>
+            <field name="cost_sale_currency"/>
+            <field name="cost_sale_currency_used"/>
+            <field name="cost_edit"/>
+        </group>
     </xpath>
 </data>

Reply via email to