diff --git a/CHANGELOG.md b/CHANGELOG.md index a1fa6818c..5f7c23f71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - `gr-mydata-v1`: Corrected exemption codes 3 and 4 mapping to `outside-scope` +### Added +- `cl`: Added the Chilean regime + ## [v0.308.0] - 2026-02-17 ### Removed diff --git a/data/regimes/cl.json b/data/regimes/cl.json new file mode 100644 index 000000000..7b35109da --- /dev/null +++ b/data/regimes/cl.json @@ -0,0 +1,119 @@ +{ + "$schema": "https://gobl.org/draft-0/tax/regime-def", + "name": { + "en": "Chile", + "es": "Chile" + }, + "description": { + "en": "Chile's tax system is administered by the SII (Servicio de Impuestos Internos), which oversees the collection of IVA (Impuesto al Valor Agregado), the country's value-added tax.\n\nTaxpayers are identified using the RUT (Rol Único Tributario), a 6-8 digit number with a check digit calculated using the modulo 11 algorithm. The check digit can be 0-9 or K, and RUTs are formatted as XX.XXX.XXX-Y. Both supplier and customer RUT are mandatory for Facturas Electrónicas (B2B invoices), while customer RUT is optional for Boletas Electrónicas (B2C receipts). Supplier address is always required, and customer address is required for B2B transactions.\n\nChile applies a single standard IVA rate of 19%, effective since October 1, 2003, when it was increased from 18% by Ley 19888. Unlike many other countries, Chile does not have reduced or super-reduced VAT rates.\n\nElectronic invoicing has been mandatory in Chile since 2018 for B2B transactions and since 2021 for B2C transactions. The system is based on DTEs (Documentos Tributarios Electrónicos - Electronic Tax Documents) that must be validated by the SII before being sent to the recipient. The validation process is known as \"prior validation,\" where documents are transmitted to the SII first, validated, returned to the issuer, and then forwarded to the customer. Recipients have 8 days to accept or reject documents; otherwise, they are considered tacitly accepted.\n\nCommon document types include Factura Electrónica (electronic invoice for B2B), Boleta Electrónica (electronic receipt for B2C), Nota de Crédito Electrónica (electronic credit note), Nota de Débito Electrónica (electronic debit note), and Guía de Despacho (dispatch guide). Use the \"simplified\" tag to indicate Boletas Electrónicas, which have relaxed customer identification requirements. All DTEs must be archived for 6 years in the XML format validated by the SII.\n\nAdditional SII requirements include Giro Comercial (business activity) for both parties, complete address details (Dirección, Ciudad, Comuna), and clear item descriptions (Resolution 36/2024, effective July 2024).", + "es": "El sistema tributario de Chile es administrado por el SII (Servicio de Impuestos Internos), que supervisa la recaudación del IVA (Impuesto al Valor Agregado).\n\nLos contribuyentes se identifican mediante el RUT (Rol Único Tributario), un número de 6-8 dígitos con un dígito verificador calculado mediante el algoritmo módulo 11. El dígito verificador puede ser 0-9 o K, y los RUT se formatean como XX.XXX.XXX-Y. El RUT del emisor y receptor es obligatorio para Facturas Electrónicas (B2B), mientras que el RUT del receptor es opcional para Boletas Electrónicas (B2C). La dirección del emisor es siempre requerida, y la dirección del receptor es requerida para transacciones B2B.\n\nChile aplica una tasa única de IVA del 19%, vigente desde el 1 de octubre de 2003, cuando fue aumentada del 18% mediante la Ley 19888. A diferencia de muchos otros países, Chile no tiene tasas reducidas o super-reducidas de IVA.\n\nLa facturación electrónica es obligatoria en Chile desde 2018 para transacciones B2B y desde 2021 para transacciones B2C. El sistema se basa en DTEs (Documentos Tributarios Electrónicos) que deben ser validados por el SII antes de enviarse al receptor. El proceso de validación se conoce como \"validación previa\", donde los documentos se transmiten primero al SII, se validan, se devuelven al emisor y luego se reenvían al cliente. Los receptores tienen 8 días para aceptar o rechazar documentos; de lo contrario, se consideran aceptados tácitamente.\n\nLos tipos de documentos comunes incluyen Factura Electrónica (factura para B2B), Boleta Electrónica (boleta para B2C), Nota de Crédito Electrónica, Nota de Débito Electrónica y Guía de Despacho. Use la etiqueta \"simplified\" para indicar Boletas Electrónicas, que tienen requisitos de identificación del cliente más flexibles. Todos los DTEs deben archivarse durante 6 años en el formato XML validado por el SII.\n\nRequisitos adicionales del SII incluyen Giro Comercial (actividad económica) para ambas partes, detalles completos de dirección (Dirección, Ciudad, Comuna), y descripciones claras de los ítems (Resolución 36/2024, vigente desde julio 2024)." + }, + "time_zone": "America/Santiago", + "country": "CL", + "currency": "CLP", + "tax_scheme": "VAT", + "categories": [ + { + "code": "VAT", + "name": { + "en": "VAT", + "es": "IVA" + }, + "title": { + "en": "Value Added Tax", + "es": "Impuesto al Valor Agregado" + }, + "desc": { + "en": "Chile's IVA (Impuesto al Valor Agregado) is a consumption tax applied to the sale of goods and services. Chile has applied a single standard rate of 19% since October 1, 2003, making it one of the simpler VAT systems in Latin America with no reduced or super-reduced rates.\n\nThe IVA applies to most goods and services unless specifically exempted. Common exemptions include certain financial services, educational services, and healthcare services. The tax is administered by the SII (Servicio de Impuestos Internos) and is a significant source of government revenue.", + "es": "El IVA (Impuesto al Valor Agregado) de Chile es un impuesto al consumo aplicado a la venta de bienes y servicios. Chile aplica una tasa estándar única del 19% desde el 1 de octubre de 2003, lo que lo convierte en uno de los sistemas de IVA más simples de América Latina, sin tasas reducidas o super-reducidas.\n\nEl IVA se aplica a la mayoría de los bienes y servicios a menos que estén específicamente exentos. Las exenciones comunes incluyen ciertos servicios financieros, servicios educativos y servicios de salud. El impuesto es administrado por el SII (Servicio de Impuestos Internos) y es una fuente importante de ingresos del gobierno." + }, + "keys": [ + { + "key": "standard", + "name": { + "en": "Standard" + } + }, + { + "key": "zero", + "name": { + "en": "Zero" + } + }, + { + "key": "reverse-charge", + "name": { + "en": "Reverse charge" + }, + "no_percent": true + }, + { + "key": "exempt", + "name": { + "en": "Exempt" + }, + "no_percent": true + }, + { + "key": "export", + "name": { + "en": "Export" + }, + "no_percent": true + }, + { + "key": "intra-community", + "name": { + "en": "Intra-community" + }, + "no_percent": true + }, + { + "key": "outside-scope", + "name": { + "en": "Outside scope" + }, + "no_percent": true + } + ], + "rates": [ + { + "rate": "general", + "keys": [ + "standard" + ], + "name": { + "en": "General Rate", + "es": "Tasa General" + }, + "values": [ + { + "since": "2003-10-01", + "percent": "19%" + }, + { + "since": "1990-07-01", + "percent": "18%" + } + ] + } + ], + "sources": [ + { + "title": { + "en": "Decreto Ley Nº 825 - Law on VAT and Services", + "es": "Decreto Ley Nº 825 - Ley sobre Impuesto a las Ventas y Servicios" + }, + "url": "https://www.sii.cl/normativa_legislacion/sobreventasyservicios.pdf" + }, + { + "title": { + "en": "Ley 19888 - Law establishing 19% VAT rate", + "es": "Ley 19888 - Ley que establece la tasa del IVA en 19%" + }, + "url": "https://www.bcn.cl/leychile/Navegar?idNorma=213493" + } + ] + } + ] +} \ No newline at end of file diff --git a/data/schemas/tax/regime-code.json b/data/schemas/tax/regime-code.json index c4b6e938a..540f2cea1 100644 --- a/data/schemas/tax/regime-code.json +++ b/data/schemas/tax/regime-code.json @@ -33,6 +33,10 @@ "const": "CH", "title": "Switzerland" }, + { + "const": "CL", + "title": "Chile" + }, { "const": "CO", "title": "Colombia" diff --git a/examples/cl/invoice-simplified-with-customer.json b/examples/cl/invoice-simplified-with-customer.json new file mode 100644 index 000000000..de39822d2 --- /dev/null +++ b/examples/cl/invoice-simplified-with-customer.json @@ -0,0 +1,66 @@ +{ + "$schema": "https://gobl.org/draft-0/bill/invoice", + "$regime": "CL", + "$tags": [ + "simplified" + ], + "uuid": "9f3c8b72-1ab5-4d9e-9c3f-f4e2d3c4b5a6", + "code": "B001-00000789", + "issue_date": "2025-01-20", + "currency": "CLP", + "supplier": { + "name": "Tienda de Electrónica Tech Store", + "tax_id": { + "country": "CL", + "code": "713254975" + }, + "addresses": [ + { + "street": "Av. Apoquindo 3500", + "locality": "Las Condes", + "region": "Región Metropolitana", + "code": "7550000", + "country": "CL" + } + ] + }, + "customer": { + "name": "Juan Pérez", + "tax_id": { + "country": "CL", + "code": "77668208K" + } + }, + "lines": [ + { + "quantity": "1", + "item": { + "name": "Notebook HP Pavilion 15", + "price": "599000" + }, + "taxes": [ + { + "cat": "VAT", + "key": "standard", + "rate": "general", + "percent": "19%" + } + ] + }, + { + "quantity": "1", + "item": { + "name": "Mouse inalámbrico", + "price": "15000" + }, + "taxes": [ + { + "cat": "VAT", + "key": "standard", + "rate": "general", + "percent": "19%" + } + ] + } + ] +} diff --git a/examples/cl/invoice-simplified.json b/examples/cl/invoice-simplified.json new file mode 100644 index 000000000..5ed837c3a --- /dev/null +++ b/examples/cl/invoice-simplified.json @@ -0,0 +1,67 @@ +{ + "$schema": "https://gobl.org/draft-0/bill/invoice", + "$regime": "CL", + "$tags": [ + "simplified" + ], + "uuid": "8d51fd61-9db6-41cf-8d44-e3a1e1b48d9a", + "code": "B001-00000456", + "issue_date": "2025-01-15", + "currency": "CLP", + "supplier": { + "name": "Restaurante El Buen Sabor", + "tax_id": { + "country": "CL", + "code": "713254975" + }, + "addresses": [ + { + "street": "Av. Providencia 1234", + "locality": "Providencia", + "region": "Región Metropolitana", + "code": "7500000", + "country": "CL" + } + ], + "emails": [ + { + "addr": "contacto@buensabor.cl" + } + ] + }, + "customer": { + "name": "Cliente Final" + }, + "lines": [ + { + "quantity": "2", + "item": { + "name": "Almuerzo Ejecutivo", + "price": "8500" + }, + "taxes": [ + { + "cat": "VAT", + "key": "standard", + "rate": "general", + "percent": "19%" + } + ] + }, + { + "quantity": "2", + "item": { + "name": "Bebida", + "price": "2000" + }, + "taxes": [ + { + "cat": "VAT", + "key": "standard", + "rate": "general", + "percent": "19%" + } + ] + } + ] +} diff --git a/examples/cl/invoice-standard.json b/examples/cl/invoice-standard.json new file mode 100644 index 000000000..993fa7355 --- /dev/null +++ b/examples/cl/invoice-standard.json @@ -0,0 +1,92 @@ +{ + "$schema": "https://gobl.org/draft-0/bill/invoice", + "$regime": "CL", + "uuid": "3aea7b56-59d8-4beb-90bd-f8f280d852a0", + "code": "F001-00000123", + "issue_date": "2025-01-15", + "currency": "CLP", + "supplier": { + "name": "Empresa Ejemplo SpA", + "tax_id": { + "country": "CL", + "code": "713254975" + }, + "addresses": [ + { + "street": "Av. Libertador Bernardo O'Higgins 1234", + "locality": "Santiago", + "region": "Región Metropolitana", + "code": "8320000", + "country": "CL" + } + ], + "emails": [ + { + "addr": "ventas@empresaejemplo.cl" + } + ] + }, + "customer": { + "name": "Cliente Comercial Ltda.", + "tax_id": { + "country": "CL", + "code": "77668208K" + }, + "addresses": [ + { + "street": "Av. Providencia 2500", + "locality": "Providencia", + "region": "Región Metropolitana", + "code": "7500000", + "country": "CL" + } + ], + "emails": [ + { + "addr": "compras@clientecomercial.cl" + } + ] + }, + "lines": [ + { + "quantity": "10", + "item": { + "name": "Servicios de consultoría", + "price": "50000" + }, + "taxes": [ + { + "cat": "VAT", + "key": "standard", + "rate": "general", + "percent": "19%" + } + ] + }, + { + "quantity": "5", + "item": { + "name": "Desarrollo de software", + "price": "100000" + }, + "taxes": [ + { + "cat": "VAT", + "key": "standard", + "rate": "general", + "percent": "19%" + } + ] + } + ], + "payment": { + "terms": { + "due_dates": [ + { + "date": "2025-02-15", + "percent": "100%" + } + ] + } + } +} diff --git a/examples/cl/out/invoice-simplified-with-customer.json b/examples/cl/out/invoice-simplified-with-customer.json new file mode 100644 index 000000000..103a37075 --- /dev/null +++ b/examples/cl/out/invoice-simplified-with-customer.json @@ -0,0 +1,107 @@ +{ + "$schema": "https://gobl.org/draft-0/envelope", + "head": { + "uuid": "8a51fd30-2a27-11ee-be56-0242ac120002", + "dig": { + "alg": "sha256", + "val": "fc37df36fc7e90f616eb8cb98c127dde40f54b8cdc13b44de2461d079873ccdb" + } + }, + "doc": { + "$schema": "https://gobl.org/draft-0/bill/invoice", + "$regime": "CL", + "$tags": [ + "simplified" + ], + "uuid": "9f3c8b72-1ab5-4d9e-9c3f-f4e2d3c4b5a6", + "type": "standard", + "code": "B001-00000789", + "issue_date": "2025-01-20", + "currency": "CLP", + "supplier": { + "name": "Tienda de Electrónica Tech Store", + "tax_id": { + "country": "CL", + "code": "713254975" + }, + "addresses": [ + { + "street": "Av. Apoquindo 3500", + "locality": "Las Condes", + "region": "Región Metropolitana", + "code": "7550000", + "country": "CL" + } + ] + }, + "customer": { + "name": "Juan Pérez", + "tax_id": { + "country": "CL", + "code": "77668208K" + } + }, + "lines": [ + { + "i": 1, + "quantity": "1", + "item": { + "name": "Notebook HP Pavilion 15", + "price": "599000" + }, + "sum": "599000", + "taxes": [ + { + "cat": "VAT", + "key": "standard", + "rate": "general", + "percent": "19%" + } + ], + "total": "599000" + }, + { + "i": 2, + "quantity": "1", + "item": { + "name": "Mouse inalámbrico", + "price": "15000" + }, + "sum": "15000", + "taxes": [ + { + "cat": "VAT", + "key": "standard", + "rate": "general", + "percent": "19%" + } + ], + "total": "15000" + } + ], + "totals": { + "sum": "614000", + "total": "614000", + "taxes": { + "categories": [ + { + "code": "VAT", + "rates": [ + { + "key": "standard", + "base": "614000", + "percent": "19%", + "amount": "116660" + } + ], + "amount": "116660" + } + ], + "sum": "116660" + }, + "tax": "116660", + "total_with_tax": "730660", + "payable": "730660" + } + } +} \ No newline at end of file diff --git a/examples/cl/out/invoice-simplified.json b/examples/cl/out/invoice-simplified.json new file mode 100644 index 000000000..63261884a --- /dev/null +++ b/examples/cl/out/invoice-simplified.json @@ -0,0 +1,108 @@ +{ + "$schema": "https://gobl.org/draft-0/envelope", + "head": { + "uuid": "8a51fd30-2a27-11ee-be56-0242ac120002", + "dig": { + "alg": "sha256", + "val": "7ac00af90933266101a735fd93dedb014451ecf3ae08e74f444f84de40d53e12" + } + }, + "doc": { + "$schema": "https://gobl.org/draft-0/bill/invoice", + "$regime": "CL", + "$tags": [ + "simplified" + ], + "uuid": "8d51fd61-9db6-41cf-8d44-e3a1e1b48d9a", + "type": "standard", + "code": "B001-00000456", + "issue_date": "2025-01-15", + "currency": "CLP", + "supplier": { + "name": "Restaurante El Buen Sabor", + "tax_id": { + "country": "CL", + "code": "713254975" + }, + "addresses": [ + { + "street": "Av. Providencia 1234", + "locality": "Providencia", + "region": "Región Metropolitana", + "code": "7500000", + "country": "CL" + } + ], + "emails": [ + { + "addr": "contacto@buensabor.cl" + } + ] + }, + "customer": { + "name": "Cliente Final" + }, + "lines": [ + { + "i": 1, + "quantity": "2", + "item": { + "name": "Almuerzo Ejecutivo", + "price": "8500" + }, + "sum": "17000", + "taxes": [ + { + "cat": "VAT", + "key": "standard", + "rate": "general", + "percent": "19%" + } + ], + "total": "17000" + }, + { + "i": 2, + "quantity": "2", + "item": { + "name": "Bebida", + "price": "2000" + }, + "sum": "4000", + "taxes": [ + { + "cat": "VAT", + "key": "standard", + "rate": "general", + "percent": "19%" + } + ], + "total": "4000" + } + ], + "totals": { + "sum": "21000", + "total": "21000", + "taxes": { + "categories": [ + { + "code": "VAT", + "rates": [ + { + "key": "standard", + "base": "21000", + "percent": "19%", + "amount": "3990" + } + ], + "amount": "3990" + } + ], + "sum": "3990" + }, + "tax": "3990", + "total_with_tax": "24990", + "payable": "24990" + } + } +} \ No newline at end of file diff --git a/examples/cl/out/invoice-standard.json b/examples/cl/out/invoice-standard.json new file mode 100644 index 000000000..d53bba09c --- /dev/null +++ b/examples/cl/out/invoice-standard.json @@ -0,0 +1,134 @@ +{ + "$schema": "https://gobl.org/draft-0/envelope", + "head": { + "uuid": "8a51fd30-2a27-11ee-be56-0242ac120002", + "dig": { + "alg": "sha256", + "val": "ed4173954975a415330a436aa48305ba9f21c690a69999434c6f5dd3b81fd58a" + } + }, + "doc": { + "$schema": "https://gobl.org/draft-0/bill/invoice", + "$regime": "CL", + "uuid": "3aea7b56-59d8-4beb-90bd-f8f280d852a0", + "type": "standard", + "code": "F001-00000123", + "issue_date": "2025-01-15", + "currency": "CLP", + "supplier": { + "name": "Empresa Ejemplo SpA", + "tax_id": { + "country": "CL", + "code": "713254975" + }, + "addresses": [ + { + "street": "Av. Libertador Bernardo O'Higgins 1234", + "locality": "Santiago", + "region": "Región Metropolitana", + "code": "8320000", + "country": "CL" + } + ], + "emails": [ + { + "addr": "ventas@empresaejemplo.cl" + } + ] + }, + "customer": { + "name": "Cliente Comercial Ltda.", + "tax_id": { + "country": "CL", + "code": "77668208K" + }, + "addresses": [ + { + "street": "Av. Providencia 2500", + "locality": "Providencia", + "region": "Región Metropolitana", + "code": "7500000", + "country": "CL" + } + ], + "emails": [ + { + "addr": "compras@clientecomercial.cl" + } + ] + }, + "lines": [ + { + "i": 1, + "quantity": "10", + "item": { + "name": "Servicios de consultoría", + "price": "50000" + }, + "sum": "500000", + "taxes": [ + { + "cat": "VAT", + "key": "standard", + "rate": "general", + "percent": "19%" + } + ], + "total": "500000" + }, + { + "i": 2, + "quantity": "5", + "item": { + "name": "Desarrollo de software", + "price": "100000" + }, + "sum": "500000", + "taxes": [ + { + "cat": "VAT", + "key": "standard", + "rate": "general", + "percent": "19%" + } + ], + "total": "500000" + } + ], + "payment": { + "terms": { + "due_dates": [ + { + "date": "2025-02-15", + "amount": "1190000", + "percent": "100%" + } + ] + } + }, + "totals": { + "sum": "1000000", + "total": "1000000", + "taxes": { + "categories": [ + { + "code": "VAT", + "rates": [ + { + "key": "standard", + "base": "1000000", + "percent": "19%", + "amount": "190000" + } + ], + "amount": "190000" + } + ], + "sum": "190000" + }, + "tax": "190000", + "total_with_tax": "1190000", + "payable": "1190000" + } + } +} \ No newline at end of file diff --git a/regimes/cl/cl.go b/regimes/cl/cl.go new file mode 100644 index 000000000..e007d3462 --- /dev/null +++ b/regimes/cl/cl.go @@ -0,0 +1,91 @@ +// Package cl handles tax regime data for Chile. +// +// This package implements validation and normalization for Chilean tax documents +// according to the requirements of the SII (Servicio de Impuestos Internos). +// +// Key regulations: +// - Decreto Ley Nº 825 (1974): VAT Law - https://www.sii.cl/normativa_legislacion/sobreventasyservicios.pdf +// - Ley 19888 (2003): Established 19% VAT rate - https://www.bcn.cl/leychile/Navegar?idNorma=213493 +// - Resolution 36/2024: Item description requirements (effective July 2024) +// +// Electronic invoicing references: +// - SII Electronic Invoicing Portal: https://www.sii.cl/factura_electronica/ +// - DTE Format Specification: https://www.sii.cl/factura_electronica/factura_mercado/formato_dte.pdf +// - Boleta Format Specification: https://www.sii.cl/factura_electronica/factura_mercado/formato_boletas_elec_202306.pdf +package cl + +import ( + "github.com/invopop/gobl/bill" + "github.com/invopop/gobl/currency" + "github.com/invopop/gobl/i18n" + "github.com/invopop/gobl/pkg/here" + "github.com/invopop/gobl/tax" +) + +func init() { + tax.RegisterRegimeDef(New()) +} + +// New provides the tax region definition +func New() *tax.RegimeDef { + return &tax.RegimeDef{ + Country: "CL", + Currency: currency.CLP, + TaxScheme: tax.CategoryVAT, + Name: i18n.String{ + i18n.EN: "Chile", + i18n.ES: "Chile", + }, + Description: i18n.String{ + i18n.EN: here.Doc(` + Chile's tax system is administered by the SII (Servicio de Impuestos Internos), which oversees the collection of IVA (Impuesto al Valor Agregado), the country's value-added tax. + + Taxpayers are identified using the RUT (Rol Único Tributario), a 6-8 digit number with a check digit calculated using the modulo 11 algorithm. The check digit can be 0-9 or K, and RUTs are formatted as XX.XXX.XXX-Y. Both supplier and customer RUT are mandatory for Facturas Electrónicas (B2B invoices), while customer RUT is optional for Boletas Electrónicas (B2C receipts). Supplier address is always required, and customer address is required for B2B transactions. + + Chile applies a single standard IVA rate of 19%, effective since October 1, 2003, when it was increased from 18% by Ley 19888. Unlike many other countries, Chile does not have reduced or super-reduced VAT rates. + + Electronic invoicing has been mandatory in Chile since 2018 for B2B transactions and since 2021 for B2C transactions. The system is based on DTEs (Documentos Tributarios Electrónicos - Electronic Tax Documents) that must be validated by the SII before being sent to the recipient. The validation process is known as "prior validation," where documents are transmitted to the SII first, validated, returned to the issuer, and then forwarded to the customer. Recipients have 8 days to accept or reject documents; otherwise, they are considered tacitly accepted. + + Common document types include Factura Electrónica (electronic invoice for B2B), Boleta Electrónica (electronic receipt for B2C), Nota de Crédito Electrónica (electronic credit note), Nota de Débito Electrónica (electronic debit note), and Guía de Despacho (dispatch guide). Use the "simplified" tag to indicate Boletas Electrónicas, which have relaxed customer identification requirements. All DTEs must be archived for 6 years in the XML format validated by the SII. + + Additional SII requirements include Giro Comercial (business activity) for both parties, complete address details (Dirección, Ciudad, Comuna), and clear item descriptions (Resolution 36/2024, effective July 2024). + `), + i18n.ES: here.Doc(` + El sistema tributario de Chile es administrado por el SII (Servicio de Impuestos Internos), que supervisa la recaudación del IVA (Impuesto al Valor Agregado). + + Los contribuyentes se identifican mediante el RUT (Rol Único Tributario), un número de 6-8 dígitos con un dígito verificador calculado mediante el algoritmo módulo 11. El dígito verificador puede ser 0-9 o K, y los RUT se formatean como XX.XXX.XXX-Y. El RUT del emisor y receptor es obligatorio para Facturas Electrónicas (B2B), mientras que el RUT del receptor es opcional para Boletas Electrónicas (B2C). La dirección del emisor es siempre requerida, y la dirección del receptor es requerida para transacciones B2B. + + Chile aplica una tasa única de IVA del 19%, vigente desde el 1 de octubre de 2003, cuando fue aumentada del 18% mediante la Ley 19888. A diferencia de muchos otros países, Chile no tiene tasas reducidas o super-reducidas de IVA. + + La facturación electrónica es obligatoria en Chile desde 2018 para transacciones B2B y desde 2021 para transacciones B2C. El sistema se basa en DTEs (Documentos Tributarios Electrónicos) que deben ser validados por el SII antes de enviarse al receptor. El proceso de validación se conoce como "validación previa", donde los documentos se transmiten primero al SII, se validan, se devuelven al emisor y luego se reenvían al cliente. Los receptores tienen 8 días para aceptar o rechazar documentos; de lo contrario, se consideran aceptados tácitamente. + + Los tipos de documentos comunes incluyen Factura Electrónica (factura para B2B), Boleta Electrónica (boleta para B2C), Nota de Crédito Electrónica, Nota de Débito Electrónica y Guía de Despacho. Use la etiqueta "simplified" para indicar Boletas Electrónicas, que tienen requisitos de identificación del cliente más flexibles. Todos los DTEs deben archivarse durante 6 años en el formato XML validado por el SII. + + Requisitos adicionales del SII incluyen Giro Comercial (actividad económica) para ambas partes, detalles completos de dirección (Dirección, Ciudad, Comuna), y descripciones claras de los ítems (Resolución 36/2024, vigente desde julio 2024). + `), + }, + TimeZone: "America/Santiago", + Validator: Validate, + Normalizer: Normalize, + Categories: taxCategories, + } +} + +// Normalize will attempt to clean the object passed to it. +func Normalize(doc any) { + switch obj := doc.(type) { + case *tax.Identity: + normalizeTaxIdentity(obj) + } +} + +// Validate checks the document type and determines if it can be validated. +func Validate(doc interface{}) error { + switch obj := doc.(type) { + case *bill.Invoice: + return validateInvoice(obj) + case *tax.Identity: + return validateTaxIdentity(obj) + } + return nil +} diff --git a/regimes/cl/invoices.go b/regimes/cl/invoices.go new file mode 100644 index 000000000..fd78345a4 --- /dev/null +++ b/regimes/cl/invoices.go @@ -0,0 +1,105 @@ +package cl + +import ( + "github.com/invopop/gobl/bill" + "github.com/invopop/gobl/org" + "github.com/invopop/gobl/tax" + "github.com/invopop/validation" +) + +// invoiceValidator validates Chilean invoices according to SII requirements. +// +// Validation enforces: +// - Supplier: RUT and address required for all DTEs +// - Customer: RUT and address required for Facturas (B2B), optional for Boletas (B2C) +// +// Use tax.TagSimplified to indicate a Boleta Electrónica (B2C receipt). +// +// Additional SII requirements (documented but not validated): Giro Comercial, Comuna, +// payment terms, and item descriptions per Resolution 36/2024. +// +// References: +// - https://www.sii.cl/factura_electronica/factura_mercado/formato_dte.pdf +// - https://www.sii.cl/factura_electronica/factura_mercado/formato_boletas_elec_202306.pdf +type invoiceValidator struct { + inv *bill.Invoice +} + +func validateInvoice(inv *bill.Invoice) error { + if inv == nil { + return nil + } + v := &invoiceValidator{inv: inv} + return v.validate() +} + +func (v *invoiceValidator) validate() error { + inv := v.inv + return validation.ValidateStruct(inv, + validation.Field(&inv.Supplier, + validation.Required, + validation.By(v.supplier), + validation.Skip, + ), + validation.Field(&inv.Customer, + validation.By(v.customer), + validation.Skip, + ), + ) +} + +func (v *invoiceValidator) supplier(value interface{}) error { + obj, _ := value.(*org.Party) + if obj == nil { + return nil + } + return validation.ValidateStruct(obj, + // RUT required for all DTEs (mandatory since 2018/2021 for B2B/B2C) + validation.Field(&obj.TaxID, + validation.Required, + tax.RequireIdentityCode, + validation.Skip, + ), + // Address required (Dirección, Ciudad, Comuna) + validation.Field(&obj.Addresses, + validation.Required, + validation.Length(1, 0), + validation.Skip, + ), + ) +} + +func (v *invoiceValidator) customer(value interface{}) error { + inv := v.inv + // Facturas (B2B): RUT and address required + // Boletas (B2C with tax.TagSimplified): RUT and address optional + // Note: High-value boletas (>135 UF) will require RUT from Sep 2025 + isB2B := !inv.Tags.HasTags(tax.TagSimplified) + + obj, _ := value.(*org.Party) + if obj == nil { + if isB2B { + return validation.NewError("validation_required", "customer is required for B2B invoices") + } + return nil + } + + return validation.ValidateStruct(obj, + validation.Field(&obj.TaxID, + validation.When( + isB2B, + validation.Required, + tax.RequireIdentityCode, + ), + validation.Skip, + ), + validation.Field(&obj.Addresses, + validation.When( + isB2B, + validation.Required, + validation.Length(1, 0), + ), + validation.Skip, + ), + ) +} diff --git a/regimes/cl/invoices_test.go b/regimes/cl/invoices_test.go new file mode 100644 index 000000000..8c3ea3bef --- /dev/null +++ b/regimes/cl/invoices_test.go @@ -0,0 +1,299 @@ +package cl_test + +import ( + "testing" + + "github.com/invopop/gobl/bill" + "github.com/invopop/gobl/cal" + "github.com/invopop/gobl/num" + "github.com/invopop/gobl/org" + "github.com/invopop/gobl/regimes/cl" + "github.com/invopop/gobl/tax" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func testInvoiceStandard(t *testing.T) *bill.Invoice { + t.Helper() + return &bill.Invoice{ + Code: "TEST-001", + Currency: "CLP", + Regime: tax.WithRegime("CL"), + Supplier: &org.Party{ + Name: "Test Supplier", + TaxID: &tax.Identity{ + Country: "CL", + Code: "713254975", + }, + Addresses: []*org.Address{ + { + Street: "Av. Libertador Bernardo O'Higgins", + Number: "1234", + Locality: "Santiago", + Region: "Región Metropolitana", + Code: "8320000", + Country: "CL", + }, + }, + }, + Customer: &org.Party{ + Name: "Test Customer", + TaxID: &tax.Identity{ + Country: "CL", + Code: "77668208K", // Valid customer RUT + }, + Addresses: []*org.Address{ + { + Street: "Av. Providencia", + Number: "567", + Locality: "Providencia", + Region: "Región Metropolitana", + Code: "7500000", + Country: "CL", + }, + }, + }, + IssueDate: cal.MakeDate(2024, 1, 1), + Lines: []*bill.Line{ + { + Quantity: num.MakeAmount(1, 0), + Item: &org.Item{ + Name: "Test Item", + Price: num.NewAmount(10000, 0), + }, + Taxes: tax.Set{ + { + Category: "VAT", + Rate: "standard", + }, + }, + }, + }, + } +} + +func TestInvoiceValidation(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + setupInv func(*bill.Invoice) + expectError string + }{ + { + name: "valid invoice", + setupInv: func(_ *bill.Invoice) {}, + }, + { + name: "missing supplier", + setupInv: func(inv *bill.Invoice) { + inv.Supplier = nil + }, + expectError: "supplier: cannot be blank", + }, + { + name: "supplier without tax ID", + setupInv: func(inv *bill.Invoice) { + inv.Supplier.TaxID = nil + }, + expectError: "tax_id: cannot be blank", + }, + { + name: "supplier with tax ID but no code", + setupInv: func(inv *bill.Invoice) { + inv.Supplier.TaxID.Code = "" + }, + expectError: "code: cannot be blank", + }, + { + name: "invalid RUT check digit", + setupInv: func(inv *bill.Invoice) { + inv.Supplier.TaxID.Code = "713254976" // Invalid check digit + }, + expectError: "invalid check digit", + }, + { + name: "supplier without address", + setupInv: func(inv *bill.Invoice) { + inv.Supplier.Addresses = nil + }, + expectError: "addresses", + }, + { + name: "supplier with empty addresses array", + setupInv: func(inv *bill.Invoice) { + inv.Supplier.Addresses = []*org.Address{} + }, + expectError: "addresses", + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + inv := testInvoiceStandard(t) + tt.setupInv(inv) + require.NoError(t, inv.Calculate()) + + err := inv.Validate() + if tt.expectError == "" { + assert.NoError(t, err) + } else { + if assert.Error(t, err) { + assert.Contains(t, err.Error(), tt.expectError) + } + } + }) + } + + // Separate test for regime-specific validation via cl.Validate + t.Run("regime-specific validation via cl.Validate", func(t *testing.T) { + t.Parallel() + inv := &bill.Invoice{ + Supplier: &org.Party{ + Name: "Test Supplier", + TaxID: &tax.Identity{ + Country: "CL", + Code: "713254975", + }, + Addresses: []*org.Address{ + { + Street: "Test Street", + Locality: "Santiago", + }, + }, + }, + } + inv.SetTags(tax.TagSimplified) + err := cl.Validate(inv) + assert.NoError(t, err) + }) +} + +func TestInvoiceCustomerValidation(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + setupInv func(*bill.Invoice) + expectError string + }{ + { + name: "B2B invoice - customer without RUT", + setupInv: func(inv *bill.Invoice) { + inv.Customer.TaxID = nil + }, + expectError: "tax_id: cannot be blank", + }, + { + name: "B2B invoice - customer with RUT but no code", + setupInv: func(inv *bill.Invoice) { + inv.Customer.TaxID = &tax.Identity{ + Country: "CL", + } + }, + expectError: "code: cannot be blank", + }, + { + name: "B2B invoice - customer with valid RUT", + setupInv: func(inv *bill.Invoice) { + inv.Customer.TaxID = &tax.Identity{ + Country: "CL", + Code: "77668208K", + } + }, + }, + { + name: "B2B invoice - customer with invalid RUT check digit", + setupInv: func(inv *bill.Invoice) { + inv.Customer.TaxID = &tax.Identity{ + Country: "CL", + Code: "77668208X", // Invalid check digit + } + }, + expectError: "invalid format", + }, + { + name: "B2B invoice - customer without address", + setupInv: func(inv *bill.Invoice) { + inv.Customer.Addresses = nil + }, + expectError: "addresses", + }, + { + name: "B2B invoice - customer with empty addresses array", + setupInv: func(inv *bill.Invoice) { + inv.Customer.Addresses = []*org.Address{} + }, + expectError: "addresses", + }, + { + name: "B2B invoice - missing customer should fail", + setupInv: func(inv *bill.Invoice) { + inv.Customer = nil + }, + expectError: "customer is required for B2B invoices", + }, + { + name: "B2C boleta - no customer required", + setupInv: func(inv *bill.Invoice) { + inv.SetTags(tax.TagSimplified) + inv.Customer = nil + }, + }, + { + name: "B2C boleta - customer without RUT is valid", + setupInv: func(inv *bill.Invoice) { + inv.SetTags(tax.TagSimplified) + inv.Customer.TaxID = nil + }, + }, + { + name: "B2C boleta - customer with RUT is also valid", + setupInv: func(inv *bill.Invoice) { + inv.SetTags(tax.TagSimplified) + inv.Customer.TaxID = &tax.Identity{ + Country: "CL", + Code: "77668208K", + } + }, + }, + { + name: "B2C boleta - customer without address is valid", + setupInv: func(inv *bill.Invoice) { + inv.SetTags(tax.TagSimplified) + inv.Customer.Addresses = nil + }, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + inv := testInvoiceStandard(t) + tt.setupInv(inv) + require.NoError(t, inv.Calculate()) + + err := inv.Validate() + if tt.expectError == "" { + assert.NoError(t, err) + } else { + if assert.Error(t, err) { + assert.Contains(t, err.Error(), tt.expectError) + } + } + }) + } +} + +func TestInvoiceNilSafety(t *testing.T) { + t.Parallel() + + t.Run("nil invoice should not panic", func(t *testing.T) { + t.Parallel() + err := cl.Validate((*bill.Invoice)(nil)) + assert.NoError(t, err) + }) +} diff --git a/regimes/cl/tax_categories.go b/regimes/cl/tax_categories.go new file mode 100644 index 000000000..ab8aab018 --- /dev/null +++ b/regimes/cl/tax_categories.go @@ -0,0 +1,77 @@ +package cl + +import ( + "github.com/invopop/gobl/cal" + "github.com/invopop/gobl/cbc" + "github.com/invopop/gobl/i18n" + "github.com/invopop/gobl/num" + "github.com/invopop/gobl/pkg/here" + "github.com/invopop/gobl/tax" +) + +var taxCategories = []*tax.CategoryDef{ + // + // VAT (IVA - Impuesto al Valor Agregado) + // + { + Code: tax.CategoryVAT, + Name: i18n.String{ + i18n.EN: "VAT", + i18n.ES: "IVA", + }, + Title: i18n.String{ + i18n.EN: "Value Added Tax", + i18n.ES: "Impuesto al Valor Agregado", + }, + Description: &i18n.String{ + i18n.EN: here.Doc(` + Chile's IVA (Impuesto al Valor Agregado) is a consumption tax applied to the sale of goods and services. Chile has applied a single standard rate of 19% since October 1, 2003, making it one of the simpler VAT systems in Latin America with no reduced or super-reduced rates. + + The IVA applies to most goods and services unless specifically exempted. Common exemptions include certain financial services, educational services, and healthcare services. The tax is administered by the SII (Servicio de Impuestos Internos) and is a significant source of government revenue. + `), + i18n.ES: here.Doc(` + El IVA (Impuesto al Valor Agregado) de Chile es un impuesto al consumo aplicado a la venta de bienes y servicios. Chile aplica una tasa estándar única del 19% desde el 1 de octubre de 2003, lo que lo convierte en uno de los sistemas de IVA más simples de América Latina, sin tasas reducidas o super-reducidas. + + El IVA se aplica a la mayoría de los bienes y servicios a menos que estén específicamente exentos. Las exenciones comunes incluyen ciertos servicios financieros, servicios educativos y servicios de salud. El impuesto es administrado por el SII (Servicio de Impuestos Internos) y es una fuente importante de ingresos del gobierno. + `), + }, + Sources: []*cbc.Source{ + { + Title: i18n.String{ + i18n.EN: "Decreto Ley Nº 825 - Law on VAT and Services", + i18n.ES: "Decreto Ley Nº 825 - Ley sobre Impuesto a las Ventas y Servicios", + }, + URL: "https://www.sii.cl/normativa_legislacion/sobreventasyservicios.pdf", + }, + { + Title: i18n.String{ + i18n.EN: "Ley 19888 - Law establishing 19% VAT rate", + i18n.ES: "Ley 19888 - Ley que establece la tasa del IVA en 19%", + }, + URL: "https://www.bcn.cl/leychile/Navegar?idNorma=213493", + }, + }, + Retained: false, + Keys: tax.GlobalVATKeys(), + Rates: []*tax.RateDef{ + { + Keys: []cbc.Key{tax.KeyStandard}, + Rate: tax.RateGeneral, + Name: i18n.String{ + i18n.EN: "General Rate", + i18n.ES: "Tasa General", + }, + Values: []*tax.RateValueDef{ + { + Since: cal.NewDate(2003, 10, 1), + Percent: num.MakePercentage(19, 2), + }, + { + Since: cal.NewDate(1990, 7, 1), + Percent: num.MakePercentage(18, 2), + }, + }, + }, + }, + }, +} diff --git a/regimes/cl/tax_identity.go b/regimes/cl/tax_identity.go new file mode 100644 index 000000000..263d0a85b --- /dev/null +++ b/regimes/cl/tax_identity.go @@ -0,0 +1,155 @@ +package cl + +import ( + "errors" + "regexp" + "strconv" + "strings" + + "github.com/invopop/gobl/cbc" + "github.com/invopop/gobl/tax" + "github.com/invopop/validation" +) + +var ( + // rutPattern matches normalized Chilean RUT format (no separators). + // Format: 6-8 digits followed by a check digit (0-9 or K/k), for a total of 7-9 characters. + // Modern RUTs typically have 8-9 digits total; older RUTs may have 7. + // Leading zeros are not allowed as real Chilean RUTs don't start with zero. + // Examples: "713254975" (9), "77668208K" (9), "10000009" (8) + rutPattern = regexp.MustCompile(`^([1-9]\d{5,7})([\dKk])$`) +) + +// validateTaxIdentity checks to ensure the RUT code looks okay. +func validateTaxIdentity(tID *tax.Identity) error { + if tID == nil { + return nil + } + return validation.ValidateStruct(tID, + validation.Field(&tID.Code, + validation.When( + tID.Country.In("CL"), + validation.By(validateRUT), + ), + ), + ) +} + +// normalizeTaxIdentity removes formatting characters from Chilean RUT numbers. +// +// Normalization process: +// 1. Removes all dots (.) and hyphens (-) +// 2. Converts lowercase 'k' to uppercase 'K' for check digits +// +// Examples: +// - "71.325.497-5" → "713254975" +// - "77.668.208-k" → "77668208K" +// - "12.345.678-5" → "123456785" +// +// Reference: https://en.wikipedia.org/wiki/National_identification_number#Chile +func normalizeTaxIdentity(tID *tax.Identity) { + if tID == nil { + return + } + tax.NormalizeIdentity(tID) +} + +// validateRUT validates a Chilean RUT (Rol Único Tributario) tax identification number. +// +// The RUT consists of a number (6-8 digits) followed by a check digit calculated +// using the modulo 11 algorithm. The check digit can be 0-9 or K (for check value 10). +// Total length: 7-9 characters. +// +// Validation process: +// 1. Verify the RUT matches the expected format (6-8 digits + check digit = 7-9 total) +// 2. Calculate the expected check digit using modulo 11 algorithm +// 3. Compare the calculated check digit with the provided one +// +// Returns nil if valid, or an error describing the validation failure. +// +// References: +// - RUT Format: https://es.wikipedia.org/wiki/Rol_%C3%9Anico_Tributario +// - RUT Length Updates (7-9 digits): https://help.getcirrus.com/es/articles/8515715-modificaciones-para-manejo-de-rut-de-7-a-9-digitos-chile +func validateRUT(value interface{}) error { + code, ok := value.(cbc.Code) + if !ok || code == "" { + return nil + } + + str := strings.ToUpper(string(code)) + + matches := rutPattern.FindStringSubmatch(str) + if matches == nil { + return errors.New("invalid format") + } + + number := matches[1] + checkDigit := matches[2] + + expected, err := calculateRUTCheckDigit(number) + if err != nil { + return err + } + + if expected != checkDigit { + return errors.New("invalid check digit") + } + + return nil +} + +// calculateRUTCheckDigit calculates the check digit for a Chilean RUT using the modulo 11 algorithm. +// +// The algorithm works as follows: +// 1. Process each digit from right to left +// 2. Multiply each digit by a factor that cycles through 2, 3, 4, 5, 6, 7 +// 3. Sum all the products +// 4. Calculate: 11 - (sum mod 11) +// 5. Special cases: result 11 → "0", result 10 → "K" +// +// Example for RUT 71325497: +// +// 7*2 + 9*3 + 4*4 + 5*5 + 2*6 + 3*7 + 1*2 + 7*3 = 14+27+16+25+12+21+2+21 = 138 +// 11 - (138 mod 11) = 11 - 6 = 5 +// Result: "713254975" +// +// Parameters: +// +// rut: The numeric portion of the RUT as a string (without check digit) +// +// Returns: +// +// The calculated check digit as a string ("0"-"9" or "K"), or an error if conversion fails +// +// Reference: https://es.wikipedia.org/wiki/Rol_%C3%9Anico_Tributario#Algoritmo +func calculateRUTCheckDigit(rut string) (string, error) { + sum := 0 + multiplier := 2 + + // Process digits from right to left + for i := len(rut) - 1; i >= 0; i-- { + digit := int(rut[i] - '0') + + if digit < 0 || digit > 9 { + return "", strconv.ErrSyntax + } + + sum += digit * multiplier + + multiplier++ + if multiplier > 7 { + multiplier = 2 + } + } + + remainder := 11 - (sum % 11) + + switch remainder { + case 11: + return "0", nil + case 10: + return "K", nil + default: + return strconv.Itoa(remainder), nil + } +} diff --git a/regimes/cl/tax_identity_test.go b/regimes/cl/tax_identity_test.go new file mode 100644 index 000000000..0039468a5 --- /dev/null +++ b/regimes/cl/tax_identity_test.go @@ -0,0 +1,176 @@ +package cl_test + +import ( + "testing" + + "github.com/invopop/gobl/cbc" + "github.com/invopop/gobl/l10n" + "github.com/invopop/gobl/regimes/cl" + "github.com/invopop/gobl/tax" + "github.com/stretchr/testify/assert" +) + +func TestNormalizeTaxIdentity(t *testing.T) { + t.Parallel() + + var tID *tax.Identity + assert.NotPanics(t, func() { + cl.Normalize(tID) + }) + + tests := []struct { + Code cbc.Code + Expected cbc.Code + }{ + { + Code: "12.345.678-5", + Expected: "123456785", + }, + { + Code: "11.111.111-1", + Expected: "111111111", + }, + { + Code: "12345678-5", + Expected: "123456785", + }, + { + Code: "76.123.456-K", + Expected: "76123456K", + }, + } + for _, tt := range tests { + tt := tt + t.Run(string(tt.Code), func(t *testing.T) { + t.Parallel() + tID := &tax.Identity{Country: "CL", Code: tt.Code} + cl.Normalize(tID) + assert.Equal(t, tt.Expected, tID.Code) + }) + } +} + +func TestValidateTaxIdentity(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + country l10n.TaxCountryCode + code cbc.Code + err string + }{ + { + name: "valid RUT 1", + country: "CL", + code: "713254975", + }, + { + name: "valid RUT 2", + country: "CL", + code: "111111111", + }, + { + name: "valid RUT 3", + country: "CL", + code: "100000008", + }, + { + name: "valid RUT 4 with K", + country: "CL", + code: "77668208K", + }, + { + name: "valid RUT 5 with lowercase k", + country: "CL", + code: "77668208k", + }, + { + name: "valid short RUT", + country: "CL", + code: "10000009", + }, + { + name: "valid RUT with check digit 0", + country: "CL", + code: "10000130", + }, + { + name: "empty code", + country: "CL", + code: "", + }, + { + name: "too short - less than 7 digits", + country: "CL", + code: "12345", + err: "invalid format", + }, + { + name: "invalid check digit", + country: "CL", + code: "123456780", + err: "invalid check digit", + }, + { + name: "too long", + country: "CL", + code: "1234567890123", + err: "invalid format", + }, + { + name: "invalid characters", + country: "CL", + code: "1234567A5", + err: "invalid format", + }, + { + name: "leading zero not allowed", + country: "CL", + code: "012345674", + err: "invalid format", + }, + { + name: "wrong check digit K when should be number", + country: "CL", + code: "12345678K", + err: "invalid check digit", + }, + { + name: "non-CL country - should not validate", + country: "AR", + code: "invalid", + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + tID := &tax.Identity{Country: tt.country, Code: tt.code} + err := cl.Validate(tID) + if tt.err == "" { + assert.NoError(t, err) + } else { + if assert.Error(t, err) { + assert.Contains(t, err.Error(), tt.err) + } + } + }) + } +} + +func TestValidateOtherDocuments(t *testing.T) { + t.Parallel() + + type unsupportedDoc struct{} + err := cl.Validate(&unsupportedDoc{}) + assert.NoError(t, err) + + err = cl.Validate(nil) + assert.NoError(t, err) + + // Test with nil tax.Identity specifically + var nilIdentity *tax.Identity + err = cl.Validate(nilIdentity) + assert.NoError(t, err) +} diff --git a/regimes/regimes.go b/regimes/regimes.go index ff3cb73a8..806e42569 100644 --- a/regimes/regimes.go +++ b/regimes/regimes.go @@ -12,6 +12,7 @@ import ( _ "github.com/invopop/gobl/regimes/br" _ "github.com/invopop/gobl/regimes/ca" _ "github.com/invopop/gobl/regimes/ch" + _ "github.com/invopop/gobl/regimes/cl" _ "github.com/invopop/gobl/regimes/co" _ "github.com/invopop/gobl/regimes/de" _ "github.com/invopop/gobl/regimes/dk"