Skip to content

Commit 5bf7af0

Browse files
committed
[ADD] l10n_ar_wsmtxca_ws: new module to support WSMTXCA webservice
1 parent 10626da commit 5bf7af0

8 files changed

Lines changed: 734 additions & 0 deletions

File tree

l10n_ar_wsmtxca_ws/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
##############################################################################
2+
# For copyright and license notices, see __manifest__.py file in module root
3+
# directory
4+
##############################################################################
5+
from . import models
6+
from . import wizards

l10n_ar_wsmtxca_ws/__manifest__.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
##############################################################################
2+
#
3+
# Copyright (C) 2015 ADHOC SA (http://www.adhoc.com.ar)
4+
# All Rights Reserved.
5+
#
6+
# This program is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU Affero General Public License as
8+
# published by the Free Software Foundation, either version 3 of the
9+
# License, or (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU Affero General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Affero General Public License
17+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
#
19+
##############################################################################
20+
{
21+
"name": "Argentinean Electronic Invoicing - WSMTXCA Webservice",
22+
"version": "18.0.1.0.0",
23+
"category": "Localization/Argentina",
24+
"sequence": 14,
25+
"author": "ADHOC SA",
26+
"website": "www.adhoc.com.ar",
27+
"license": "AGPL-3",
28+
"summary": """
29+
Argentinean Electronic Invoicing - WSMTXCA Webservice
30+
======================================================
31+
32+
This module extends the Argentinean Electronic Invoicing (l10n_ar_edi) to add support for the WSMTXCA webservice.
33+
34+
Functional
35+
----------
36+
37+
WSMTXCA - "Mercado de Cambio Electrónico" (Electronic Exchange Market)
38+
39+
This webservice is used for electronic invoicing in the context of foreign exchange operations in Argentina.
40+
It allows generating and validating invoices with specific requirements for:
41+
42+
* Foreign currency operations
43+
* Exchange market transactions
44+
* Invoices with special tax treatment for international operations
45+
46+
The module inherits and extends the base electronic invoicing functionality to handle:
47+
48+
* Specific WSMTXCA authentication conversion
49+
* WSMTXCA-specific request data format
50+
* Product MTX codes (barcode validation for GTIN 8/12/13)
51+
* Special handling for invoice line details
52+
* Tributes and taxes in WSMTXCA format
53+
* Related invoice data conversion
54+
* Currency exchange rate validations specific to WSMTXCA
55+
56+
Configuration
57+
-------------
58+
59+
1. Install the module
60+
2. Configure your AFIP certificate in the Accounting Settings (inherited from l10n_ar_edi)
61+
3. Create a Sales Journal with AFIP POS System set to "WSMTXCA - Mercado de Cambio Electrónico"
62+
4. Configure the AFIP POS Number according to your AFIP portal configuration
63+
64+
Technical
65+
---------
66+
67+
The module implements:
68+
69+
* account.move inheritance for WSMTXCA-specific CAE request handling
70+
* account.journal inheritance for WSMTXCA authentication conversion
71+
* res.currency inheritance for WSMTXCA-specific currency rate handling
72+
* l10n_ar_afipws.connection inheritance for WSMTXCA webservice connection
73+
* l10n_ar_afip.ws.consult wizard inheritance for WSMTXCA invoice consultation
74+
75+
For more information about WSMTXCA go to:
76+
https://www.afip.gob.ar/ws/documentacion/ws-mtxca.asp
77+
""",
78+
"depends": [
79+
"l10n_ar_edi",
80+
],
81+
"data": [],
82+
"installable": True,
83+
"auto_install": False,
84+
"application": False,
85+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from . import account_journal
2+
from . import account_move
3+
from . import l10n_ar_afipws_connection
4+
from . import res_currency
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
from odoo import _, api, models
2+
from odoo.exceptions import UserError
3+
4+
5+
class AccountJournal(models.Model):
6+
_inherit = "account.journal"
7+
8+
def _get_l10n_ar_afip_ws(self):
9+
"""Return the list of values of the selection field."""
10+
res = super()._get_l10n_ar_afip_ws()
11+
return [
12+
("wsmtxca", _("Codificación de producto - RG2904 (WSMTXCA)")),
13+
] + res
14+
15+
def _get_l10n_ar_afip_pos_types_selection(self):
16+
"""Add more options to the selection field AFIP POS System, re order options by common use"""
17+
res = super()._get_l10n_ar_afip_pos_types_selection()
18+
res.insert(0, ("WSMTXCAWS", _("Codificación de producto - Web Service")))
19+
return res
20+
21+
@api.depends("l10n_ar_afip_pos_system")
22+
def _compute_l10n_ar_afip_ws(self):
23+
"""Depending on AFIP POS System selected set the proper AFIP WS"""
24+
super()._compute_l10n_ar_afip_ws()
25+
type_mapping = {"WSMTXCAWS": "wsmtxca"}
26+
for rec in self:
27+
rec.l10n_ar_afip_ws = type_mapping.get(rec.l10n_ar_afip_pos_system, False)
28+
29+
def l10n_ar_check_afip_pos_number(self):
30+
"""Return information about the AFIP POS numbers related to the given AFIP WS"""
31+
if self.l10n_ar_afip_ws == "wsmtxca":
32+
self.ensure_one()
33+
connection = self.company_id._l10n_ar_get_connection(self.l10n_ar_afip_ws)
34+
client, auth = connection._get_client()
35+
if self.company_id._get_environment_type() == "testing":
36+
raise UserError(
37+
_(
38+
'"Check Available AFIP PoS" is not implemented in testing mode for webservice %s',
39+
self.l10n_ar_afip_ws,
40+
)
41+
)
42+
auth = self._wsmtxca_convert_auth(auth)
43+
response = client.service.consultarPuntosVentaCAE(auth)
44+
raise UserError(response)
45+
return super().l10n_ar_check_afip_pos_number()
46+
47+
def _l10n_ar_get_afip_last_invoice_number(self, document_type):
48+
"""Consult via webservice the number of the last invoice register"""
49+
afip_ws = self.l10n_ar_afip_ws
50+
if afip_ws == "wsmtxca":
51+
self.ensure_one()
52+
if self.env.registry.in_test_mode():
53+
return 0
54+
55+
pos_number = self.l10n_ar_afip_pos_number
56+
connection = self.company_id._l10n_ar_get_connection(afip_ws)
57+
client, auth = connection._get_client()
58+
last = errors = False
59+
60+
data = self._wsmtxca_convert_auth(auth)
61+
response = client.service.consultarUltimoComprobanteAutorizado(
62+
data,
63+
consultaUltimoComprobanteAutorizadoRequest={
64+
"codigoTipoComprobante": document_type.code,
65+
"numeroPuntoVenta": pos_number,
66+
},
67+
)
68+
if response.numeroComprobante:
69+
last = response.numeroComprobante
70+
if response.arrayErrores:
71+
errors = "".join(
72+
[
73+
"\n* Code %s: %s" % (err.codigo, err.descripcion)
74+
for err in response.arrayErrores.codigoDescripcion
75+
]
76+
)
77+
error_first_invoice = [1502]
78+
if error_first_invoice == [err.codigo for err in response.arrayErrores.codigoDescripcion]:
79+
errors = False # No invoices found for this document type
80+
last = 0
81+
82+
if errors:
83+
raise UserError(
84+
_("We receive this error trying to consult the last invoice number to AFIP:\n%s", errors)
85+
)
86+
return last
87+
return super()._l10n_ar_get_afip_last_invoice_number(document_type)
88+
89+
@api.model
90+
def _get_codes_per_journal_type(self, afip_pos_system):
91+
res = super()._get_codes_per_journal_type(afip_pos_system)
92+
if afip_pos_system != "WSMTXCAWS":
93+
return res
94+
95+
usual_codes = ["1", "2", "3", "6", "7", "8"]
96+
invoice_m_code = ["51", "52", "53"]
97+
mipyme_codes = ["201", "202", "203", "206", "207", "208"]
98+
codes = usual_codes + invoice_m_code + mipyme_codes
99+
100+
res[0] = ("code", "in", codes)
101+
return res
102+
103+
@api.model
104+
def _wsmtxca_convert_auth(self, auth):
105+
res = {"sign": auth.get("Sign"), "token": auth.get("Token"), "cuitRepresentada": auth.get("Cuit")}
106+
return res

0 commit comments

Comments
 (0)