diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/l10n_cl/models | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/l10n_cl/models')
| -rw-r--r-- | addons/l10n_cl/models/__init__.py | 14 | ||||
| -rw-r--r-- | addons/l10n_cl/models/account_chart_template.py | 15 | ||||
| -rw-r--r-- | addons/l10n_cl/models/account_journal.py | 11 | ||||
| -rw-r--r-- | addons/l10n_cl/models/account_move.py | 126 | ||||
| -rw-r--r-- | addons/l10n_cl/models/account_tax.py | 27 | ||||
| -rw-r--r-- | addons/l10n_cl/models/ir_sequence.py | 10 | ||||
| -rw-r--r-- | addons/l10n_cl/models/l10n_latam_document_type.py | 37 | ||||
| -rw-r--r-- | addons/l10n_cl/models/res_company.py | 12 | ||||
| -rw-r--r-- | addons/l10n_cl/models/res_country.py | 12 | ||||
| -rw-r--r-- | addons/l10n_cl/models/res_currency.py | 10 | ||||
| -rw-r--r-- | addons/l10n_cl/models/res_partner.py | 65 | ||||
| -rw-r--r-- | addons/l10n_cl/models/res_partner_bank.py | 9 | ||||
| -rw-r--r-- | addons/l10n_cl/models/uom_uom.py | 9 |
13 files changed, 357 insertions, 0 deletions
diff --git a/addons/l10n_cl/models/__init__.py b/addons/l10n_cl/models/__init__.py new file mode 100644 index 00000000..54120897 --- /dev/null +++ b/addons/l10n_cl/models/__init__.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from . import account_chart_template +from . import account_journal +from . import account_move +from . import account_tax +from . import ir_sequence +from . import l10n_latam_document_type +from . import res_company +from . import res_country +from . import res_currency +from . import res_partner +from . import res_partner_bank +from . import uom_uom diff --git a/addons/l10n_cl/models/account_chart_template.py b/addons/l10n_cl/models/account_chart_template.py new file mode 100644 index 00000000..ef586451 --- /dev/null +++ b/addons/l10n_cl/models/account_chart_template.py @@ -0,0 +1,15 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import models +from odoo.http import request + + +class AccountChartTemplate(models.Model): + _inherit = 'account.chart.template' + + def _load(self, sale_tax_rate, purchase_tax_rate, company): + """ Set tax calculation rounding method required in Chilean localization""" + res = super()._load(sale_tax_rate, purchase_tax_rate, company) + if company.country_id.code == 'CL': + company.write({'tax_calculation_rounding_method': 'round_globally'}) + return res diff --git a/addons/l10n_cl/models/account_journal.py b/addons/l10n_cl/models/account_journal.py new file mode 100644 index 00000000..5917e688 --- /dev/null +++ b/addons/l10n_cl/models/account_journal.py @@ -0,0 +1,11 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models, api + + +class AccountJournal(models.Model): + _inherit = "account.journal" + + l10n_cl_sequence_ids = fields.Many2many( + 'ir.sequence', 'l10n_cl_journal_sequence_rel', 'journal_id', 'sequence_id', string='Sequences (cl)', + domain="[('l10n_latam_document_type_id', '!=', False)]")
\ No newline at end of file diff --git a/addons/l10n_cl/models/account_move.py b/addons/l10n_cl/models/account_move.py new file mode 100644 index 00000000..06588533 --- /dev/null +++ b/addons/l10n_cl/models/account_move.py @@ -0,0 +1,126 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo.exceptions import ValidationError +from odoo import models, fields, api, _ +from odoo.osv import expression + +SII_VAT = '60805000-0' + + +class AccountMove(models.Model): + _inherit = "account.move" + + l10n_latam_document_type_id_code = fields.Char(related='l10n_latam_document_type_id.code', string='Doc Type') + partner_id_vat = fields.Char(related='partner_id.vat', string='VAT No') + l10n_latam_internal_type = fields.Selection( + related='l10n_latam_document_type_id.internal_type', string='L10n Latam Internal Type') + + def _get_l10n_latam_documents_domain(self): + self.ensure_one() + if self.journal_id.company_id.country_id != self.env.ref('base.cl') or not \ + self.journal_id.l10n_latam_use_documents: + return super()._get_l10n_latam_documents_domain() + if self.journal_id.type == 'sale': + domain = [('country_id.code', '=', "CL"), ('internal_type', '!=', 'invoice_in')] + if self.company_id.partner_id.l10n_cl_sii_taxpayer_type == '1': + domain += [('code', '!=', '71')] # Companies with VAT Affected doesn't have "Boleta de honorarios Electrónica" + return domain + domain = [ + ('country_id.code', '=', 'CL'), + ('internal_type', 'in', ['invoice', 'debit_note', 'credit_note', 'invoice_in'])] + if self.partner_id.l10n_cl_sii_taxpayer_type == '1' and self.partner_id_vat != '60805000-0': + domain += [('code', 'not in', ['39', '70', '71', '914', '911'])] + elif self.partner_id.l10n_cl_sii_taxpayer_type == '1' and self.partner_id_vat == '60805000-0': + domain += [('code', 'not in', ['39', '70', '71'])] + if self.move_type == 'in_invoice': + domain += [('internal_type', '!=', 'credit_note')] + elif self.partner_id.l10n_cl_sii_taxpayer_type == '2': + domain += [('code', 'in', ['70', '71', '56', '61'])] + elif self.partner_id.l10n_cl_sii_taxpayer_type == '3': + domain += [('code', 'in', ['35', '38', '39', '41', '56', '61'])] + elif not self.partner_id.l10n_cl_sii_taxpayer_type or self.partner_id.country_id != self.env.ref( + 'base.cl') or self.partner_id.l10n_cl_sii_taxpayer_type == '4': + domain += [('code', 'in', [])] + return domain + + + def _check_document_types_post(self): + for rec in self.filtered( + lambda r: r.company_id.country_id.code == "CL" and + r.journal_id.type in ['sale', 'purchase']): + tax_payer_type = rec.partner_id.l10n_cl_sii_taxpayer_type + vat = rec.partner_id.vat + country_id = rec.partner_id.country_id + latam_document_type_code = rec.l10n_latam_document_type_id.code + if (not tax_payer_type or not vat) and (country_id.code == "CL" and latam_document_type_code + and latam_document_type_code not in ['35', '38', '39', '41']): + raise ValidationError(_('Tax payer type and vat number are mandatory for this type of ' + 'document. Please set the current tax payer type of this customer')) + if rec.journal_id.type == 'sale' and rec.journal_id.l10n_latam_use_documents: + if country_id.code != "CL": + if not ((tax_payer_type == '4' and latam_document_type_code in ['110', '111', '112']) or ( + tax_payer_type == '3' and latam_document_type_code in ['39', '41', '61', '56'])): + raise ValidationError(_( + 'Document types for foreign customers must be export type (codes 110, 111 or 112) or you \ + should define the customer as an end consumer and use receipts (codes 39 or 41)')) + if rec.journal_id.type == 'purchase' and rec.journal_id.l10n_latam_use_documents: + if vat != SII_VAT and latam_document_type_code == '914': + raise ValidationError(_('The DIN document is intended to be used only with RUT 60805000-0' + ' (Tesorería General de La República)')) + if not tax_payer_type or not vat: + if country_id.code == "CL" and latam_document_type_code not in [ + '35', '38', '39', '41']: + raise ValidationError(_('Tax payer type and vat number are mandatory for this type of ' + 'document. Please set the current tax payer type of this supplier')) + if tax_payer_type == '2' and latam_document_type_code not in ['70', '71', '56', '61']: + raise ValidationError(_('The tax payer type of this supplier is incorrect for the selected type' + ' of document.')) + if tax_payer_type in ['1', '3']: + if latam_document_type_code in ['70', '71']: + raise ValidationError(_('The tax payer type of this supplier is not entitled to deliver ' + 'fees documents')) + if latam_document_type_code in ['110', '111', '112']: + raise ValidationError(_('The tax payer type of this supplier is not entitled to deliver ' + 'imports documents')) + if tax_payer_type == '4' or country_id.code != "CL": + raise ValidationError(_('You need a journal without the use of documents for foreign ' + 'suppliers')) + if rec.journal_id.type == 'purchase' and not rec.journal_id.l10n_latam_use_documents: + if tax_payer_type != '4': + raise ValidationError(_('This supplier should be defined as foreigner tax payer type and ' + 'the country should be different from Chile to register purchases.')) + + @api.onchange('journal_id') + def _l10n_cl_onchange_journal(self): + self.l10n_latam_document_type_id = False + + def _post(self, soft=True): + self._check_document_types_post() + return super()._post(soft) + + def _l10n_cl_get_formatted_sequence(self, number=0): + return '%s %06d' % (self.l10n_latam_document_type_id.doc_code_prefix, number) + + def _get_starting_sequence(self): + """ If use documents then will create a new starting sequence using the document type code prefix and the + journal document number with a 6 padding number """ + if self.journal_id.l10n_latam_use_documents and self.env.company.country_id.code == "CL": + if self.l10n_latam_document_type_id: + return self._l10n_cl_get_formatted_sequence() + return super()._get_starting_sequence() + + def _get_last_sequence_domain(self, relaxed=False): + where_string, param = super(AccountMove, self)._get_last_sequence_domain(relaxed) + if self.company_id.country_id.code == "CL" and self.l10n_latam_use_documents: + where_string = where_string.replace('journal_id = %(journal_id)s AND', '') + where_string += ' AND l10n_latam_document_type_id = %(l10n_latam_document_type_id)s AND ' \ + 'company_id = %(company_id)s AND move_type IN (\'out_invoice\', \'out_refund\')' + param['company_id'] = self.company_id.id or False + param['l10n_latam_document_type_id'] = self.l10n_latam_document_type_id.id or 0 + return where_string, param + + def _get_name_invoice_report(self): + self.ensure_one() + if self.l10n_latam_use_documents and self.company_id.country_id.code == 'CL': + return 'l10n_cl.report_invoice_document' + return super()._get_name_invoice_report() diff --git a/addons/l10n_cl/models/account_tax.py b/addons/l10n_cl/models/account_tax.py new file mode 100644 index 00000000..0f102863 --- /dev/null +++ b/addons/l10n_cl/models/account_tax.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo import fields, models + + +class AccountTax(models.Model): + _name = 'account.tax' + _inherit = 'account.tax' + + l10n_cl_sii_code = fields.Integer('SII Code', group_operator=False) + + +class AccountTaxTemplate(models.Model): + _name = 'account.tax.template' + _inherit = 'account.tax.template' + + l10n_cl_sii_code = fields.Integer('SII Code') + + def _get_tax_vals(self, company, tax_template_to_tax): + self.ensure_one() + vals = super(AccountTaxTemplate, self)._get_tax_vals(company, tax_template_to_tax) + vals.update({ + 'l10n_cl_sii_code': self.l10n_cl_sii_code, + }) + if self.tax_group_id: + vals['tax_group_id'] = self.tax_group_id.id + return vals diff --git a/addons/l10n_cl/models/ir_sequence.py b/addons/l10n_cl/models/ir_sequence.py new file mode 100644 index 00000000..5da1e5c9 --- /dev/null +++ b/addons/l10n_cl/models/ir_sequence.py @@ -0,0 +1,10 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo import fields, models + + +class IrSequence(models.Model): + + _inherit = 'ir.sequence' + + l10n_cl_journal_ids = fields.Many2many('account.journal', 'l10n_cl_journal_sequence_rel', 'sequence_id', + 'journal_id', 'Journals', readonly=True) diff --git a/addons/l10n_cl/models/l10n_latam_document_type.py b/addons/l10n_cl/models/l10n_latam_document_type.py new file mode 100644 index 00000000..e458cb71 --- /dev/null +++ b/addons/l10n_cl/models/l10n_latam_document_type.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo import models, fields + + +class L10nLatamDocumentType(models.Model): + + _inherit = 'l10n_latam.document.type' + + internal_type = fields.Selection( + selection_add=[ + ('invoice', 'Invoices'), + ('invoice_in', 'Purchase Invoices'), + ('debit_note', 'Debit Notes'), + ('credit_note', 'Credit Notes'), + ('receipt_invoice', 'Receipt Invoice')]) + + def _format_document_number(self, document_number): + """ Make validation of Import Dispatch Number + * making validations on the document_number. If it is wrong it should raise an exception + * format the document_number against a pattern and return it + """ + self.ensure_one() + if self.country_id.code != "CL": + return super()._format_document_number(document_number) + + if not document_number: + return False + + return document_number.zfill(6) + + def _filter_taxes_included(self, taxes): + """ In Chile we include taxes depending on document type """ + self.ensure_one() + if self.country_id.code == "CL" and self.code in ['39', '41', '110', '111', '112', '34']: + return taxes.filtered(lambda x: x.l10n_cl_sii_code == 14) + return super()._filter_taxes_included(taxes) diff --git a/addons/l10n_cl/models/res_company.py b/addons/l10n_cl/models/res_company.py new file mode 100644 index 00000000..8821be52 --- /dev/null +++ b/addons/l10n_cl/models/res_company.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo import models, fields + + +class ResCompany(models.Model): + _inherit = "res.company" + + def _localization_use_documents(self): + """ Chilean localization use documents """ + self.ensure_one() + return self.country_id.code == "CL" or super()._localization_use_documents() diff --git a/addons/l10n_cl/models/res_country.py b/addons/l10n_cl/models/res_country.py new file mode 100644 index 00000000..7e78a0ca --- /dev/null +++ b/addons/l10n_cl/models/res_country.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo import fields, models + + +class ResPartner(models.Model): + _name = 'res.country' + _inherit = 'res.country' + + l10n_cl_customs_code = fields.Char('Customs Code') + l10n_cl_customs_name = fields.Char('Customs Name') + l10n_cl_customs_abbreviation = fields.Char('Customs Abbreviation') diff --git a/addons/l10n_cl/models/res_currency.py b/addons/l10n_cl/models/res_currency.py new file mode 100644 index 00000000..473cad7f --- /dev/null +++ b/addons/l10n_cl/models/res_currency.py @@ -0,0 +1,10 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo import _, api, fields, models + + +class ResCurrency(models.Model): + _name = "res.currency" + _inherit = "res.currency" + + l10n_cl_currency_code = fields.Char('Currency Code') + l10n_cl_short_name = fields.Char('Short Name') diff --git a/addons/l10n_cl/models/res_partner.py b/addons/l10n_cl/models/res_partner.py new file mode 100644 index 00000000..cc7c9786 --- /dev/null +++ b/addons/l10n_cl/models/res_partner.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +import stdnum +from odoo import _, api, fields, models +from odoo.exceptions import UserError, ValidationError + + +class ResPartner(models.Model): + _name = 'res.partner' + _inherit = 'res.partner' + + _sii_taxpayer_types = [ + ('1', _('VAT Affected (1st Category)')), + ('2', _('Fees Receipt Issuer (2nd category)')), + ('3', _('End Consumer')), + ('4', _('Foreigner')), + ] + + l10n_cl_sii_taxpayer_type = fields.Selection( + _sii_taxpayer_types, 'Taxpayer Type', index=True, + help='1 - VAT Affected (1st Category) (Most of the cases)\n' + '2 - Fees Receipt Issuer (Applies to suppliers who issue fees receipt)\n' + '3 - End consumer (only receipts)\n' + '4 - Foreigner') + + @api.model + def _commercial_fields(self): + return super()._commercial_fields() + ['l10n_cl_sii_taxpayer_type'] + + def _format_vat_cl(self, values): + identification_types = [self.env.ref('l10n_latam_base.it_vat').id, self.env.ref('l10n_cl.it_RUT').id, + self.env.ref('l10n_cl.it_RUN').id] + country = self.env["res.country"].browse(values.get('country_id')) + identification_type = self.env['l10n_latam.identification.type'].browse( + values.get('l10n_latam_identification_type_id') + ) + partner_country_is_chile = country.code == "CL" or identification_type.country_id.code == "CL" + if partner_country_is_chile and \ + values.get('l10n_latam_identification_type_id') in identification_types and values.get('vat'): + return stdnum.util.get_cc_module('cl', 'vat').format(values['vat']).replace('.', '').replace( + 'CL', '').upper() + else: + return values['vat'] + + def _format_dotted_vat_cl(self, vat): + vat_l = vat.split('-') + n_vat, n_dv = vat_l[0], vat_l[1] + return '%s-%s' % (format(int(n_vat), ',d').replace(',', '.'), n_dv) + + @api.model + def create(self, values): + if values.get('vat'): + values['vat'] = self._format_vat_cl(values) + return super().create(values) + + def write(self, values): + for record in self: + vat_values = { + 'vat': values.get('vat', record.vat), + 'l10n_latam_identification_type_id': values.get( + 'l10n_latam_identification_type_id', record.l10n_latam_identification_type_id.id), + 'country_id': values.get('country_id', record.country_id.id) + } + values['vat'] = self._format_vat_cl(vat_values) + return super().write(values) diff --git a/addons/l10n_cl/models/res_partner_bank.py b/addons/l10n_cl/models/res_partner_bank.py new file mode 100644 index 00000000..611c14e1 --- /dev/null +++ b/addons/l10n_cl/models/res_partner_bank.py @@ -0,0 +1,9 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo import fields, models + + +class ResBank(models.Model): + _name = 'res.bank' + _inherit = 'res.bank' + + l10n_cl_sbif_code = fields.Char('Cod. SBIF', size=10) diff --git a/addons/l10n_cl/models/uom_uom.py b/addons/l10n_cl/models/uom_uom.py new file mode 100644 index 00000000..f4ec5de0 --- /dev/null +++ b/addons/l10n_cl/models/uom_uom.py @@ -0,0 +1,9 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models, api, _ + + +class UomUom(models.Model): + _inherit = 'uom.uom' + + l10n_cl_sii_code = fields.Char('SII Code') |
