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. -->