Skip to content

Commit 7bda849

Browse files
[FP][IMP] l10n_ar_account_tax_settlement: nueva especificación txt iibb Misiones ret/perc
Ticket: 60295 X-original-commit: ba999a2 FP directo de 13 a 16 closes #242 Signed-off-by: Ignacio Cainelli <ica@adhoc.com.ar>
1 parent 4e68701 commit 7bda849

File tree

3 files changed

+164
-15
lines changed

3 files changed

+164
-15
lines changed

l10n_ar_account_tax_settlement/README.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ Especificación de archivos:
4545
cuit (req): 11, razon_soc (req): 80, nro_certificado: 10, fecha_ret: 10 (formato "dd/mm/aaaa"), base_imp: 09.2, alicuota: 09.6, importe (req): 09.2
4646
Los campos "base_imp","alicuota","importe" son numéricos , deben completarse con ceros a la izquierda y tienen "." decimal.
4747

48+
* Retenciones y percepciones de IVA sufridas:
49+
* Especificación en ticket 54274 (en una archivo adjunto IVAEspecificación Percepcion y Retencinoes Iva.pdf)
50+
4851
* MISIONES: https://www.atm.misiones.gob.ar/index.php/guia-de-tramites/instructivos/category/53-agentes
4952
Correo DGR: mesadeayuda@tsgroup.com.ar
5053

l10n_ar_account_tax_settlement/__manifest__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@
1919
##############################################################################
2020
{
2121
'name': 'Tax Settlements For Argentina',
22+
<<<<<<< HEAD
2223
'version': "16.0.1.2.0",
24+
=======
25+
'version': "16.0.1.3.0",
26+
>>>>>>> e973f54 ([FW][IMP]l10n_ar_account_tax_settlement: retenciones y percepciones IVA txt #163)
2327
'category': 'Accounting',
2428
'website': 'www.adhoc.com.ar',
2529
'license': 'LGPL-3',

l10n_ar_account_tax_settlement/models/account_journal.py

Lines changed: 157 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class AccountJournal(models.Model):
6161
('iibb_aplicado_api', 'TXT Perc/Ret IIBB aplicadas API'),
6262
('iibb_aplicado_sircar', 'TXT Perc/Ret IIBB aplicadas SIRCAR'),
6363
('iibb_aplicado_dgr_mendoza', 'TXT Perc/Ret IIBB aplicado DGR Mendonza'),
64+
('retenciones_iva', 'TXT Retenciones/Percepciones Sufridas IVA'),
6465
# ('other', 'Other')
6566
])
6667

@@ -1273,7 +1274,7 @@ def drei_aplicado_files_values(self, move_lines):
12731274
}]
12741275

12751276
def misiones_files_values(self, move_lines):
1276-
""" Implementado segun especificación indicada en ticket 51437. También se puede ver detalles en readme
1277+
""" Implementado segun especificación indicada en ticket 60295. También se puede ver detalles en readme
12771278
"""
12781279
self.ensure_one()
12791280
content = ''
@@ -1283,15 +1284,23 @@ def misiones_files_values(self, move_lines):
12831284
# Fecha
12841285
content += fields.Date.from_string(payment.date).strftime('%d-%m-%Y') + ','
12851286

1286-
# Constancia
1287-
content += payment.withholding_number[-8:] + ','
1287+
# Tipo de comprobante
1288+
# Aquí vemos si se está pagando al menos una nota de crédito
1289+
# si es así interpretamos que es corresponde a un CAR
1290+
matched_move_code_prefix = payment.payment_group_id.matched_move_line_ids.move_id.l10n_latam_document_type_id.mapped('doc_code_prefix')
1291+
is_car = False
1292+
if any(prefix[:3]=='NC-' for prefix in matched_move_code_prefix):
1293+
is_car = True
1294+
content += 'CAR' + ','
1295+
else:
1296+
content += 'CR' + ','
1297+
1298+
# Punto de Venta + Nro de Comprobante
1299+
content += payment.withholding_number.replace('-','')[:20] + ','
12881300

12891301
# Razón Social
12901302
content += payment.partner_id.name.replace(',','')[:100] + ','
12911303

1292-
# Domicilio
1293-
content += payment.partner_id.street.replace(',','')[:200] + ','
1294-
12951304
# CUIT
12961305
payment.partner_id.ensure_vat()
12971306
content += payment.partner_id.l10n_ar_formatted_vat + ','
@@ -1303,18 +1312,63 @@ def misiones_files_values(self, move_lines):
13031312
alicuot_line = line.tax_line_id.get_partner_alicuot(
13041313
line.partner_id, line.date)
13051314
if not alicuot_line:
1306-
raise ValidationError(_(
1315+
raise ValidationError(
13071316
'No hay alicuota configurada en el partner '
13081317
'"%s" (id: %s)') % (
1309-
line.partner_id.name, line.partner_id.id))
1318+
line.partner_id.name, line.partner_id.id)
13101319

13111320
content += str(line.tax_line_id.get_partner_alicuot(
1312-
line.partner_id, line.date).alicuota_retencion)
1321+
line.partner_id, line.date).alicuota_retencion) + ','
1322+
1323+
if is_car:
1324+
1325+
# Tipo de comprobante original
1326+
content += 'CR' + ','
1327+
1328+
# Comprobante que dio origen a la nota de crédito
1329+
1330+
# pago -> grupo de pagos --> nc --> factura --> grupo de pagos --> pago (con retenc misiones)
1331+
origin_invoice = payment.payment_group_id.matched_move_line_ids.move_id.reversed_entry_id
1332+
tax_withholding_id = payment.tax_withholding_id
1333+
for payment_group in origin_invoice.payment_group_ids:
1334+
cant_ret = 0
1335+
for pay_cr in payment_group.payment_ids:
1336+
if pay_cr.tax_withholding_id == tax_withholding_id:
1337+
origin_payment_cr = pay_cr
1338+
cant_ret += 1
1339+
if cant_ret != 1 or origin_payment_cr.amount != payment.amount:
1340+
raise ValidationError("Solo se admitirá un comprobante de anulación de retención referido a un solo comprobante de retención y la anulación debe ser por un importe igual al importe total de la retención original. Revisar recibo/s %s. El recibo que anula la retención es %s (id: %s)" % (origin_invoice.payment_group_ids.mapped('name'), payment.payment_group_id.name, payment.payment_group_id.id))
1341+
1342+
payment_date = payment.date
1343+
origin_payment_cr_date = origin_payment_cr.date
1344+
if (payment_date.year - origin_payment_cr_date.year) * 12 + (payment_date.month - origin_payment_cr_date.month) > 2:
1345+
raise ValidationError("Solo se admitirá un comprobante de anulación de retención para un comprobante de origen dentro de los dos períodos anteriores. Revisar recibo/s %s. El recibo que anula la retención es %s (id: %s)".format(origin_invoice.payment_group_ids.mapped('name'), payment.payment_group_id.name, payment.payment_group_id.id))
1346+
1347+
if payment_date < origin_payment_cr_date:
1348+
raise ValidationError("La fecha del comprobante de anulación de retención no puede ser anterior al de la retención que está anulando. Revisar recibo/s %s. El recibo que anula la retención es %s (id: %s)".format(origin_invoice.payment_group_ids.mapped('name'), payment.payment_group_id.name, payment.payment_group_id.id))
1349+
1350+
payment_partner_vat = payment.partner_id.ensure_vat()
1351+
origin_payment_partner_vat = origin_payment_cr.partner_id.ensure_vat()
1352+
if payment_partner_vat != origin_payment_partner_vat:
1353+
raise ValidationError("Deben coincidir los CUIT emisores del comprobante de anulación de retención y del comprobante de retención original. Revisar recibo/s %s. El recibo que anula la retención es %s (id: %s)".format(origin_invoice.payment_group_ids.mapped('name'), payment.payment_group_id.name, payment.payment_group_id.id))
1354+
1355+
# Nro de comprobante que dio origen a la nota de crédito
1356+
content += origin_payment_cr.withholding_number.replace('-','')[:20] + ','
1357+
1358+
# Fecha del comprobante que dio origen a la nota de crédito
1359+
content += origin_payment_cr.date.strftime('%d-%m-%Y') + ','
1360+
1361+
# CUIT del comprobante que dio origen a la nota de crédito
1362+
partner_vat = origin_payment_cr.partner_id.ensure_vat()
1363+
content += partner_vat
1364+
else:
1365+
content += ',,,'
13131366

13141367
content += '\n'
13151368
elif line.move_id.is_invoice():
13161369
# Fecha
1317-
content += line.move_id.invoice_date.strftime('%d-%m-%Y') + ','
1370+
invoice_date = line.move_id.invoice_date
1371+
content += invoice_date.strftime('%d-%m-%Y') + ','
13181372

13191373
# Tipo de comprobante
13201374
content += line.move_id.l10n_latam_document_type_id.doc_code_prefix.replace('-','_') + ','
@@ -1326,13 +1380,11 @@ def misiones_files_values(self, move_lines):
13261380
content += line.move_id.partner_id.name[:100] + ','
13271381

13281382
# CUIT
1329-
content += line.move_id.partner_id.ensure_vat() + ','
1383+
partner_vat = line.move_id.partner_id.ensure_vat()
1384+
content += partner_vat + ','
13301385

13311386
# Importe de la operación, consultar si l10n_latam_price_net es correcto
1332-
tax_group_id = line.tax_line_id.tax_group_id.id
1333-
for x in line.move_id.amount_by_group:
1334-
if x[-1] == tax_group_id:
1335-
content += str(x[2]) + ','
1387+
content += str(abs(line.balance)) + ','
13361388

13371389
# Alícuota
13381390
alicuot_line = line.tax_line_id.get_partner_alicuot(
@@ -1344,9 +1396,99 @@ def misiones_files_values(self, move_lines):
13441396
line.partner_id.name, line.partner_id.id))
13451397
content += str(line.tax_line_id.get_partner_alicuot(line.partner_id, line.date).alicuota_percepcion)
13461398

1399+
if line.move_id.l10n_latam_document_type_id.doc_code_prefix[:3] == 'NC-':
1400+
1401+
# Comprobante de origen
1402+
origin_invoice = line.move_id.reversed_entry_id
1403+
1404+
# CUIT del partner del comprobante de origen
1405+
partner_vat_origin_invoice = origin_invoice.partner_id.ensure_vat()
1406+
1407+
# Fecha del comprobante original
1408+
date_origin_invoice = origin_invoice.invoice_date
1409+
1410+
if (invoice_date.year - date_origin_invoice.year) * 12 + (invoice_date.month - date_origin_invoice.month) > 2:
1411+
raise ValidationError("Solo se admitirá una NC para un comprobante de origen dentro de los dos períodos anteriores, revisar %s (id: %s) asociado a la factura %s (id: %s)" % (line.move_id.name, line.move_id.id, origin_invoice.name, origin_invoice.id))
1412+
1413+
if invoice_date < date_origin_invoice:
1414+
raise ValidationError("La fecha de la NC no podrá ser anterior a la fecha del comprobante de origen, revisar %s (id: %s) asociado a la factura %s (id: %s)" % (line.move_id.name, line.move_id.id, origin_invoice.name, origin_invoice.id))
1415+
1416+
if partner_vat != partner_vat_origin_invoice:
1417+
raise ValidationError("Deben coincidir los CUIT emisores de la NC y del comprobante original, revisar: %s (id: %s) asociado a la factura %s (id: %s)" % (line.move_id.name, line.move_id.id, origin_invoice.name, origin_invoice.id))
1418+
1419+
# Tipo de comprobante original
1420+
content += ',' + origin_invoice.l10n_latam_document_type_id.doc_code_prefix.replace('-','_') + ','
1421+
1422+
# Nro de comprobante original
1423+
content += origin_invoice.l10n_latam_document_number.replace('-','')[:20] + ','
1424+
1425+
# Fecha de comprobante original
1426+
content += date_origin_invoice.strftime('%d-%m-%Y') + ','
1427+
1428+
# CUIT de comprobante original
1429+
content += partner_vat_origin_invoice
1430+
else:
1431+
content += ',,,,'
1432+
13471433
content += '\n'
13481434

13491435
return [{
13501436
'txt_filename': ('Retenciones ' if payment else 'Percepciones ') + 'Misiones.txt',
13511437
'txt_content': content,
13521438
}]
1439+
1440+
def retenciones_iva_files_values(self, move_lines):
1441+
""" Implementado segun especificación indicada en ticket 54274."""
1442+
self.ensure_one()
1443+
content = ''
1444+
for line in move_lines.sorted(key=lambda r: (r.date, r.id)):
1445+
payment = line.payment_id
1446+
if payment:
1447+
# regimen (long 3)
1448+
codigo_regimen = payment.tax_withholding_id.codigo_regimen
1449+
if not codigo_regimen:
1450+
raise ValidationError(_('No hay código de régimen en la configuración del impuesto "%s"') % (
1451+
payment.tax_withholding_id.name))
1452+
if len(codigo_regimen) < 3:
1453+
raise ValidationError(_('El código de régimen tiene que tener 3 dígitos en la configuración del impuesto "%s"') % (payment.tax_withholding_id.name))
1454+
content += codigo_regimen[:3]
1455+
1456+
# cuit agente (long 11)
1457+
content += payment.partner_id.ensure_vat()
1458+
1459+
# fecha retención (long 10)
1460+
content += fields.Date.from_string(payment.date).strftime('%d/%m/%Y')
1461+
1462+
# número comprobante (long 16)
1463+
content += re.sub('[^0-9\.]', '', payment.withholding_number).ljust(16)
1464+
1465+
# importe retención (long 16)
1466+
content += '%16.2f' % payment.amount
1467+
content += '\r\n'
1468+
elif line.move_id.is_invoice():
1469+
# regimen (long 3)
1470+
codigo_regimen = line.tax_line_id.codigo_regimen
1471+
if not codigo_regimen:
1472+
raise ValidationError(_('No hay código de régimen en la configuración del impuesto "%s"') % (
1473+
line.tax_line_id.name))
1474+
if len(codigo_regimen) < 3:
1475+
raise ValidationError(_('El código de régimen tiene que tener 3 dígitos en la configuración del impuesto "%s"') % (line.tax_line_id.name))
1476+
content += codigo_regimen[:3]
1477+
1478+
# cuit agente (long 11)
1479+
content += line.move_id.partner_id.ensure_vat()
1480+
1481+
# fecha retención (long 10)
1482+
content += fields.Date.from_string(line.move_id.invoice_date).strftime('%d/%m/%Y')
1483+
1484+
# número comprobante (long 16)
1485+
content += line.move_id.l10n_latam_document_number.ljust(16)
1486+
1487+
# importe retención (long 16)
1488+
content += '%16.2f' % line.balance
1489+
content += '\r\n'
1490+
1491+
return [{
1492+
'txt_filename': ('Retenciones' if payment else 'Percepciones') + '_iva.txt',
1493+
'txt_content': content,
1494+
}]

0 commit comments

Comments
 (0)