trytond-stock_valued-old/shipment.py

205 lines
6.9 KiB
Python
Executable File

# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
from decimal import Decimal
from trytond.model import fields
from trytond.pool import PoolMeta
from trytond.pyson import Eval
from trytond.modules.account.tax import TaxableMixin
__all__ = ['ShipmentIn', 'ShipmentOut']
MOVES = {
'stock.shipment.in': 'incoming_moves',
'stock.shipment.in.return': 'moves',
'stock.shipment.out': 'outgoing_moves',
'stock.shipment.out.return': 'incoming_moves',
}
class ShipmentValuedMixin(TaxableMixin):
currency = fields.Function(fields.Many2One('currency.currency',
'Currency'),
'on_change_with_currency')
currency_digits = fields.Function(fields.Integer('Currency Digits'),
'on_change_with_currency_digits')
untaxed_amount = fields.Numeric('Untaxed',
digits=(16, Eval('currency_digits', 2)),
readonly=True,
depends=['currency_digits'])
tax_amount = fields.Numeric('Tax',
digits=(16, Eval('currency_digits', 2)),
readonly=True,
depends=['currency_digits'])
total_amount = fields.Numeric('Total',
digits=(16, Eval('currency_digits', 2)),
readonly=True,
depends=['currency_digits'])
untaxed_amount_func = fields.Function(fields.Numeric('Untaxed',
digits=(16, Eval('currency_digits', 2)),
depends=['currency_digits']), 'get_amounts')
tax_amount_func = fields.Function(fields.Numeric('Tax',
digits=(16, Eval('currency_digits', 2)),
readonly=True,
depends=['currency_digits']), 'get_amounts')
total_amount_func = fields.Function(fields.Numeric('Total',
digits=(16, Eval('currency_digits', 2)),
readonly=True,
depends=['currency_digits']), 'get_amounts')
@fields.depends('company')
def on_change_with_currency(self, name=None):
if self.company:
return self.company.currency.id
return None
@fields.depends('company')
def on_change_with_currency_digits(self, name=None):
if self.company:
return self.company.currency.digits
return 2
@property
def valued_moves(self):
return getattr(self, MOVES.get(self.__name__), [])
@property
def taxable_lines(self):
taxable_lines = []
# In case we're called from an on_change we have to use some sensible
# defaults
for move in self.valued_moves:
if move.state == 'cancelled':
continue
taxable_lines.append(tuple())
for attribute, default_value in [
('taxes', []),
('unit_price', Decimal(0)),
('quantity', 0.),
]:
value = getattr(move, attribute, None)
taxable_lines[-1] += (
value if value is not None else default_value,)
return taxable_lines
def calc_amounts(self):
untaxed_amount = sum((m.untaxed_amount for m in self.valued_moves),
Decimal(0))
taxes = self._get_taxes()
untaxed_amount = self.company.currency.round(untaxed_amount)
tax_amount = sum((self.company.currency.round(tax['amount'])
for tax in taxes.values()), Decimal(0))
return {
'untaxed_amount': untaxed_amount,
'tax_amount': tax_amount,
'total_amount': untaxed_amount + tax_amount,
}
@classmethod
def get_amounts(cls, shipments, names):
untaxed_amount = dict((i.id, Decimal(0)) for i in shipments)
tax_amount = dict((i.id, Decimal(0)) for i in shipments)
total_amount = dict((i.id, Decimal(0)) for i in shipments)
for shipment in shipments:
if shipment.untaxed_amount:
untaxed_amount[shipment.id] = shipment.untaxed_amount
tax_amount[shipment.id] = shipment.tax_amount
total_amount[shipment.id] = shipment.total_amount
else:
res = shipment.calc_amounts()
untaxed_amount[shipment.id] = res['untaxed_amount']
tax_amount[shipment.id] = res['tax_amount']
total_amount[shipment.id] = res['total_amount']
result = {
'untaxed_amount_func': untaxed_amount,
'tax_amount_func': tax_amount,
'total_amount_func': total_amount,
}
for key in result.keys():
if key not in names:
del result[key]
return result
class ShipmentIn(ShipmentValuedMixin):
__name__ = 'stock.shipment.in'
__metaclass__ = PoolMeta
@classmethod
def create(cls, shipments):
shipments = super(ShipmentIn, cls).create(shipments)
to_write = []
for shipment in shipments:
to_write.extend(([shipment], shipment.calc_amounts()))
cls.write(*to_write)
return shipments
@classmethod
def write(cls, *args):
actions = iter(args)
to_update = []
for shipments, values in zip(actions, actions):
if set(values) & set(['incoming_moves']):
to_update.extend(shipments)
super(ShipmentIn, cls).write(*args)
to_write = []
for shipment in to_update:
values = shipment.calc_amounts()
to_write.extend(([shipment], values))
if to_write:
cls.write(*to_write)
@classmethod
def receive(cls, shipments):
super(ShipmentIn, cls).receive(shipments)
to_write = []
for shipment in shipments:
to_write.extend(([shipment], shipment.calc_amounts()))
cls.write(*to_write)
@classmethod
def done(cls, shipments):
super(ShipmentIn, cls).done(shipments)
to_write = []
for shipment in shipments:
to_write.extend(([shipment], shipment.calc_amounts()))
cls.write(*to_write)
class ShipmentOut(ShipmentValuedMixin):
__name__ = 'stock.shipment.out'
__metaclass__ = PoolMeta
@classmethod
def wait(cls, shipments):
super(ShipmentOut, cls).wait(shipments)
to_write = []
for shipment in shipments:
to_write.extend(([shipment], shipment.calc_amounts()))
cls.write(*to_write)
@classmethod
def assign(cls, shipments):
super(ShipmentOut, cls).assign(shipments)
to_write = []
for shipment in shipments:
to_write.extend(([shipment], shipment.calc_amounts()))
cls.write(*to_write)
@classmethod
def pack(cls, shipments):
super(ShipmentOut, cls).pack(shipments)
to_write = []
for shipment in shipments:
to_write.extend(([shipment], shipment.calc_amounts()))
cls.write(*to_write)
@classmethod
def done(cls, shipments):
super(ShipmentOut, cls).done(shipments)
to_write = []
for shipment in shipments:
to_write.extend(([shipment], shipment.calc_amounts()))
cls.write(*to_write)