| REPOSITORY | |
|---|---|
| REPOSITORY | OCA/l10n-paraguay |
| GIT | |
| GIT | https://github.com/OCA/l10n-paraguay.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/OCA/l10n-paraguay/tree/16.0/l10n_py_edi_base |
| VERSION | |
| VERSION | 3.0.0 |
| CATEGORY | |
| CATEGORY | Accounting/Localizations/EDI |
| LICENSE | |
| LICENSE | LGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | No |
| AUTHORS | |
| AUTHORS | Odoo Community Association (OCA), KMEE |
| MAINTAINERS | |
| MAINTAINERS | Odoo Community Association (OCA), KMEE |
| COMMITTERS | |
| COMMITTERS | mileo, OCA-git-bot, oca-ci |
| WEBSITE | |
| WEBSITE | https://github.com/OCA/l10n-paraguay |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-06 19:12:07 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
OCA/l10n-paraguay: - l10n_py_base - l10n_py_account - l10n_py odoo/odoo: - account - base_setup - base - web - product - bus - web_tour - uom - analytic - portal - web_editor - http_routing - auth_signup - digest - resource - base_address_extended - l10n_latam_base - contacts - base_vat - l10n_latam_invoice_document - account_debit_note |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES |
cryptography pykude qrcode requests num2words |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | # Paraguay - Electronic Invoicing Base This module provides the base functionality for electronic invoicing (facturación electrónica) in Paraguay, compliant with SET (Subsecretaría de Estado de Tributación) requirements. ## Features ### Document Types Support - **Factura Electrónica**: Electronic invoice - **Nota de Crédito Electrónica**: Electronic credit note - **Nota de Débito Electrónica**: Electronic debit note - **Nota de Remisión Electrónica**: Electronic delivery note - **Autofactura Electrónica**: Electronic self-invoice ### Core Functionality - **Data Models**: Complete models for electronic documents - **Field Extensions**: Enhanced account.move, res.partner, and res.company - **Fiscal Validation**: RUC and DV validation - **JSON Builder**: Automatic generation of JSON for SIFEN - **QR Code Generation**: Ready for KUDE (Código Único de Documento Electrónico) - **Log System**: Complete audit trail of EDI operations ### Compliance - **SIFEN Compatible**: Sistema Integrado de Facturación Electrónica Nacional - **SET Requirements**: Meets all SET regulatory requirements - **Contingency Mode**: Support for offline operation - **KUDE Support**: Ready for electronic document codes ### Integration Ready This is a base module that requires a connector: - `l10n_py_edi_factpy`: FactPy integration - `l10n_py_edi_facturasend`: FacturaSend integration ## Technical Architecture - **Provider-agnostic**: Works with multiple EDI providers - **Extensible**: Easy to add new document types - **Robust**: Error handling and retry mechanisms - **Auditable**: Complete logging of all operations ## Dependencies - `account`: Core accounting - `l10n_py_base`: Base Paraguayan localization - `l10n_py_account`: Accounting extensions (timbrado management) - `product`: Product management - `sale`: Sales management |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
kude_report_template |
kude_report_template | ir.ui.view | qweb | New |
view_account_move_send_edi_wizard |
account.move.send.edi.wizard.form | account.move.send.edi.wizard | form | New |
view_company_form_edi |
res.company.form.edi | res.company | xpath | Inherits base.view_company_form |
view_edi_connector_form |
l10n_py.edi.connector.form | l10n_py.edi.connector | form | New |
view_edi_connector_tree |
l10n_py.edi.connector.tree | l10n_py.edi.connector | tree | New |
view_l10n_py_associated_document_tree |
l10n_py.associated.document.tree | l10n_py.associated.document | tree | New |
view_l10n_py_edi_cancel_wizard |
l10n_py.edi.cancel.wizard.form | l10n_py.edi.cancel.wizard | form | New |
view_l10n_py_edi_log_form |
l10n_py.edi.log.form | l10n_py.edi.log | form | New |
view_l10n_py_edi_log_tree |
l10n_py.edi.log.tree | l10n_py.edi.log | tree | New |
view_l10n_py_number_inutilization_form |
l10n_py.number.inutilization.form | l10n_py.number.inutilization | form | New |
view_l10n_py_number_inutilization_tree |
l10n_py.number.inutilization.tree | l10n_py.number.inutilization | tree | New |
view_l10n_py_transport_form |
l10n_py.transport.form | l10n_py.transport | form | New |
view_l10n_py_transport_tree |
l10n_py.transport.tree | l10n_py.transport | tree | New |
view_move_form_edi |
account.move.form.edi | account.move | xpath | Inherits account.view_move_form |
view_product_template_form_edi |
product.template.form.edi | product.template | xpath | Inherits product.product_template_form_view |
l10n_py_afe_constancia_control
Char
size=20
string='Número de Control (EA005)'
l10n_py_afe_constancia_number
Char
size=20
string='Número de Constancia (EA004)'
l10n_py_afe_constancia_type
Selection
string='Tipo de Constancia (EA002)'
args: [('1', 'No contribuyente'), ('2', 'Microproductor')]
l10n_py_afe_provision_address
Char
string='Dirección Provisión (EA018)'
l10n_py_afe_provision_city
Integer
string='Ciudad Provisión (EA023)'
l10n_py_afe_provision_department
Integer
string='Departamento Provisión (EA019)'
l10n_py_afe_provision_district
Integer
string='Distrito Provisión (EA021)'
l10n_py_afe_vendor_address
Char
string='Dirección Vendedor (EA010)'
l10n_py_afe_vendor_city
Integer
string='Ciudad Vendedor (EA016)'
l10n_py_afe_vendor_department
Integer
string='Departamento Vendedor (EA012)'
l10n_py_afe_vendor_district
Integer
string='Distrito Vendedor (EA014)'
l10n_py_afe_vendor_doc_number
Char
size=20
string='Nro. Doc. Vendedor (EA008)'
l10n_py_afe_vendor_doc_type
Selection
string='Tipo Doc. Vendedor (EA006)'
args: [('1', 'Cédula paraguaya'), ('2', 'Pasaporte'), ('3', 'Cédula extranjera'), ('4', 'Carnet de residencia')]
l10n_py_afe_vendor_house
Integer
string='Nro. Casa Vendedor (EA011)'
l10n_py_afe_vendor_name
Char
string='Nombre Vendedor (EA009)'
l10n_py_associated_document_ids
One2many → l10n_py.associated.document
help='Documentos asociados al DTE (Grupo H del SIFEN)'
string='Documentos Asociados'
args: 'l10n_py.associated.document', 'move_id'
l10n_py_cdc
Char
copy=False
help='Código de Control del documento electrónico'
readonly=True
args: 'CDC'
l10n_py_contingency_motive
Char
l10n_py_doc_type_code
Char
compute='_compute_l10n_py_doc_type_code'
l10n_py_edi_batch_id
Char
copy=False
readonly=True
args: 'ID de Lote'
l10n_py_edi_message
Text
copy=False
readonly=True
args: 'Mensaje EDI'
l10n_py_edi_status
Selection
copy=False
default='draft'
readonly=True
string='Estado EDI'
args: [('draft', 'Borrador'), ('to_send', 'Para Enviar'), ('sent', 'Enviado'), ('processing', 'Procesando'), ('accepted', 'Aceptado'), ('rejected', 'Rechazado'), ('cancelled', 'Cancelado'), ('error', 'Error')]
l10n_py_edi_xml
Binary
copy=False
readonly=True
args: 'XML Firmado'
l10n_py_edi_xml_filename
Char
readonly=True
args: 'XML Filename'
l10n_py_emission_type
Selection
default='1'
required=True
string='Tipo de Emisión'
args: [('1', 'Normal'), ('2', 'Contingencia')]
l10n_py_exchange_rate_condition
Selection
default='1'
help='Condición del tipo de cambio (D015)'
string='Condición Tipo de Cambio'
args: [('1', 'Global'), ('2', 'Por Ítem')]
l10n_py_kude_filename
Char
readonly=True
args: 'KUDE Filename'
l10n_py_kude_pdf
Binary
copy=False
readonly=True
args: 'KUDE (PDF)'
l10n_py_nre_estimated_invoice_date
Date
help='Fecha estimada de facturación para NRE sin factura asociada'
string='Fecha Estimada de Facturación (E506)'
l10n_py_nre_motive
Selection
string='Motivo de Remisión (E501)'
args: [('1', 'Traslado por venta'), ('2', 'Traslado por consignación'), ('3', 'Traslado por exportación'), ('4', 'Traslado por importación'), ('5', 'Traslado entre locales'), ('6', 'Otros')]
l10n_py_payment_type
Selection
default='1'
help='Tipo de pago para condición contado (E606)'
string='Tipo de Pago'
args: [('1', 'Efectivo'), ('2', 'Cheque'), ('3', 'Tarjeta de crédito'), ('4', 'Tarjeta de débito'), ('5', 'Transferencia'), ('6', 'Giro'), ('7', 'Billetera electrónica'), ('8', 'Tarjeta empresarial'), ('9', 'Vale'), ('10', 'Retención'), ('11', 'Anticipo'), ('12', 'Valor fiscal'), ('13', 'Valor comercial'), ('14', 'Compensación'), ('15', 'Permuta'), ('16', 'Pago bancario')]
l10n_py_presence_type
Selection
default='1'
string='Tipo de Presencia'
args: [('1', 'Operación presencial'), ('2', 'Operación electrónica'), ('3', 'Operación telemarketing'), ('4', 'Venta a domicilio'), ('5', 'Operación bancaria')]
l10n_py_qr_code
Binary
copy=False
readonly=True
args: 'Código QR'
l10n_py_qr_string
Char
copy=False
readonly=True
args: 'String QR'
l10n_py_receipt_id
Char
help='ID único del sistema cliente'
args: 'Receipt ID'
l10n_py_security_code
Char
copy=False
readonly=True
size=9
args: 'Código de Seguridad'
l10n_py_transaction_type
Selection
default='1'
required=True
string='Tipo de Transacción'
args: [('1', 'Venta de mercadería'), ('2', 'Prestación de servicios'), ('3', 'Mixto (Venta de mercadería y servicios)'), ('4', 'Venta de activo fijo'), ('5', 'Venta de divisas'), ('6', 'Compra de divisas'), ('7', 'Promoción o entrega de muestras'), ('8', 'Donación'), ('9', 'Anticipo'), ('10', 'Compra de productos'), ('11', 'Compra de servicios'), ('12', 'Venta de crédito fiscal'), ('13', 'Compra de crédito fiscal')]
l10n_py_transmission_deadline
Datetime
compute='_compute_transmission_deadline'
help='Plazo máximo para transmitir el DTE (72 horas desde emisión)'
store=True
string='Plazo de Transmisión'
l10n_py_transport_id
Many2one → l10n_py.transport
help='Datos de transporte para Nota de Remisión (Grupo G SIFEN)'
string='Datos de Transporte'
args: 'l10n_py.transport'
action_cancel_edi(self)
action_download_kude(self)
action_download_xml(self)
action_post(self)
action_preview_kude(self)
action_preview_xml(self)
action_retry_edi(self)
action_send_edi(self)
invoice_id
Many2one → account.move
required=True
string='Factura'
args: 'account.move'
action_send(self)
default_get(self, fields_list)
association_type
Selection
required=True
string='Tipo de Asociación (H002)'
args: [('1', 'Electrónico'), ('2', 'Impreso'), ('3', 'Constancia Electrónica')]
cdc
Char
help='Código de Control del Documento Electrónico (44 dígitos)'
size=44
string='CDC'
constancia_number
Char
size=20
string='Número de Constancia (H012)'
constancia_type
Selection
string='Tipo de Constancia (H011)'
args: [('1', 'Constancia de no ser contribuyente'), ('2', 'Constancia de microproductor')]
doc_date
Date
string='Fecha del Documento (H010)'
doc_number
Char
help='Número del documento (H008)'
size=7
string='Número de Documento'
doc_type_code
Selection
string='Tipo de Documento Impreso (H009)'
args: [('1', 'Factura'), ('2', 'Nota de crédito'), ('3', 'Nota de débito'), ('4', 'Nota de remisión'), ('5', 'Comprobante de retención')]
establishment
Char
help='Código de establecimiento (H006)'
size=3
string='Establecimiento'
expedition_point
Char
help='Punto de expedición (H007)'
size=3
string='Punto de Expedición'
move_id
Many2one → account.move
index=True
ondelete='cascade'
required=True
string='Factura'
args: 'account.move'
timbrado
Char
help='Número de timbrado del documento impreso (H005)'
size=8
No public methods.
invoice_id
Many2one → account.move
required=True
string='Factura'
args: 'account.move'
motive
Text
required=True
string='Motivo de Cancelación'
action_cancel(self)
default_get(self, fields_list)
active
Boolean
default=True
company_id
Many2one → res.company
default=<expr>
required=True
args: 'res.company'
environment
Selection
default='test'
required=True
args: [('test', 'Pruebas'), ('prod', 'Producción')]
name
Char
required=True
provider_type
Selection
required=True
selection=[]
string='Proveedor'
timeout
Integer
default=30
cancel_document(self, document_id, reason='')
check_status(self, document_id)
inutilize_range(self, data)
preview_document(self, invoice_data)
send_document(self, invoice_data)
test_connection(self)
code
Char
required=True
size=2
string='Código'
description
Text
string='Descripción'
translate=True
name
Char
required=True
string='Nombre'
translate=True
No public methods.
batch_id
Char
help='Identificador de lote do provedor'
string='ID do Lote'
cdc
Char
help='Código de Control del documento'
index=True
string='CDC'
document_id
Many2one → account.move
help='Documento fiscal relacionado'
index=True
ondelete='cascade'
string='Documento'
args: 'account.move'
duration_human
Char
compute='_compute_duration_human'
help='Duração em formato legível'
string='Duração'
endpoint
Char
help='URL ou endpoint da API'
error
Boolean
compute='_compute_error'
help='Indica se houve erro na operação'
store=True
string='É Erro'
error_code
Char
help='Código de erro do provedor'
string='Código de Erro'
error_message
Text
help='Descrição do erro se houver'
string='Mensagem de Erro'
execution_time
Float
digits=(10, 2)
help='Tempo de execução em milissegundos'
string='Tempo de Execução (ms)'
method
Selection
string='Método HTTP'
args: [('GET', 'GET'), ('POST', 'POST'), ('PUT', 'PUT'), ('DELETE', 'DELETE'), ('PATCH', 'PATCH')]
operation_type
Selection
index=True
required=True
string='Tipo de Operação'
args: [('send', 'Envio de Documento'), ('status', 'Consulta de Status'), ('cancel', 'Cancelación'), ('event', 'Evento'), ('download_pdf', 'Download PDF'), ('download_xml', 'Download XML'), ('validate', 'Validação')]
provider
Selection
index=True
required=True
string='Provedor'
args: [('factpy', 'FactPy'), ('facturasend', 'FacturaSend'), ('sifen', 'SIFEN Directo'), ('local', 'Processamento Local')]
request_data
Text
help='Payload da requisição'
string='Dados Enviados'
request_headers
Text
help='Headers HTTP enviados'
string='Headers da Requisição'
response_data
Text
help='Payload da resposta'
string='Resposta Recebida'
response_headers
Text
help='Headers HTTP recebidos'
string='Headers da Resposta'
retry_count
Integer
default=0
help='Número de tentativas realizadas'
string='Tentativas'
status_code
Integer
help='Código de status HTTP'
string='Código de Status'
success
Boolean
default=True
help='Indica se a operação foi bem-sucedida'
index=True
string='Sucesso'
action_retry_operation(self)
action_view_document(self)
action_view_request_data(self)
action_view_response_data(self)
log_operation(self, operation_type, provider, document=None, request_data=None, response_data=None, execution_time=0, success=True, error_message=None, **kwargs)
No new fields.
Public methods (1)log_edi_operation(self, operation_type, provider, document=None, **kwargs)
authorization_id
Many2one → account.authorization
ondelete='restrict'
required=True
string='Timbrado'
args: 'account.authorization'
company_id
Many2one
related='authorization_id.company_id'
store=True
motive
Text
required=True
string='Motivo'
number_from
Integer
required=True
string='Número Desde'
number_to
Integer
required=True
string='Número Hasta'
quantity
Integer
compute='_compute_quantity'
string='Cantidad'
state
Selection
default='draft'
readonly=True
string='Estado'
args: [('draft', 'Borrador'), ('sent', 'Enviado'), ('accepted', 'Aceptado'), ('rejected', 'Rechazado')]
action_send(self)
company_id
Many2one
related='move_id.company_id'
store=True
delivery_ids
One2many → l10n_py.transport.delivery
string='Entregas'
args: 'l10n_py.transport.delivery', 'transport_id'
departure_address
Char
string='Dirección de Salida (E920)'
departure_city
Integer
string='Ciudad Salida (E928)'
departure_department
Integer
string='Departamento Salida (E924)'
departure_district
Integer
string='Distrito Salida (E926)'
departure_house
Integer
string='Número de Casa Salida (E921)'
driver_doc_number
Char
string='Doc. del Chofer (E950)'
driver_name
Char
string='Nombre del Chofer (E951)'
freight_responsibility
Selection
string='Responsable del Flete (E905)'
args: [('1', 'Emisor de la Factura Electrónica'), ('2', 'Receptor de la Factura Electrónica'), ('3', 'Tercero'), ('4', 'Agente intermediario del transporte')]
incoterm
Selection
string='Condición de Negociación (E906)'
args: [('CFR', 'CFR'), ('CIF', 'CIF'), ('CIP', 'CIP'), ('CPT', 'CPT'), ('DAP', 'DAP'), ('DAT', 'DAT'), ('DDP', 'DDP'), ('EXW', 'EXW'), ('FAS', 'FAS'), ('FCA', 'FCA'), ('FOB', 'FOB')]
manifest_number
Char
string='Número de Manifiesto / Conocimiento (E907)'
move_id
Many2one → account.move
ondelete='cascade'
required=True
string='Documento'
args: 'account.move'
transport_end_date
Date
string='Fecha Fin Transporte (E910)'
transport_mode
Selection
default='1'
required=True
string='Modalidad de Transporte (E901)'
args: [('1', 'Terrestre'), ('2', 'Fluvial'), ('3', 'Aéreo'), ('4', 'Multimodal')]
transport_start_date
Date
string='Fecha Inicio Transporte (E909)'
transport_type
Selection
string='Tipo de Transporte (E903)'
args: [('1', 'Propio'), ('2', 'Tercero')]
transporter_dv
Char
size=1
string='DV del Transportista (E943)'
transporter_name
Char
string='Nombre del Transportista (E941)'
transporter_nature
Selection
string='Naturaleza del Transportista (E940)'
args: [('1', 'Contribuyente'), ('2', 'No contribuyente')]
transporter_ruc
Char
string='RUC del Transportista (E942)'
vehicle_ids
One2many → l10n_py.transport.vehicle
string='Vehículos'
args: 'l10n_py.transport.vehicle', 'transport_id'
No public methods.
address
Char
required=True
string='Dirección de Entrega (E930)'
city
Integer
required=True
string='Ciudad (E938)'
department
Integer
required=True
string='Departamento (E934)'
district
Integer
string='Distrito (E936)'
house_number
Integer
string='Número de Casa (E931)'
transport_id
Many2one → l10n_py.transport
ondelete='cascade'
required=True
string='Transporte'
args: 'l10n_py.transport'
No public methods.
brand
Char
required=True
string='Marca (E961)'
plate_number
Char
required=True
string='Número de Identificación (E962)'
transport_id
Many2one → l10n_py.transport
ondelete='cascade'
required=True
string='Transporte'
args: 'l10n_py.transport'
vehicle_type
Char
required=True
string='Tipo de Vehículo (E960)'
No public methods.
l10n_py_ncm_code
Char
help='Nomenclatura Común del Mercosur (8 dígitos)'
size=8
string='Código NCM'
l10n_py_unit_code
Integer
default=77
help='Código de unidad de medida según SET (77 = UNI - Unidad)'
string='Código Unidad de Medida'
No public methods.
l10n_py_city_code
Char
help='Código de la ciudad según SET'
readonly=True
related='partner_id.l10n_py_city_code'
store=True
string='Código Ciudad SET'
l10n_py_department_code
Integer
help='Código del departamento según SET'
readonly=True
related='partner_id.l10n_py_department_code'
store=True
string='Código Departamento SET'
l10n_py_district_code
Integer
help='Código del distrito según SET'
string='Código Distrito SET'
l10n_py_dv
Char
compute='_compute_dv'
help='Dígito Verificador del RUC'
size=1
store=True
string='DV'
l10n_py_economic_activity
Char
help='Descripción de la actividad económica principal'
string='Descripción Actividad Económica'
l10n_py_economic_activity_code
Char
help='Código de actividad económica principal según SET'
size=8
string='Código Actividad Económica'
l10n_py_ruc
Char
help='Registro Único del Contribuyente sin dígito verificador'
size=8
string='RUC'
l10n_py_ruc_full
Char
compute='_compute_ruc_full'
help='RUC con dígito verificador'
store=True
string='RUC Completo'
l10n_py_trade_name
Char
help='Nombre comercial o de fantasía de la empresa'
string='Nombre Fantasía'
No public methods.