diff --git a/addons/base_vat/models/res_partner.py b/addons/base_vat/models/res_partner.py
index e06f1ac8f02..615694ae1fc 100644
--- a/addons/base_vat/models/res_partner.py
+++ b/addons/base_vat/models/res_partner.py
@@ -95,7 +95,7 @@ _ref_vat = {
'mx': 'ABC123456T1B',
'nl': 'NL123456782B90',
'no': 'NO123456785',
- 'pe': 'PER10254824220 or PED10254824220',
+ 'pe': '10XXXXXXXXY or 20XXXXXXXXY or 15XXXXXXXXY or 16XXXXXXXXY or 17XXXXXXXXY',
'pl': 'PL1234567883',
'pt': 'PT123456789',
'ro': 'RO1234567897',
@@ -325,38 +325,14 @@ class ResPartner(models.Model):
# Peruvian VAT validation, contributed by Vauxoo
def check_vat_pe(self, vat):
-
- vat_type, vat = vat and len(vat) >= 2 and (vat[0], vat[1:]) or (False, False)
-
- if vat_type and vat_type.upper() == 'D':
- # DNI
- return True
- elif vat_type and vat_type.upper() == 'R':
- # verify RUC
- factor = '5432765432'
- sum = 0
- dig_check = False
- if len(vat) != 11:
- return False
- try:
- int(vat)
- except ValueError:
- return False
-
- for f in range(0, 10):
- sum += int(factor[f]) * int(vat[f])
-
- subtraction = 11 - (sum % 11)
- if subtraction == 10:
- dig_check = 0
- elif subtraction == 11:
- dig_check = 1
- else:
- dig_check = subtraction
-
- return int(vat[10]) == dig_check
- else:
+ if len(vat) != 11 or not vat.isdigit():
return False
+ dig_check = 11 - (sum([int('5432765432'[f]) * int(vat[f]) for f in range(0, 10)]) % 11)
+ if dig_check == 10:
+ dig_check = 0
+ elif dig_check == 11:
+ dig_check = 1
+ return int(vat[10]) == dig_check
# VAT validation in Turkey, contributed by # Levent Karakas @ Eska Yazilim A.S.
def check_vat_tr(self, vat):
diff --git a/addons/base_vat/tests/__init__.py b/addons/base_vat/tests/__init__.py
new file mode 100644
index 00000000000..89c4b04134d
--- /dev/null
+++ b/addons/base_vat/tests/__init__.py
@@ -0,0 +1,2 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from . import test_validate_ruc
diff --git a/addons/base_vat/tests/test_validate_ruc.py b/addons/base_vat/tests/test_validate_ruc.py
new file mode 100644
index 00000000000..69dfbdcf59c
--- /dev/null
+++ b/addons/base_vat/tests/test_validate_ruc.py
@@ -0,0 +1,16 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from odoo.tests import common
+from odoo.exceptions import ValidationError
+
+
+class TestRUCStructure(common.TransactionCase):
+
+ def test_peru_ruc_format(self):
+ """Only values that has the length of 11 will be checked as RUC, that's what we are proving. The second part
+ will check for a valid ruc and there will be no problem at all.
+ """
+ partner = self.env['res.partner'].create({'name': "Dummy partner", 'country_id': self.env.ref('base.pe').id})
+
+ with self.assertRaises(ValidationError):
+ partner.vat = '11111111111'
+ partner.vat = '20507822470'
diff --git a/addons/l10n_pe/data/l10n_pe_chart_post_data.xml b/addons/l10n_pe/data/l10n_pe_chart_post_data.xml
index b28f5129674..5103fa97f27 100644
--- a/addons/l10n_pe/data/l10n_pe_chart_post_data.xml
+++ b/addons/l10n_pe/data/l10n_pe_chart_post_data.xml
@@ -6,7 +6,7 @@
-
+
diff --git a/addons/l10n_pe/data/res_country_data.xml b/addons/l10n_pe/data/res_country_data.xml
index 72aede8be3c..4b6a12df565 100644
--- a/addons/l10n_pe/data/res_country_data.xml
+++ b/addons/l10n_pe/data/res_country_data.xml
@@ -9,22 +9,22 @@
@@ -32,5 +32,7 @@
+
+
diff --git a/addons/l10n_pe/models/__init__.py b/addons/l10n_pe/models/__init__.py
index 7be3012e1aa..4ba6149ba4f 100644
--- a/addons/l10n_pe/models/__init__.py
+++ b/addons/l10n_pe/models/__init__.py
@@ -1,7 +1,10 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import account_tax
from . import account_move
+from . import account_journal
+from . import account_chart_template
from . import l10n_latam_identification_type
from . import res_partner
from . import res_city_district
from . import res_city
+from . import res_company
diff --git a/addons/l10n_pe/models/account_chart_template.py b/addons/l10n_pe/models/account_chart_template.py
new file mode 100644
index 00000000000..e9314da7709
--- /dev/null
+++ b/addons/l10n_pe/models/account_chart_template.py
@@ -0,0 +1,14 @@
+from odoo import models
+
+
+class AccountChartTemplate(models.Model):
+
+ _inherit = 'account.chart.template'
+
+ def _load(self, sale_tax_rate, purchase_tax_rate, company):
+ """Load the rounding method properly to the company once the CoA is installed.
+ """
+ company.filtered(lambda c: c.country_id.id == self.env.ref('base.pe').id).write({
+ 'tax_calculation_rounding_method': 'round_globally',
+ })
+ return super()._load(sale_tax_rate, purchase_tax_rate, company)
diff --git a/addons/l10n_pe/models/account_journal.py b/addons/l10n_pe/models/account_journal.py
new file mode 100644
index 00000000000..ff55a01cd45
--- /dev/null
+++ b/addons/l10n_pe/models/account_journal.py
@@ -0,0 +1,31 @@
+from odoo import models, api
+
+
+class AccountJournal(models.Model):
+ _inherit = "account.journal"
+
+ @api.model
+ def _get_sequence_prefix(self, code, refund=False):
+ """For peruvian companies we can not use sequences with **/** due to the edi generation which need in the
+ sequence a plain text ended by a *-* and the length of this prefix"""
+ if self.env.company.country_id != self.env.ref('base.pe'):
+ return super()._get_sequence_prefix(code, refund=refund)
+ prefix = code.upper()
+ if len(prefix) > 3:
+ prefix = prefix[:3]
+ prefix = prefix.ljust(3, 'X')
+ if refund:
+ prefix = 'R' + prefix[:-1]
+ return prefix + '-'
+
+ @api.model
+ def _create_sequence(self, vals, refund=False):
+ """For Peruvian companies, a number reset by date do not make sense due to the fact that we can not use a free
+ prefix the format does not have enough space to put a year on it or any other char, then with this approach we
+ are avoiding the default behavior there."""
+ res = super()._create_sequence(vals, refund=refund)
+ # NOTE: the self element is coming filled just when write and not on create (which is Ok)
+ journal_type = self.type if not vals.get('type') else vals.get('type')
+ if self.env.company.country_id == self.env.ref('base.pe') or journal_type in ['sale', 'purchase']:
+ res.write({'use_date_range': False})
+ return res
diff --git a/addons/l10n_pe/models/account_tax.py b/addons/l10n_pe/models/account_tax.py
index eb8674c629c..903093fc9fc 100644
--- a/addons/l10n_pe/models/account_tax.py
+++ b/addons/l10n_pe/models/account_tax.py
@@ -57,4 +57,4 @@ class AccountTaxTemplate(models.Model):
'l10n_pe_edi_tax_code': self.l10n_pe_edi_tax_code,
'l10n_pe_edi_unece_category': self.l10n_pe_edi_unece_category,
})
- return val
\ No newline at end of file
+ return val
diff --git a/addons/l10n_pe/models/res_company.py b/addons/l10n_pe/models/res_company.py
new file mode 100644
index 00000000000..bee9be55580
--- /dev/null
+++ b/addons/l10n_pe/models/res_company.py
@@ -0,0 +1,13 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from odoo import models, api
+
+
+class ResCompany(models.Model):
+
+ _inherit = "res.company"
+
+ @api.onchange('country_id')
+ def onchange_country(self):
+ """In Peru, the rounding method it's calculated as global"""
+ for rec in self.filtered(lambda x: x.country_id == self.env.ref('base.pe')):
+ rec.tax_calculation_rounding_method = 'round_globally'