Created
March 6, 2023 07:31
-
-
Save mamfredym/1de7d18e3c3c89d2c57b01d0107274df to your computer and use it in GitHub Desktop.
Odoo | Reporte TXT Superintendencia de Bancos Ventas a Crédito (a.k.a. Dinardap)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
from odoo import api, fields, models, _ | |
from odoo.exceptions import UserError | |
import base64 | |
import calendar | |
class L10nEcSuperbancosSalesReportWizard(models.TransientModel): | |
_name = 'ln10_ec.superbancos.sales.wizard' | |
_description = 'Credit Sales' | |
date = fields.Date("Date", required=True) | |
company_id = fields.Many2one("res.company", "Company", default=lambda self: self.env.company, required=True) | |
txt_file = fields.Binary(string='Download') | |
name = fields.Char(string='Filename', size=64) | |
@api.constrains("date") | |
def _validate_date(self): | |
for report in self : | |
daysinmonth = calendar.monthrange(report.date.year, report.date.month)[1] | |
if report.date.day != daysinmonth : | |
raise UserError(_(u'Please select the last day of month')) | |
# XML FILE REPORT | |
def button_generate_txt(self): | |
self.ensure_one() | |
filename = self.company_id.vat + str(self.date.day).zfill(2) + str(self.date.month).zfill(2) + str(self.date.year) + ".txt" | |
txt_content = self._l10n_generate_superbancos_data() | |
self.write({'name': filename, | |
'txt_file': base64.b64encode(txt_content.encode())}) | |
return { | |
'type': 'ir.actions.act_url', | |
'name': filename, | |
'url': '/web/content/%s/%s/txt_file/%s?download=true' %(self._name, self.id, filename), | |
} | |
def _generate_detail_record(self, invoice): | |
#VALIDATIONS | |
self._validate_address_partner(invoice.partner_id) | |
self._validate_nutural_data_partner(invoice.partner_id) | |
#DATA | |
control = [] | |
control.append("{:1.7}".format(self.company_id.l10n_ec_superbancos_entity_code.strip())) | |
control.append(self.date.strftime("%d/%m/%Y")) | |
control.append("{:1.1}".format(self._get_partner_identification_type(invoice.partner_id))) | |
control.append("{:1.20}".format(invoice.partner_id.commercial_partner_id.vat.strip())) | |
control.append("{:1.100}".format(invoice.partner_id.commercial_partner_id.name.strip())) | |
control.append("{:1.1}".format(self._get_partner_type(invoice.partner_id))) | |
control.append("{:2.2}".format(invoice.partner_id.commercial_partner_id.state_id.code.strip()[-2:])) | |
control.append("{:2.2}".format(invoice.partner_id.commercial_partner_id.city_id.zipcode.strip()[-2:])) | |
control.append("{:2.2}".format(invoice.partner_id.commercial_partner_id.parish_id.zip.strip()[-2:])) | |
control.append("{:.1}".format(invoice.partner_id.commercial_partner_id.l10n_ec_partner_type == '01' and invoice.partner_id.commercial_partner_id.l10n_ec_sex or '')) | |
control.append("{:.1}".format(invoice.partner_id.commercial_partner_id.l10n_ec_partner_type == '01' and invoice.partner_id.commercial_partner_id.l10n_ec_marital_status or '')) | |
control.append("{:.1}".format(invoice.partner_id.commercial_partner_id.l10n_ec_partner_type == '01' and invoice.partner_id.commercial_partner_id.l10n_ec_income_origin or '')) | |
control.append("{:1.32}".format(invoice.l10n_ec_document_number)) #INVOICE NUMBER | |
control.append("{:.2f}".format(invoice.amount_total)) | |
control.append("{:.2f}".format(invoice.amount_residual)) | |
control.append(invoice.invoice_date.strftime("%d/%m/%Y")) | |
control.append(invoice.invoice_date_due.strftime("%d/%m/%Y")) | |
control.append(invoice.invoice_date_due.strftime("%d/%m/%Y")) #THE SAME DATE DUE | |
control.append("{}".format(min(self._compute_days_between_dates(invoice.invoice_date, invoice.invoice_date_due),99999))) | |
control.append("{}".format(min(self._compute_days_between_dates(invoice.invoice_date, invoice.invoice_date_due),99999))) #THE SAME DAYS | |
#DAYS CALCULATION | |
days_due = self._compute_days_between_dates(invoice.invoice_date_due, self.date) | |
control.append("{}".format(min((days_due if days_due > 0 else 0),99999))) | |
control.append("{:.2f}".format(invoice.amount_residual if days_due > 0 else 0.0)) | |
control.append("{:.2f}".format(0.0)) | |
#NOT DUE | |
control.append("{:.2f}".format(invoice.amount_residual) if days_due <= -1 and days_due >= -30 else "0.00") | |
control.append("{:.2f}".format(invoice.amount_residual) if days_due <= -31 and days_due >= -90 else "0.00") | |
control.append("{:.2f}".format(invoice.amount_residual) if days_due <= -91 and days_due >= -180 else "0.00") | |
control.append("{:.2f}".format(invoice.amount_residual) if days_due <= -181 and days_due >= -360 else "0.00") | |
control.append("{:.2f}".format(invoice.amount_residual) if days_due <= -361 else "0.00") | |
#DUE | |
control.append("{:.2f}".format(invoice.amount_residual) if days_due >= 1 and days_due <= 30 else "0.00") | |
control.append("{:.2f}".format(invoice.amount_residual) if days_due >= 31 and days_due <= 90 else "0.00") | |
control.append("{:.2f}".format(invoice.amount_residual) if days_due >= 91 and days_due <= 180 else "0.00") | |
control.append("{:.2f}".format(invoice.amount_residual) if days_due >= 181 and days_due <= 360 else "0.00") | |
control.append("{:.2f}".format(invoice.amount_residual) if days_due >= 361 else "0.00") | |
control.append("{:.2f}".format(0.0)) | |
control.append("{:.2f}".format(0.0)) | |
control.append("{:.2f}".format(invoice.amount_residual)) | |
control.append("{:.1}".format('')) | |
control.append("{:.1}".format('')) | |
return "|".join(control) | |
def _l10n_generate_superbancos_data(self): | |
for report in self: | |
#ToDo: AÑADIR EN EL SEARCH UN FILTRO PARA SACAR SOLO LAS VENTAS CREDITO | |
#QUE LA FECHA DE FACT SEA DIFERENTE A LA DE VENCIMIENTO (VENTAS CREDITO) | |
invoices = self.env['account.move'].search([ | |
('move_type','=','out_invoice'), | |
('state','=','posted'), | |
('invoice_date','<', report.date), | |
('payment_state', 'in', ('not_paid', 'partial')) | |
]) | |
company = report.company_id | |
#DATA VALIDATION FOR SUPERBANCOS INFOMATION IN res_company | |
if not company.l10n_ec_superbancos_entity_code : | |
raise UserError(_("Entity Code Company is not defined!")) | |
if not company.l10n_ec_superbancos_min_vale : | |
raise UserError(_("Minimum Amount Company is not defined!")) | |
entries = [] | |
for invoice in invoices : | |
if invoice.invoice_date != invoice.invoice_date_due and invoice.partner_id.commercial_partner_id.country_id.code == 'EC' : | |
entries.append(report._generate_detail_record(invoice)) | |
return "\r\n".join(entries) | |
#UTILS DATA | |
@api.model | |
def _get_partner_identification_type(self, partner_id): | |
it_ruc = self.env.ref("l10n_ec_base.ec_ruc", False) | |
it_dni = self.env.ref("l10n_ec_base.ec_dni", False) | |
return (partner_id.commercial_partner_id.l10n_latam_identification_type_id.id == it_ruc.id and 'R') or (partner_id.commercial_partner_id.l10n_latam_identification_type_id.id == it_dni.id and 'C') or 'E' | |
@api.model | |
def _get_partner_type(self, partner_id): | |
return (partner_id.commercial_partner_id.l10n_ec_partner_type == '01' and 'N') or (partner_id.commercial_partner_id.l10n_ec_partner_type == '02' and 'J') or '' | |
@api.model | |
def _compute_days_between_dates(self, date_start, date_end): | |
start_date = fields.Date.from_string(date_start) | |
end_date = fields.Date.from_string(date_end) | |
return (end_date - start_date).days | |
#DATA VALIDATIONS | |
@api.model | |
def _validate_address_partner(self, partner_id): | |
if (not partner_id.commercial_partner_id.country_id or | |
not partner_id.commercial_partner_id.state_id or | |
not partner_id.commercial_partner_id.city_id or | |
not partner_id.commercial_partner_id.parish_id): | |
raise UserError(_(u'Country, State, City, Parish not established in %s') % (partner_id.commercial_partner_id.name)) | |
return True | |
@api.model | |
def _validate_nutural_data_partner(self, partner_id): | |
if partner_id.commercial_partner_id.l10n_ec_partner_type == '01' : | |
if (not partner_id.commercial_partner_id.l10n_ec_sex or | |
not partner_id.commercial_partner_id.l10n_ec_marital_status or | |
not partner_id.commercial_partner_id.l10n_ec_income_origin ): | |
raise UserError(_(u'Sex, Marital Status, Income Origin, Parish not established in %s') % (partner_id.commercial_partner_id.name)) | |
return True |
Ficha Técnica descargada desde la Superintendencia de Bancos
Guias:
Manuales de Reporte (Superintendencia de Bancos)
Descarga:
MANUAL TÉCNICO TRANSFERENCIA DE INFORMACIÓN DE VENTAS A CRÉDITO DE LAS COMPAÑÍAS
Versión: 2.1
Actualizado a: 30/12/2022
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
CONSIDERACIONES
res_company debe contener los siguientes campos:
res_partner debe contener los siguientes campos:
Para el número de Factura o documento estoy usando el campo l10n_ec_document_number, este campo es un campo personal considerar usar el campo name si es que lo tienen o el que el tenga cada quien.