diff --git a/modules/customs/CHANGELOG b/modules/customs/CHANGELOG
index f346c19c9d..93744c1c69 100644
--- a/modules/customs/CHANGELOG
+++ b/modules/customs/CHANGELOG
@@ -1,3 +1,4 @@
+* Support country organization for tariff code and duty rate
* Use ir.calendar.month for tariff code months
Version 6.6.0 - 2022-10-31
diff --git a/modules/customs/customs.py b/modules/customs/customs.py
index a52bc3eb8a..20f58f1979 100644
--- a/modules/customs/customs.py
+++ b/modules/customs/customs.py
@@ -14,7 +14,33 @@ from trytond.pyson import Bool, Eval, If
from trytond.transaction import Transaction
-class TariffCode(DeactivableMixin, ModelSQL, ModelView, MatchMixin):
+class CountryMatchMixin(MatchMixin):
+ country = fields.Many2One(
+ 'country.country', "Country",
+ states={
+ 'invisible': Bool(Eval('organization')),
+ })
+ organization = fields.Many2One(
+ 'country.organization', "Organization",
+ states={
+ 'invisible': Bool(Eval('country')),
+ })
+
+ def match(self, pattern, match_none=False):
+ if 'country' in pattern:
+ pattern = pattern.copy()
+ country = pattern.pop('country')
+ if country is not None or match_none:
+ if self.country and self.country.id != country:
+ return False
+ if (self.organization
+ and country not in [
+ c.id for c in self.organization.countries]):
+ return False
+ return super().match(pattern, match_none=match_none)
+
+
+class TariffCode(DeactivableMixin, CountryMatchMixin, ModelSQL, ModelView):
'Tariff Code'
__name__ = 'customs.tariff.code'
_rec_name = 'code'
@@ -96,7 +122,7 @@ class TariffCode(DeactivableMixin, ModelSQL, ModelView, MatchMixin):
table_h.drop_column('_temp_start_month')
table_h.drop_column('_temp_end_month')
- def match(self, pattern):
+ def match(self, pattern, match_none=False):
if 'date' in pattern:
pattern = pattern.copy()
date = pattern.pop('date')
@@ -110,7 +136,7 @@ class TariffCode(DeactivableMixin, ModelSQL, ModelView, MatchMixin):
else:
if end <= date <= start:
return False
- return super(TariffCode, self).match(pattern)
+ return super().match(pattern, match_none=match_none)
def get_duty_rate(self, pattern):
for rate in self.duty_rates:
@@ -118,13 +144,11 @@ class TariffCode(DeactivableMixin, ModelSQL, ModelView, MatchMixin):
return rate
-class DutyRate(ModelSQL, ModelView, MatchMixin):
+class DutyRate(CountryMatchMixin, ModelSQL, ModelView):
'Duty Rate'
__name__ = 'customs.duty.rate'
tariff_code = fields.Many2One(
'customs.tariff.code', "Tariff Code", required=True)
- country = fields.Many2One('country.country', 'Country')
- # TODO country group
type = fields.Selection([
('import', 'Import'),
('export', 'Export'),
diff --git a/modules/customs/doc/index.rst b/modules/customs/doc/index.rst
index 34f09c063a..45355e2a48 100644
--- a/modules/customs/doc/index.rst
+++ b/modules/customs/doc/index.rst
@@ -11,6 +11,7 @@ It stores the `Harmonized System`_ that can be set on *Product*.
- The *Code* from the HS.
- The *Country* in case of a country specific code.
+- The *Organization* in case of a country organization code.
- The *Start* / *End* period of the year for which the code is valid.
.. _`Harmonized System`: http://en.wikipedia.org/wiki/Harmonized_System
@@ -22,6 +23,7 @@ It stores the rate of a *Tarif Code* for a country over a period.
- The *Tariff Code*.
- The *Country* for which the rate is.
+- The *Organization* for which the rate is.
- The *Type*: *Import* or *Export*
- The *Start* and *End* date of validity.
- The *Computation Type*:
diff --git a/modules/customs/tests/test_module.py b/modules/customs/tests/test_module.py
index 261b3fabb6..13bcc75779 100644
--- a/modules/customs/tests/test_module.py
+++ b/modules/customs/tests/test_module.py
@@ -13,8 +13,8 @@ class CustomsTestCase(ModuleTestCase):
module = 'customs'
@with_transaction()
- def test_tariff_code_match(self):
- 'Test tariff code match'
+ def test_tariff_code_match_date(self):
+ "Test tariff code match date"
pool = Pool()
Tariff = pool.get('customs.tariff.code')
Template = pool.get('product.template')
@@ -55,6 +55,58 @@ class CustomsTestCase(ModuleTestCase):
]:
self.assertEqual(template.get_tariff_code(pattern), result)
+ @with_transaction()
+ def test_tariff_code_match_country(self):
+ "Test tariff code match country"
+ pool = Pool()
+ Tariff = pool.get('customs.tariff.code')
+ Country = pool.get('country.country')
+
+ country1 = Country(name="Country 1")
+ country1.save()
+ country2 = Country(name="Country 2")
+ country2.save()
+ tariff1 = Tariff(code='170390')
+ tariff1.save()
+ tariff2 = Tariff(code='17039099', country=country1)
+ tariff2.save()
+
+ self.assertTrue(tariff1.match({}))
+ self.assertTrue(tariff1.match({'country': None}))
+ self.assertTrue(tariff1.match({'country': country1.id}))
+ self.assertTrue(tariff2.match({}))
+ self.assertTrue(tariff2.match({'country': None}))
+ self.assertTrue(tariff2.match({'country': country1.id}))
+ self.assertFalse(tariff2.match({'country': country2.id}))
+
+ @with_transaction()
+ def test_tariff_code_match_country_organization(self):
+ "Test Tariff code match country with organization"
+ pool = Pool()
+ Tariff = pool.get('customs.tariff.code')
+ Country = pool.get('country.country')
+ Organization = pool.get('country.organization')
+
+ country1 = Country(name="Country 1")
+ country1.save()
+ country2 = Country(name="Country 2")
+ country2.save()
+ organization = Organization(
+ name="Organization", members=[{'country': country1.id}])
+ organization.save()
+ tariff1 = Tariff(code='170390')
+ tariff1.save()
+ tariff2 = Tariff(code='17039099', organization=organization)
+ tariff2.save()
+
+ self.assertTrue(tariff1.match({}))
+ self.assertTrue(tariff1.match({'country': None}))
+ self.assertTrue(tariff1.match({'country': country1.id}))
+ self.assertTrue(tariff2.match({}))
+ self.assertTrue(tariff2.match({'country': None}))
+ self.assertTrue(tariff2.match({'country': country1.id}))
+ self.assertFalse(tariff2.match({'country': country2.id}))
+
@with_transaction()
def test_get_tariff_code(self):
'Test get_tariff_code'
diff --git a/modules/customs/view/duty_rate_form.xml b/modules/customs/view/duty_rate_form.xml
index dd9942f1c3..382fb41902 100644
--- a/modules/customs/view/duty_rate_form.xml
+++ b/modules/customs/view/duty_rate_form.xml
@@ -6,10 +6,12 @@ this repository contains the full copyright notices and license terms. -->
+
-
-
+
+
+
diff --git a/modules/customs/view/duty_rate_list.xml b/modules/customs/view/duty_rate_list.xml
index 0b0635a973..30e9276c75 100644
--- a/modules/customs/view/duty_rate_list.xml
+++ b/modules/customs/view/duty_rate_list.xml
@@ -4,7 +4,7 @@ this repository contains the full copyright notices and license terms. -->
-
+
diff --git a/modules/customs/view/tariff_code_form.xml b/modules/customs/view/tariff_code_form.xml
index ff1e302619..bcff94f0f0 100644
--- a/modules/customs/view/tariff_code_form.xml
+++ b/modules/customs/view/tariff_code_form.xml
@@ -8,10 +8,12 @@ this repository contains the full copyright notices and license terms. -->
+
-
-
+
+
+
diff --git a/modules/customs/view/tariff_code_list.xml b/modules/customs/view/tariff_code_list.xml
index 6e4b325f2f..ce9e26236a 100644
--- a/modules/customs/view/tariff_code_list.xml
+++ b/modules/customs/view/tariff_code_list.xml
@@ -4,5 +4,5 @@ this repository contains the full copyright notices and license terms. -->
-
+