223 lines
7.5 KiB
Python
223 lines
7.5 KiB
Python
# 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.model import ModelSQL, ModelView, fields, sequence_ordered
|
|
from trytond.pool import Pool, PoolMeta
|
|
from trytond.pyson import Bool, Eval, Or
|
|
from trytond.tools import grouped_slice
|
|
|
|
|
|
class Category(metaclass=PoolMeta):
|
|
__name__ = 'product.category'
|
|
customs = fields.Boolean(
|
|
"Customs",
|
|
states={
|
|
'readonly': Bool(Eval('childs', [0])) | Bool(Eval('parent')),
|
|
})
|
|
tariff_codes_parent = fields.Boolean("Use Parent's Tariff Codes",
|
|
states={
|
|
'invisible': ~Eval('customs', False),
|
|
},
|
|
help='Use the tariff codes defined on the parent category.')
|
|
tariff_codes = fields.One2Many('product-customs.tariff.code',
|
|
'product', "Tariff Codes",
|
|
order=[
|
|
('sequence', 'ASC NULLS FIRST'),
|
|
('id', 'ASC'),
|
|
],
|
|
states={
|
|
'invisible': (Eval('tariff_codes_parent', False)
|
|
| ~Eval('customs', False)),
|
|
})
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super().__setup__()
|
|
cls.parent.domain = [
|
|
('customs', '=', Eval('customs', False)),
|
|
cls.parent.domain or []]
|
|
cls.parent.states['required'] = Or(
|
|
cls.parent.states.get('required', False),
|
|
Eval('tariff_codes_parent', False))
|
|
|
|
@classmethod
|
|
def default_customs(cls):
|
|
return False
|
|
|
|
@classmethod
|
|
def default_tariff_codes_parent(cls):
|
|
return False
|
|
|
|
@fields.depends('parent', '_parent_parent.customs', 'customs')
|
|
def on_change_with_customs(self):
|
|
if self.parent:
|
|
return self.parent.customs
|
|
return self.customs
|
|
|
|
def get_tariff_codes(self, pattern):
|
|
if not self.tariff_codes_parent:
|
|
for link in self.tariff_codes:
|
|
if link.tariff_code.match(pattern):
|
|
yield link.tariff_code
|
|
else:
|
|
yield from self.parent.get_tariff_codes(pattern)
|
|
|
|
def get_tariff_code(self, pattern):
|
|
try:
|
|
return next(self.get_tariff_codes(pattern))
|
|
except StopIteration:
|
|
pass
|
|
|
|
@classmethod
|
|
def view_attributes(cls):
|
|
return super().view_attributes() + [
|
|
('/form/notebook/page[@id="customs"]', 'states', {
|
|
'invisible': ~Eval('customs', False),
|
|
}),
|
|
]
|
|
|
|
@classmethod
|
|
def on_delete(cls, categories):
|
|
pool = Pool()
|
|
Product_TariffCode = pool.get('product-customs.tariff.code')
|
|
|
|
callback = super().on_delete(categories)
|
|
|
|
product_tariffcodes = set()
|
|
products = [str(t) for t in categories]
|
|
for products in grouped_slice(products):
|
|
product_tariffcodes.update(Product_TariffCode.search([
|
|
'product', 'in', list(products),
|
|
]))
|
|
if product_tariffcodes:
|
|
product_tariffcodes = Product_TariffCode.browse(
|
|
product_tariffcodes)
|
|
callback.append(
|
|
lambda: Product_TariffCode.delete(product_tariffcodes))
|
|
return callback
|
|
|
|
|
|
class Template(metaclass=PoolMeta):
|
|
__name__ = 'product.template'
|
|
customs_category = fields.Many2One('product.category', 'Customs Category',
|
|
domain=[
|
|
('customs', '=', True),
|
|
],
|
|
states={
|
|
'required': Eval('tariff_codes_category', False),
|
|
})
|
|
tariff_codes_category = fields.Boolean("Use Category's Tariff Codes",
|
|
help='Use the tariff codes defined on the category.')
|
|
tariff_codes = fields.One2Many('product-customs.tariff.code',
|
|
'product', "Tariff Codes",
|
|
order=[
|
|
('sequence', 'ASC NULLS FIRST'),
|
|
('id', 'ASC'),
|
|
],
|
|
states={
|
|
'invisible': ((Eval('type') == 'service')
|
|
| Eval('tariff_codes_category', False)),
|
|
})
|
|
country_of_origin = fields.Many2One(
|
|
'country.country', "Country",
|
|
states={
|
|
'invisible': Eval('type') == 'service',
|
|
},
|
|
help="The country of origin of the product.")
|
|
|
|
@classmethod
|
|
def default_tariff_codes_category(cls):
|
|
return False
|
|
|
|
def get_tariff_codes(self, pattern):
|
|
if not self.tariff_codes_category:
|
|
for link in self.tariff_codes:
|
|
if link.tariff_code.match(pattern):
|
|
yield link.tariff_code
|
|
else:
|
|
yield from self.customs_category.get_tariff_codes(pattern)
|
|
|
|
def get_tariff_code(self, pattern):
|
|
try:
|
|
return next(self.get_tariff_codes(pattern))
|
|
except StopIteration:
|
|
pass
|
|
|
|
@classmethod
|
|
def view_attributes(cls):
|
|
return super().view_attributes() + [
|
|
('//page[@id="customs"]', 'states', {
|
|
'invisible': Eval('type') == 'service',
|
|
}),
|
|
]
|
|
|
|
@classmethod
|
|
def on_delete(cls, templates):
|
|
pool = Pool()
|
|
Product_TariffCode = pool.get('product-customs.tariff.code')
|
|
|
|
callback = super().on_delete(templates)
|
|
|
|
product_tariffcodes = set()
|
|
products = [str(t) for t in templates]
|
|
for products in grouped_slice(products):
|
|
product_tariffcodes.update(Product_TariffCode.search([
|
|
'product', 'in', list(products),
|
|
]))
|
|
if product_tariffcodes:
|
|
product_tariffcodes = Product_TariffCode.browse(
|
|
product_tariffcodes)
|
|
callback.append(
|
|
lambda: Product_TariffCode.delete(product_tariffcodes))
|
|
return callback
|
|
|
|
|
|
class Product_TariffCode(sequence_ordered(), ModelSQL, ModelView):
|
|
__name__ = 'product-customs.tariff.code'
|
|
product = fields.Reference('Product', selection=[
|
|
('product.template', 'Template'),
|
|
('product.category', 'Category'),
|
|
], required=True)
|
|
tariff_code = fields.Many2One('customs.tariff.code', 'Tariff Code',
|
|
required=True, ondelete='CASCADE')
|
|
country = fields.Function(
|
|
fields.Many2One('country.country', "Country"), 'get_tariff_code_field')
|
|
organization = fields.Function(
|
|
fields.Many2One('country.organization', "Organization"),
|
|
'get_tariff_code_field')
|
|
start_day = fields.Function(
|
|
fields.Integer("Start Day"), 'get_tariff_code_field')
|
|
start_month = fields.Function(
|
|
fields.Many2One('ir.calendar.month', "Start Month"),
|
|
'get_tariff_code_field')
|
|
end_day = fields.Function(
|
|
fields.Integer("End Day"), 'get_tariff_code_field')
|
|
end_month = fields.Function(
|
|
fields.Many2One('ir.calendar.month', "End Month"),
|
|
'get_tariff_code_field')
|
|
|
|
def get_tariff_code_field(self, name):
|
|
field = getattr(self.__class__, name)
|
|
value = getattr(self.tariff_code, name, None)
|
|
if isinstance(value, ModelSQL):
|
|
if field._type == 'reference':
|
|
return str(value)
|
|
return value.id
|
|
return value
|
|
|
|
def get_rec_name(self, name):
|
|
return self.tariff_code.rec_name
|
|
|
|
@classmethod
|
|
def search_rec_name(cls, name, clause):
|
|
return [('tariff_code.rec_name',) + tuple(clause[1:])]
|
|
|
|
|
|
class Product(metaclass=PoolMeta):
|
|
__name__ = 'product.product'
|
|
|
|
def get_tariff_codes(self, pattern):
|
|
yield from self.template.get_tariff_codes(pattern)
|
|
|
|
def get_tariff_code(self, pattern):
|
|
return self.template.get_tariff_code(pattern)
|