Simplify manual alteration of shipment cost
issue10142 review340111002
This commit is contained in:
1 parent
b5461c07f7
commit
c1c8b4a8d3
5 files changed
+144
-64
No files matched your search
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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')
|
||||
|
||||
@@ -5,12 +5,18 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<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>
|
||||
Reference in new issue
Block a user