Skip to content

Commit

Permalink
[IMP] l10n_ar_txt_mendoza: last changes
Browse files Browse the repository at this point in the history
  • Loading branch information
pablohmontenegro committed Oct 29, 2024
1 parent f3e192c commit 327b599
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 246 deletions.
2 changes: 1 addition & 1 deletion l10n_ar_account_tax_settlement/models/account_journal.py
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,7 @@ def iibb_aplicado_sircar_files_values(self, move_lines):
line_nbr = 1
for line in move_lines.filtered('payment_id'):
alicuot_line = line.tax_line_id.get_partner_alicuot(
line.partner_id, line.date)
line.partner_id, line.date, line)
if not alicuot_line:
raise ValidationError(_(
'No hay alicuota configurada en el partner '
Expand Down
2 changes: 1 addition & 1 deletion l10n_ar_txt_mendoza/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
],
'installable': True,
'auto_install': False,
'application': True,
'application': False,
}
1 change: 1 addition & 0 deletions l10n_ar_txt_mendoza/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
from . import res_company
from . import account_payment_group
from . import account_payment
from . import account_tax
from . import account_journal
266 changes: 22 additions & 244 deletions l10n_ar_txt_mendoza/models/account_journal.py
Original file line number Diff line number Diff line change
@@ -1,252 +1,30 @@
from odoo import models, fields, _
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError, RedirectWarning
from odoo.tools.float_utils import float_round
# from odoo.tools.misc import formatLang
# from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
import re

#########
# helpers
#########


def format_amount(amount, padding=15, decimals=2, sep=""):
if amount < 0:
template = "-{:0>%dd}" % (padding - 1 - len(sep))
else:
template = "{:0>%dd}" % (padding - len(sep))
res = template.format(
int(round(abs(amount) * 10**decimals, decimals)))
if sep:
res = "{0}{1}{2}".format(res[:-decimals], sep, res[-decimals:])
return res


def get_line_tax_base(move_line):
return sum(move_line.move_id.line_ids.filtered(
lambda x: move_line.tax_line_id in x.tax_ids).mapped(
'balance'))


def get_pos_and_number(full_number):
"""
Para un numero nos fijamos si hay '-', si hay:
* mas de 1, entonces devolvemos error
* 1, entonces devolvemos las partes (solo parte númerica)
* 0, entonces devolvemos '0' y parte númerica del número que se pasó
"""
args = full_number.split('-')
if len(args) == 1:
# si no hay '-' tomamos punto de venta 0
return ('0', re.sub('[^0-9]', '', args[0]))
else:
return re.sub('[^0-9]', '', args[0]), re.sub('[^0-9]', '', ''.join(args[1:]))


class AccountJournal(models.Model):
_inherit = 'account.journal'

def iibb_aplicado_sircar_files_values(self, move_lines):
""" Especificacion en /doc/sircar, solicitado en ticket 62526. Método heredado de https://github.com/ingadhoc/odoo-argentina-ee/blob/16.0/l10n_ar_account_tax_settlement/models/account_journal.py#L840
""" Extendemos este método del original de l10n_ar_account_tax_settlement para mendoza. El objetivo de este método es validar que el impuesto de mendoza tenga código de régimen.
"""
self.ensure_one()
ret = ''
perc = ''

for line in move_lines.filtered(
lambda x: not x.payment_id and not x.move_id):
raise ValidationError(_(
'Hay lineas a liquidar que no estan enlazadas a pagos ni '
'facturas lo cual es requerido para generar el TXT'))

line_nbr = 1
for line in move_lines.filtered('payment_id'):
alicuot_line = line.tax_line_id.get_partner_alicuot(
line.partner_id, line.date) if not line.tax_line_id.withholding_type == 'code' else line.payment_id.alicuota_mendoza * 100

if not isinstance(alicuot_line, float) and not alicuot_line:
raise ValidationError(_(
'No hay alicuota configurada en el partner '
'"%s" (id: %s)') % (
line.partner_id.name, line.partner_id.id))

payment = line.payment_id
internal_type = line.l10n_latam_document_type_id.internal_type

# 1 Número de Renglón (único por archivo)
content = []
content.append('%05d' % line_nbr)

# 2 Origen del Comprobante
content.append('1')

# 3 Tipo del Comprobante
if payment.payment_type == 'outbound':
content.append('1')
else:
content.append('2')

# 4 Número del comprobante
content.append('%012d' % int(
re.sub('[^0-9]', '', line.payment_id.withholding_number or '')))

# 5 Cuit del contribuyene
content.append(line.partner_id.ensure_vat())

# 6 Fecha de la percepción
content.append(
fields.Date.from_string(line.date).strftime('%d/%m/%Y'))

# 7 Monto sujeto a percepción
content.append(format_amount(
payment.withholdable_base_amount, 12, 2, '.'))

# 8 alicuota de la retencion
content.append(format_amount(
alicuot_line.alicuota_retencion if not isinstance(alicuot_line, float) else alicuot_line, 6, 2, '.'))

# 9 Monto retenido
content.append(format_amount(-line.balance, 12, 2, '.'))

# 10 Tipo de Régimen de Percepción
# (código correspondiente según tabla definida por la jurisdicción)
if not isinstance(alicuot_line, float) and not alicuot_line.regimen_retencion:
raise ValidationError(_(
'No hay regimen de retencion configurado para la alícuota'
' del partner %s') % line.partner_id.name)
elif not line.tax_line_id.codigo_regimen:
raise RedirectWarning(
message=_("El impuesto '%s' not tiene código de regimen en solapa 'Opciones avanzadas' campo 'Codigo de regimen'.", line.tax_line_id.name),
action={
'type': 'ir.actions.act_window',
'res_model': 'account.tax',
'views': [(False, 'form')],
'res_id': line.tax_line_id.id,
'name': _('Tax'),
'view_mode': 'form',
},
button_text=_('Editar Impuesto'),
)
content.append(alicuot_line.regimen_retencion if not isinstance(alicuot_line, float) else line.tax_line_id.codigo_regimen)

# 11 Jurisdicción: código en Convenio Multilateral de la
# jurisdicción a la cual está presentando la DDJJ
if not line.tax_line_id.jurisdiction_code:
raise ValidationError(_(
'No hay etiqueta de jurisdicción configurada!'))

content.append(line.tax_line_id.jurisdiction_code)

# Tipo registro 2. Provincia Cordoba
if line.tax_line_id.jurisdiction_code in ['904', '914']:

# 12 Tipo de Operación (1-Efectuada, 2-Anulada, 3-Omitida)
content.append('2' if internal_type == 'credit_note' else '1')

# 13 Fecha de Emisión de Constancia (en formato dd/mm/aaaa)
content.append(fields.Date.from_string(line.date).strftime('%d/%m/%Y'))

# 14 Número de Constancia - Numeric(14)
content.append('%014s' % int(re.sub('[^0-9]', '', payment.withholding_number or '0')[:14]))

# 15 Número de Constancia original (sólo para las Anulaciones –ver códigos por jur-) - Numeric(14)
original_invoice = line.move_id._found_related_invoice() or line.move_id
content.append('%014d' % int(re.sub('[^0-9]', '', original_invoice.document_number or ''))
if internal_type == 'credit_note' else '%014d' % 0)

ret += ','.join(content) + '\r\n'
line_nbr += 1

line_nbr = 1
for line in move_lines.filtered(lambda x: x.move_id.is_invoice()):
alicuot_line = line.tax_line_id.get_partner_alicuot(
line.partner_id, line.date)
if not alicuot_line:
raise ValidationError(_(
'No hay alicuota configurada en el partner '
'"%s" (id: %s)') % (
line.partner_id.name, line.partner_id.id))


# 1 Número de Renglón (único por archivo)
content = []
content.append('%05d' % line_nbr)

letter = line.l10n_latam_document_type_id.l10n_ar_letter

# 2 Tipo de comprobante
internal_type = line.l10n_latam_document_type_id.internal_type
if internal_type == 'invoice':
tipo_comprobante = letter == 'E' and 5 or 1
elif internal_type == 'credit_note':
tipo_comprobante = letter == 'E' and 106 or 102
elif internal_type == 'debit_note':
tipo_comprobante = letter == 'E' and 6 or 2
elif line.move_id.type == 'out_invoice':
tipo_comprobante = 20
elif line.move_id.type == 'out_refund':
tipo_comprobante = 120
else:
raise ValidationError(_('Tipo de comprobante no reconocido'))
content.append('%03d' % tipo_comprobante)

# 3 Letra del comprobante
content.append(line.l10n_latam_document_type_id.l10n_ar_letter)

# 4 Número del comprobante
content.append('%012d' % int(
re.sub('[^0-9]', '', line.move_id.l10n_latam_document_number or '')))

# 5 Cuit del contribuyene
content.append(line.partner_id.ensure_vat())

# 6 Fecha de la percepción
content.append(
fields.Date.from_string(line.date).strftime('%d/%m/%Y'))

# 7 Monto sujeto a percepción
content.append(format_amount(-get_line_tax_base(line), 12, 2, '.'))

# 8 alicuota de la percepcion
content.append(format_amount(
alicuot_line.alicuota_percepcion, 6, 2, '.'))

# 9 Monto percibido
content.append(format_amount(-line.balance, 12, 2, '.'))

# 10 Tipo de Régimen de Percepción
# (código correspondiente según tabla definida por la jurisdicción)
if not alicuot_line.regimen_percepcion:
raise ValidationError(_(
'No hay regimen de percepcion configurado para la alícuota'
' del partner %s') % line.partner_id.name)
content.append(alicuot_line.regimen_percepcion)

# 11 Jurisdicción: código en Convenio Multilateral de la
# jurisdicción a la cual está presentando la DDJJ
if not line.tax_line_id.jurisdiction_code:
raise ValidationError(_(
'No hay etiqueta de jurisdicción configurada!'))

content.append(line.tax_line_id.jurisdiction_code)

# Tipo registro 2. Provincia Cordoba
if line.tax_line_id.jurisdiction_code in ['904', '914']:

# 12 Tipo de Operación (1-Efectuada, 2-Anulada, 3-Omitida, 4-Informativa)
content.append('2' if internal_type == 'credit_note' else '1')

# 13 Número de Constancia original (sólo para 2-Anulaciones) Alfanumérico (14) - ejemplo 1A002311312221
content.append(self._get_perception_original_invoice_number(line)
if internal_type == 'credit_note' else '%014d' % 0)

perc += ','.join(content) + '\r\n'
line_nbr += 1

return [
{
'txt_filename': 'Perc IIBB Aplicadas para SIRCAR.txt',
'txt_content': perc,
},
{
'txt_filename': 'Ret IIBB Aplicadas para SIRCAR.txt',
'txt_content': ret,
}]

tax_group_id_mendoza_id = self.env.ref('l10n_ar_ux.tax_group_retencion_iibb_za')
mendoza_lines = move_lines.filtered(lambda x: x.payment_id and x.tax_line_id.withholding_type == 'code' and x.tax_group_id == tax_group_id_mendoza_id)
missing_codigo_regimen = mendoza_lines.filtered(lambda x: not x.payment_id.tax_withholding_id.codigo_regimen)
if mendoza_lines and missing_codigo_regimen:
raise RedirectWarning(
message=_("El impuesto '%s' not tiene código de regimen en solapa 'Opciones avanzadas' campo 'Codigo de regimen'.", missing_codigo_regimen.payment_id.tax_withholding_id.name),
action={
'type': 'ir.actions.act_window',
'res_model': 'account.tax',
'views': [(False, 'form')],
'res_id': mendoza_lines.tax_line_id.id,
'name': _('Tax'),
'view_mode': 'form',
},
button_text=_('Editar Impuesto'),
)
return super().iibb_aplicado_sircar_files_values(move_lines)
15 changes: 15 additions & 0 deletions l10n_ar_txt_mendoza/models/account_tax.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from odoo import models, fields, api, _
from odoo.exceptions import UserError
from dateutil.relativedelta import relativedelta


class AccountTax(models.Model):
_inherit = "account.tax"

def get_partner_alicuot(self, partner, date, line=None):
""" La alícuota para el archivo txt de mendoza que se genera desde el método iibb_aplicado_sircar_files_values no se obtiene del partner sino que se obtiene del payment, y el código de régimen se obtiene del impuesto pero extendemos el método get_partner_alicuot original para usarlo como puente, agregamos 'line' como parámentro. """
if line.payment_id.alicuota_mendoza and line.payment_id.tax_withholding_id.codigo_regimen:
aliquot = self.env['res.partner.arba_alicuot'].new({'alicuota_retencion': line.payment_id.alicuota_mendoza * 100, 'partner_id': partner, 'regimen_retencion': line.payment_id.tax_withholding_id.codigo_regimen})
else:
aliquot = super().get_partner_alicuot(partner, date)
return aliquot

0 comments on commit 327b599

Please sign in to comment.