Skip to content

Commit 5db87dc

Browse files
committed
[WIP] Reorder CAEA
closes #41 Signed-off-by: Juan José Scarafía <jjs@adhoc.com.ar>
1 parent 30900ca commit 5db87dc

21 files changed

+165
-145
lines changed

l10n_ar_afipws_caea/README.rst

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,37 @@
1-
=========================================
1+
===========================================
22
Implemenar CAEA en los Web Services de AFIP
3-
=========================================
3+
===========================================
44
¿Que es el CAEA?
5-
--------------------------
5+
----------------
66
Permite consignar en los comprobantes respaldatorios de las operaciones, el Código de Autorización Electrónico Anticipado "CAEA", en reemplazo del "CAE"
77
http://www.afip.gov.ar/genericos/guiavirtual/directorio_subcategoria_nivel3.aspx?id_nivel1=562id_nivel2=603&id_nivel3=1663
88

99
Requisitos
10-
--------------------------
10+
------------
1111
http://www.afip.gov.ar/genericos/guiavirtual/consultas_detalle.aspx?id=13872311
1212
Hayan emitido en cada mes calendario un mínimo de 1.800 comprobantes (Facturas, recibos, notas de crédito y notas de débito clases "A", "A" con leyenda "PAGO EN CBU INFORMADA", "M", "B" y "C"), en el período de 3 meses calendarios inmediatos anteriores a la solicitud de incorporación al procedimiento especial.
1313
No podrán considerarse para el cumplimiento de la mencionada condición los comprobantes por operaciones con consumidores finales
1414

1515
¿Cómo se realiza la solicitud de adhesión al régimen?
16-
--------------------------
16+
-------------------------------------------------------
1717
La solicitud de adhesión deberá realizarse ingresando al servicio con clave fiscal "Regímenes de Facturación y Registración (REAR/RECE/RFI)". Asimismo, se deberá comunicar el período a partir del cual comenzará a aplicar el procedimiento especial y si la adhesión se efectúa bajo la modalidad de emisión complementaria a la principal - contingencia - (p.ej. Controlador Fiscal, Factura Electrónica) conforme lo previsto en el Título III RG 4290/18.
1818

1919
constancia de la presentación realizada y admitida, el sistema emitirá un comprobante que tendrá el carácter de acuse de recibo.
2020

2121
¿Se debe habilitar un nuevo punto de venta para el CAEA?
22-
--------------------------
22+
---------------------------------------------------------
2323
Para los comprobantes que se emitan bajo la modalidad excepcional complementaria a la principal (contingencia) conforme a lo previsto en el Título III RG 4290/18, se deberán habilitar puntos de venta específicos por dicha modalidad asociados al mismo domicilio de la modalidad de emisión principal y a su condición ante el impuesto al valor agregado.
2424

2525
¿Cómo debo proceder en caso de no haber solicitado el CAEA durante una quincena?
26-
--------------------------
26+
--------------------------------------------------------------------------------
2727
Si el contribuyente es un obligado a Factura Electrónica y no puede realizar los comprobantes con CAEA deberán ser generados con CAE. Al no haber solicitado CAEA, no deben informar nada para esa quincena.
2828

2929
¿Hay un límite en la cantidad de comprobantes a emitir por medios alternativos de contingencia?
30-
--------------------------
30+
-----------------------------------------------------------------------------------------------
3131
Las modalidades alternativas ante inconvenientes con el uso del controlador fiscal o de la emisión de comprobantes electrónicos, sólo deben ser utilizadas en condiciones de excepcionalidad.
3232

3333
Se considera que no se cumple con la condición de excepcionalidad cuando
34-
----------------------------
34+
-------------------------------------------------------------------------
3535
Durante 2 meses consecutivos o 3 meses alternados en un año calendario, se observe alguna de las siguientes irregularidades:
3636

3737
a) que la emisión de comprobantes con CAEA o CAI excedan significativamente el nivel de facturación regular, es decir la cantidad de comprobantes emitidos mensualmente por excepción representan un 5%, o más, respecto del total de la sucursal.

l10n_ar_afipws_caea/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# -*- coding: utf-8 -*-
22

33
from . import models
4+
from . import wizard
Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "Factura Electrónica Argentina CAEA",
33
"summary": """
4-
Habilita la gestion de CAEA""",
4+
Habilita la gestion de CAEA para modo contingencia""",
55
"sequence": 14,
66
"author": "Filoquin",
77
"website": "http://www.sipecu.com.ar",
@@ -11,19 +11,22 @@
1111
"depends": ["l10n_ar_afipws_fe"],
1212
"data": [
1313
"security/ir.model.access.csv",
14-
"views/asset.xml",
1514
"views/account_journal.xml",
1615
"views/afipws_caea.xml",
1716
"views/company.xml",
18-
"views/res_config_settings.xml",
19-
"views/pyafipws_dummy.xml",
17+
"wizard/res_config_settings.xml",
18+
"wizard/pyafipws_dummy.xml",
2019
"views/account_move.xml",
2120
"data/ir_cron.xml",
2221
],
2322
"qweb": [
2423
"static/src/xml/systray_afip_caea.xml",
2524
],
26-
"installable": False,
25+
'assets': {
26+
'web.assets_backend': ['/l10n_ar_afipws_caea/static/src/js/systray_afip_caea.js'],
27+
'web.assets_qweb': ['/l10n_ar_afipws_caea/static/src/xml/systray_afip_caea.xml'],
28+
},
29+
"installable": True,
2730
"auto_install": False,
2831
"application": False,
2932
}

l10n_ar_afipws_caea/models/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,3 @@
44
from . import account_journal
55
from . import res_company
66
from . import account_move
7-
from . import res_config_settings
8-
from . import pyafipws_dummy

l10n_ar_afipws_caea/models/account_journal.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from odoo import fields, models, _
1+
from odoo import fields, models, api, _
22
from odoo.exceptions import UserError
33

44
import logging
@@ -14,6 +14,12 @@ class AccountJournal(models.Model):
1414
string="Caea journal",
1515
)
1616

17+
@api.model
18+
def _get_type_mapping(self):
19+
vals = super()._get_type_mapping()
20+
vals["CAEA"] = "wsfe"
21+
return vals
22+
1723
def _get_l10n_ar_afip_pos_types_selection(self):
1824
"""Add more options to the selection field AFIP POS System, re order options by common use"""
1925
res = super()._get_l10n_ar_afip_pos_types_selection()

l10n_ar_afipws_caea/models/account_move.py

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def _post(self, soft=True):
3333
.sudo()
3434
.get_param("afip.ws.caea.state", "inactive")
3535
)
36+
3637
if caea_state == "active":
3738
inv_ids = self.filtered(
3839
lambda record: record.journal_id.l10n_ar_afip_pos_system != "CAEA"
@@ -41,32 +42,21 @@ def _post(self, soft=True):
4142
if len(inv.journal_id.caea_journal_id):
4243
inv.journal_id = inv.journal_id.caea_journal_id.id
4344

44-
res = super()._post(soft)
45-
return res
45+
return super()._post(soft)
4646

4747
def do_pyafipws_request_cae(self):
48-
caea_state = (
49-
self.env["ir.config_parameter"]
50-
.sudo()
51-
.get_param("afip.ws.caea.state", "inactive")
52-
)
53-
if caea_state == "inactive":
54-
return super().do_pyafipws_request_cae()
55-
elif caea_state == "active":
56-
return self.do_pyafipws_request_caea()
48+
caea_inv = self.filtered(lambda x: x.journal_id.l10n_ar_afip_pos_system == "CAEA")
49+
caea_inv.do_pyafipws_request_caea()
50+
super(AccountMove, self - caea_inv).do_pyafipws_request_cae()
5751

5852
def do_pyafipws_request_caea(self):
5953
for inv in self:
60-
if inv.journal_id.l10n_ar_afip_pos_system != "CAEA":
61-
continue
6254
# Ignore invoices with cae (do not check date)
6355
if inv.afip_auth_code:
6456
continue
6557

6658
afip_ws = inv.journal_id.afip_ws
67-
if not afip_ws:
68-
continue
69-
59+
_logger.info("afip_ws %s" % afip_ws )
7060
# Ignore invoice if not ws on point of sale
7161
if not afip_ws:
7262
raise UserError(
@@ -119,6 +109,7 @@ def do_pyafipws_post_caea_invoice(self):
119109
# Inicio conexion
120110
ws = inv.company_id.get_connection(afip_ws).connect()
121111

112+
122113
# Preparo los datos
123114
invoice_info = inv.map_invoice_info(afip_ws)
124115
invoice_info["caea"] = inv.afip_auth_code
@@ -166,12 +157,12 @@ def do_pyafipws_post_caea_invoice(self):
166157
# escribe aca si no hay errores
167158
_logger.info(
168159
"CAEA solicitado con exito. %s. Resultado %s"
169-
% (afip_auth_code, ws.Resultado)
160+
% (ws.CAEA, ws.Resultado)
170161
)
171-
if hasattr(ws, "Vencimiento"):
172-
vto = datetime.strptime(ws.Vencimiento, "%Y%m%d").date()
173-
if hasattr(ws, "FchVencCAE"):
174-
vto = datetime.strptime(ws.FchVencCAE, "%Y%m%d").date()
162+
163+
if hasattr(ws, "CbteFch"):
164+
vto = datetime.strptime(ws.CbteFch, "%Y%m%d").date()
165+
175166

176167
inv.write(
177168
{
@@ -185,3 +176,32 @@ def do_pyafipws_post_caea_invoice(self):
185176
)
186177

187178
inv._cr.commit()
179+
180+
def wsfe_pyafipws_caea_create_invoice(self, ws, invoice_info):
181+
ws.CrearFactura(
182+
invoice_info["concepto"],
183+
invoice_info["tipo_doc"],
184+
invoice_info["nro_doc"],
185+
invoice_info["doc_afip_code"],
186+
invoice_info["pos_number"],
187+
invoice_info["cbt_desde"],
188+
invoice_info["cbt_hasta"],
189+
invoice_info["imp_total"],
190+
invoice_info["imp_tot_conc"],
191+
invoice_info["imp_neto"],
192+
invoice_info["imp_iva"],
193+
invoice_info["imp_trib"],
194+
invoice_info["imp_op_ex"],
195+
invoice_info["fecha_cbte"],
196+
invoice_info["fecha_venc_pago"],
197+
invoice_info["fecha_serv_desde"],
198+
invoice_info["fecha_serv_hasta"],
199+
invoice_info["moneda_id"],
200+
invoice_info["moneda_ctz"],
201+
invoice_info["caea"],
202+
invoice_info["CbteFchHsGen"],
203+
)
204+
205+
206+
def wsfe_caea_request_autorization(self, ws, afip_ws):
207+
ws.CAEARegInformativo()

l10n_ar_afipws_caea/models/afipws_caea.py

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class AfipwsCaea(models.Model):
1515
_inherit = ["mail.thread", "mail.activity.mixin"]
1616

1717
_sql_constraints = [
18-
("unique_caea", "unique (company_id,name,order)", "CAEA already exists!")
18+
("name_uniq", "unique(name)", "CAEA already exists!")
1919
]
2020
state = fields.Selection(
2121
[("draft", "draft"), ("active", "active"), ("reported", "reported")],
@@ -133,37 +133,28 @@ def _compute_date(self):
133133
- relativedelta(days=1)
134134
)
135135

136-
@api.model
137-
def create(self, values):
138-
"""exist = self.search([
139-
('company_id', '=', values['company_id']),
140-
('name', '=', values['name']),
141-
('order', '=', values['order'])
142-
])
143-
if len(exist):
144-
return"""
136+
@api.model_create_multi
137+
def create(self, vals_list):
145138
self.env["ir.config_parameter"].set_param("afip.ws.caea.state", "inactive")
146-
147-
company_id = self.env["res.company"].search([("id", "=", values["company_id"])])
148-
afip_ws = self.company_id.get_caea_ws()
149-
150-
ws = company_id.get_connection(afip_ws).connect()
151-
caea = ws.CAEAConsultar(values["period"], values["order"])
152-
# raise ValidationError(
153-
# _('The Common Name must be lower than 50 characters long'))
154-
155-
# _logger.info("ws.ErrMsg " % ws.ErrMsg)
156-
if caea == "":
157-
caea = ws.CAEASolicitar(values["period"], values["order"])
158-
_logger.info(ws.ErrMsg)
159-
_logger.info(caea)
160-
161-
values["name"] = caea
162-
values["afip_observations"] = ws.Obs
163-
values["process_deadline"] = datetime.strptime(ws.FchTopeInf, "%Y%m%d")
164-
values["state"] = "active"
165-
# TODO: FchProceso
166-
return super().create(values)
139+
for vals in vals_list:
140+
if vals['name'] == '/':
141+
company_id = self.env["res.company"].search([("id", "=", vals["company_id"])])
142+
afip_ws = company_id.get_caea_ws()
143+
ws = company_id.get_connection(afip_ws).connect()
144+
caea = ws.CAEAConsultar(values["period"], values["order"])
145+
146+
# _logger.info("ws.ErrMsg " % ws.ErrMsg)
147+
if caea == "":
148+
caea = ws.CAEASolicitar(values["period"], values["order"])
149+
_logger.info(ws.ErrMsg)
150+
_logger.info(caea)
151+
152+
vals["name"] = caea
153+
vals["afip_observations"] = ws.Obs
154+
vals["process_deadline"] = datetime.strptime(ws.FchTopeInf, "%Y%m%d")
155+
vals["state"] = "active"
156+
# TODO: FchProceso
157+
return super().create(vals_list)
167158

168159
def action_send_invoices(self):
169160
self.env["ir.config_parameter"].set_param("afip.ws.caea.state", "inactive")

l10n_ar_afipws_caea/security/ir.model.access.csv

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
22
access_afipws_caea_manager,afipws.caea.manager,model_afipws_caea,base.group_system,1,1,1,1
33
access_afipws_caea_user,afipws.caea.user,model_afipws_caea,base.group_user,1,0,0,0
44
access_afipws_caea_log_manager,afipws.caea.log.user,l10n_ar_afipws_caea.model_afipws_caea_log,base.group_user,1,0,0,0
5-
ccess_afipws_caea_log_user,afipws.caea.log.manger,l10n_ar_afipws_caea.model_afipws_caea_log,account.group_account_invoice,1,1,1,0
5+
access_afipws_caea_log_user,afipws.caea.log.manger,l10n_ar_afipws_caea.model_afipws_caea_log,account.group_account_invoice,1,1,1,0
6+
access_pyafipws_dummy_user,afipws.dummy.user,model_pyafipws_dummy,base.group_user,1,1,1,1
Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,35 @@
1-
odoo.define('afip.caea', function (require) {
2-
"use strict";
1+
/** @odoo-module **/
2+
import SystrayMenu from 'web.SystrayMenu';
3+
import Widget from 'web.Widget';
4+
/**
5+
* Menu item appended in the systray part of the navbar
6+
*/
37

4-
var SystrayMenu = require('web.SystrayMenu');
5-
var Widget = require('web.Widget');
68
//var model_obj = new instance.web.Model('ir.model.data');
9+
const { Component } = owl;
10+
var CaeaMenu = Widget.extend({
11+
name: 'caea_menu',
12+
template: 'systray_afip.caea',
13+
events: {
14+
'click .caea_label': 'onclick_caea_icon',
15+
},
16+
onclick_caea_icon:function(){
17+
var action = {
18+
type: 'ir.actions.act_window',
19+
res_model: 'pyafipws.dummy',
20+
view_type: 'form',
21+
views:[[false, 'form']],
22+
target: 'new',
23+
};
724

8-
var ActionMenu = Widget.extend({
9-
template: 'systray_afip.caea',
10-
events: {
11-
'click .caea_label': 'onclick_caea_icon',
12-
},
13-
onclick_caea_icon:function(){
14-
var action = {
15-
type: 'ir.actions.act_window',
16-
res_model: 'pyafipws.dummy',
17-
view_type: 'form',
18-
views:[[false, 'form']],
19-
target: 'new',
20-
};
21-
22-
this.do_action(action);
23-
},
24-
//some functions
25+
this.do_action(action);
26+
},
27+
//some functions
2528

26-
});
29+
});
2730

28-
SystrayMenu.Items.push(ActionMenu);
29-
return ActionMenu;
30-
});
3131

32+
SystrayMenu.Items.push(CaeaMenu);
33+
34+
export default CaeaMenu;
3235

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8" ?>
22
<templates>
33
<t t-name="systray_afip.caea">
4-
<li class="caea_icon">
5-
<label class="caea_label" style="margin-bottom:0px;"
6-
title="Afip state">
7-
<div class="icon_div">
8-
<div class="toggle-icon"><i class="fa fa-plug"
9-
id="fa-icon"/>
10-
</div>
11-
</div>
12-
</label>
13-
</li>
14-
</t>
15-
</templates>
4+
<div class="o_caea_systray_item">
5+
<a class="o-no-caret caea_label" data-display="static" aria-expanded="false" title="afip" href="#" role="button">
6+
<i class="fa fa-plug" role="img" aria-label="Afip"/>
7+
</a>
8+
9+
</div>
10+
</t>
11+
</templates>

0 commit comments

Comments
 (0)