1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
# 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.model import ModelSQL, ModelView, fields
from trytond.modules.currency.fields import Monetary
from trytond.pool import PoolMeta
from trytond.pyson import Bool, Eval, Id
from trytond.transaction import Transaction
class Carrier(metaclass=PoolMeta):
__name__ = 'carrier'
weight_uom = fields.Many2One(
'product.uom', "Weight UoM",
domain=[('category', '=', Id('product', 'uom_cat_weight'))],
states={
'invisible': Eval('carrier_cost_method') != 'weight',
'required': Eval('carrier_cost_method') == 'weight',
'readonly': Bool(Eval('weight_price_list', [])),
},
help="The Unit of Measure of weight criteria for the price list.")
weight_currency = fields.Many2One('currency.currency', 'Currency',
states={
'invisible': Eval('carrier_cost_method') != 'weight',
'required': Eval('carrier_cost_method') == 'weight',
'readonly': Bool(Eval('weight_price_list', [])),
},
help="The currency of the price.")
weight_price_list = fields.One2Many('carrier.weight_price_list', 'carrier',
'Price List',
states={
'invisible': Eval('carrier_cost_method') != 'weight',
'readonly': ~(Eval('weight_uom', 0) & Eval('weight_currency', 0)),
},
help="Add price per weight to the carrier service.\n"
"The first line for which the weight is greater is used.\n"
"The line with weight of 0 is used as default price.")
@classmethod
def __setup__(cls):
super(Carrier, cls).__setup__()
selection = ('weight', 'Weight')
if selection not in cls.carrier_cost_method.selection:
cls.carrier_cost_method.selection.append(selection)
def compute_weight_price(self, weight):
"Compute price based on weight"
for line in reversed(self.weight_price_list):
if line.weight < weight:
return line.price
else:
if not line.weight and not weight:
return line.price
return Decimal(0)
def _get_weight_price(self):
weights = Transaction().context.get('weights', [])
if weights:
weight_price = sum(
self.compute_weight_price(w) for w in weights)
else:
weight_price = self.compute_weight_price(0)
return weight_price, self.weight_currency.id
def get_sale_price(self):
price, currency_id = super(Carrier, self).get_sale_price()
if self.carrier_cost_method == 'weight':
price, currency_id = self._get_weight_price()
return price, currency_id
def get_purchase_price(self):
price, currency_id = super(Carrier, self).get_purchase_price()
if self.carrier_cost_method == 'weight':
price, currency_id = self._get_weight_price()
return price, currency_id
class WeightPriceList(ModelSQL, ModelView):
'Carrier Weight Price List'
__name__ = 'carrier.weight_price_list'
carrier = fields.Many2One(
'carrier', "Carrier", required=True,
help="The carrier that the price list belongs to.")
weight = fields.Float(
"Weight", digits='weight_uom',
domain=[
('weight', '>=', 0),
],
depends={'carrier'},
help="The lower limit for the price.")
price = Monetary(
"Price", currency='currency', digits='currency',
help="The price of the carrier service.")
currency = fields.Function(fields.Many2One(
'currency.currency', "Currency"),
'on_change_with_currency')
weight_uom = fields.Function(fields.Many2One(
'product.uom', "Weight UoM",
help="The Unit of Measure of the weight."),
'on_change_with_weight_uom')
@classmethod
def __setup__(cls):
super(WeightPriceList, cls).__setup__()
cls._order.insert(0, ('weight', 'ASC'))
@fields.depends('carrier', '_parent_carrier.weight_currency')
def on_change_with_currency(self, name=None):
return self.carrier.weight_currency if self.carrier else None
@fields.depends('carrier', '_parent_carrier.weight_uom')
def on_change_with_weight_uom(self, name=None):
return self.carrier.weight_uom if self.carrier else None
|