-
-
Notifications
You must be signed in to change notification settings - Fork 103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[14.0]intrastat Brexit support #163
Changes from 9 commits
47cbc65
fa5667b
5127bbd
2b096b2
a8cdd74
2874b76
085e24f
698dbfc
516b49d
964037e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# Copyright 2022 Noviat. | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
from odoo import _, api, models | ||
from odoo.exceptions import UserError | ||
|
||
XI_COUNTY_NAMES = [ | ||
"antrim", | ||
"armagh", | ||
"down", | ||
"fermanagh", | ||
"londonderry", | ||
"tyrone", | ||
"northern ireland", | ||
] | ||
|
||
XI_COUNTIES = [ | ||
"base.state_uk18", # County Antrim | ||
"base.state_uk19", # County Armagh | ||
"base.state_uk20", # County Down | ||
"base.state_uk22", # County Fermanagh | ||
"base.state_uk23", # County Londonderry | ||
"base.state_uk24", # County Tyrone | ||
"base.state_ie_27", # Antrim | ||
"base.state_ie_28", # Armagh | ||
"base.state_ie_29", # Down | ||
"base.state_ie_30", # Fermanagh | ||
"base.state_ie_31", # Londonderry | ||
"base.state_ie_32", # Tyrone | ||
] | ||
|
||
|
||
class ResPartner(models.Model): | ||
_inherit = "res.partner" | ||
|
||
@api.model | ||
def _get_xi_counties(self): | ||
return [self.env.ref(x) for x in XI_COUNTIES] | ||
|
||
@api.model | ||
def _get_xu_counties(self): | ||
uk_counties = self.env.ref("base.uk").state_ids | ||
xu_counties = uk_counties.filtered(lambda r: r not in self._get_xi_counties()) | ||
return xu_counties | ||
|
||
def _get_intrastat_country_code(self, country=None, state=None): | ||
if self: | ||
self.ensure_one() | ||
country = self.country_id | ||
state = self.state_id | ||
else: | ||
state = state or self.env["res.country.state"] | ||
country = country or state.country_id | ||
if not country: | ||
raise UserError( | ||
_("Programming Error when calling '_get_intrastat_country_code()") | ||
) | ||
cc = country.code | ||
if cc == "GB": | ||
cc = "XU" | ||
if state and cc in ["XU", "IE"]: | ||
if ( | ||
state in self._get_xi_counties() | ||
or state.name.lower().strip() in XI_COUNTY_NAMES | ||
): | ||
cc = "XI" | ||
return cc |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
# Copyright 2011-2020 Akretion France (http://www.akretion.com) | ||
# Copyright 2009-2020 Noviat (http://www.noviat.com) | ||
# Copyright 2009-2022 Noviat (http://www.noviat.com) | ||
# @author Alexis de Lattre <alexis.delattre@akretion.com> | ||
# @author Luc de Meyer <info@noviat.com> | ||
|
||
from odoo import api, fields, models | ||
from odoo import _, api, fields, models | ||
from odoo.exceptions import UserError | ||
|
||
|
||
class AccountMove(models.Model): | ||
|
@@ -93,13 +94,22 @@ def _get_intrastat_line_vals(self, line): | |
if not hs_code: | ||
return vals | ||
weight, qty = decl_model._get_weight_and_supplunits(line, hs_code, notedict) | ||
product_country = line.product_id.origin_country_id | ||
product_state = line.product_id.origin_state_id | ||
country = product_country or product_state.country_id | ||
product_origin_country_code = "QU" | ||
if country: | ||
product_origin_country_code = self.env[ | ||
"res.partner" | ||
]._get_intrastat_country_code(product_country, product_state) | ||
vals.update( | ||
{ | ||
"invoice_line_id": line.id, | ||
"hs_code_id": hs_code.id, | ||
"transaction_weight": int(weight), | ||
"transaction_suppl_unit_qty": qty, | ||
"product_origin_country_id": line.product_id.origin_country_id.id, | ||
"product_origin_country_code": product_origin_country_code, | ||
} | ||
) | ||
return vals | ||
|
@@ -160,11 +170,22 @@ class AccountMoveIntrastatLine(models.Model): | |
transaction_weight = fields.Integer( | ||
help="Transaction weight in Kg: Quantity x Product Weight" | ||
) | ||
# product_origin_country_id is replaced by product_origin_country_code | ||
# this field should be dropped once the localisation modules have been | ||
# adapted accordingly | ||
product_origin_country_id = fields.Many2one( | ||
comodel_name="res.country", | ||
string="Country of Origin", | ||
help="Country of origin of the product i.e. product " "'made in ____'.", | ||
) | ||
product_origin_country_code = fields.Char( | ||
string="Country of Origin of the Product", | ||
required=True, | ||
default="QU", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I find it a bit "too easy" to use QU by default. I think we should display a warning in the warning dialog box about the fact that the country of origin is missing on product X and say that we've set the country code to QU as a temporary solution. |
||
help="2 digit code of country of origin of the product except for the UK.\n" | ||
"Specify 'XI' for UK Northern Ireland and 'XU' for rest of the UK.\n" | ||
"Specify 'QU' when the country is unknown.\n", | ||
) | ||
|
||
@api.onchange("invoice_line_id") | ||
def _onchange_move_id(self): | ||
|
@@ -176,3 +197,25 @@ def _onchange_move_id(self): | |
("id", "not in", moves.mapped("intrastat_line_ids.invoice_line_id").ids), | ||
] | ||
return {"domain": {"invoice_line_id": dom}} | ||
|
||
@api.model | ||
def create(self, vals): | ||
self._format_vals(vals) | ||
return super().create(vals) | ||
|
||
def write(self, vals): | ||
self._format_vals(vals) | ||
return super().write(vals) | ||
|
||
def _format_vals(self, vals): | ||
if "product_origin_country_code" in vals: | ||
vals["product_origin_country_code"] = ( | ||
vals["product_origin_country_code"].upper().strip() | ||
) | ||
if len(vals["product_origin_country_code"]) != 2: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of having a check here on the length, I think it would be more easier and user-friendly to have a max-length directly on the field to be warned beforehand. |
||
raise UserError( | ||
_( | ||
"Intrastat transaction details error:\n" | ||
"Product Origin Country Code must be 2 characters." | ||
) | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is really strange with it's "if self / else" ! When self has a value, then the arguments country and state are ignored, which is surprising. For me, instead of this wired code, we should have 2 separate methods, the first one calling the second one.