| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Invoicing (account)
• Discuss (mail) • Contacts (contacts) |
| Lines of code | 1781 |
| Technical Name |
l10n_co_dian_vendor_bill_import |
| License | OPL-1 |
| Website | https://github.com/juanes361 |
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Invoicing (account)
• Discuss (mail) • Contacts (contacts) |
| Lines of code | 1781 |
| Technical Name |
l10n_co_dian_vendor_bill_import |
| License | OPL-1 |
| Website | https://github.com/juanes361 |
Colombia DIAN Bill Import
Drag-and-drop import for Colombian electronic vendor bills
Drop a DIAN AttachedDocument XML or its full ZIP onto a Vendor Bills journal —
this module unwraps the envelope, hands the inner UBL document to the native parser,
fills in 17 fields on the supplier, and logs DIAN ApplicationResponse events
to a dedicated audit table.
The problem
Colombian electronic invoices arrive wrapped in a DIAN <AttachedDocument>
envelope, with the actual UBL invoice — <Invoice>,
<CreditNote> or <DebitNote> — embedded as escaped CDATA inside a
cbc:Description tag. Standard Odoo Enterprise's UBL importer does not
understand that envelope, so the file is rejected or imported as an empty draft.
On top of that, suppliers send these documents as a .zip bundle that also
contains the graphical PDF and, sometimes, an ApplicationResponse from DIAN.
Accountants end up extracting files manually and filling in supplier data by hand —
NIT + verification digit, fiscal regimen, tax obligations, DANE address codes,
contact info — on every new vendor.
See it in action
Drop the XML, get a draft. Open the supplier — every DIAN field already filled.
1. Drop a .xml or .zip from the supplier on any Vendor Bills journal — the module handles the unwrap.
2. A draft account.move appears with the CUFE indexed, payment means resolved, purchase order linked, and the original ZIP attached for audit.
3. The supplier is enriched with NIT + DV, fiscal regimen, tax obligations, DANE-coded address, postal code and contact info — fields the accountant has touched are never overwritten.
4. DIAN ApplicationResponse events (030 validated, 031 received, 032 acknowledged, 033 claim, 034 express acceptance) land in a dedicated audit log — without polluting the journal with empty drafts.
What this module does
Unwraps the DIAN envelope
Detects AttachedDocument at the root, extracts the inner
Invoice / CreditNote / DebitNote from the embedded
CDATA and feeds it to Odoo's native UBL parser. .xml and .zip
are both accepted as drag-and-drop input on any Vendor Bills journal.
Idempotent by CUFE
The CUFE/CUDE is read before any record is created. If the same document has already been imported in the company, the existing draft is returned — no duplicate move, no duplicate attachment, safe to re-process the same email folder over and over.
Enriches the supplier (17 fields)
After import, the supplier's res.partner is filled from the XML —
NIT and verification digit, identification type, fiscal regimen, tax obligations
(including Gran Contribuyente), commercial name, full address with DANE
state and city codes, postal code with 4-72 fallback, contact name, phone (cleaned)
and email. Existing values are never overwritten.
Auto-fixes wrong-journal uploads
If an accountant drops the XML on a Customer Invoices journal by mistake, the module
detects that the company NIT appears as the customer (not the supplier) in the XML,
flips move_type to in_invoice / in_refund,
reroutes the move to a purchase journal and points partner_id to the
real supplier — searching by NIT or creating a new partner from the XML data.
Logs DIAN ApplicationResponse
When the incoming document is a DIAN ApplicationResponse (acknowledgement, rejection, claim) instead of an invoice, it is recorded in a dedicated audit model — searchable from Accounting → Miscellaneous → DIAN ApplicationResponses — without creating any draft, so DIAN events stay traceable without polluting the journal.
Strips supplier-specific noise
Before the native UBL parser sees the document, the module removes
SellersItemIdentification and friends so lines do not fuzzy-match
unrelated products in your catalogue. Boilerplate cbc:Note tags
(legal disclaimers, marketing) are also dropped, keeping the move's narration clean.
Fields populated automatically
On account.move
- Received CUFE/CUDE (idempotency key)
- Payment means code (DIAN 10/41/ZZZ →
l10n_co_edi_payment_option_id) - Payment reference from
PaymentID - Purchase order reference from
OrderReference/ID - Supplier bank account from
PayeeFinancialAccount - DIAN operation type (10/20/22/30/32) inferred from document type and reference
- Credit-note discrepancy reason in narration
- Auto-link credit notes to the original invoice via
BillingReference
On res.partner
- VAT (NIT + verification digit)
- Identification type (NIT / Cédula / Pasaporte / PEP / PPT / etc.)
- Fiscal regimen (Responsable IVA / No responsable / etc.)
- Tax obligations + Gran Contribuyente flag
- Commercial name (when different from registration name)
- Street, city, state — by DANE 5- and 2-digit codes
- Postal code (with 1122-municipality 4-72 fallback)
- Phone (normalised), email, contact name
Technical notes
- Odoo version: 18 Enterprise. Depends on
l10n_co_dian, which is Enterprise-only. - Standards: UBL 2.1 with the DIAN customisation profile.
- Dependencies:
account,account_edi_ubl_cii,l10n_co_dian. No external Python packages beyondlxml, which is already in Odoo's stack. - Public API:
account.move.l10n_co_dian_create_invoice_from_attachment(filename, content_b64, mimetype, journal_id=None)— XML-RPC callable, returns the created move id, the existing move id on CUFE collision, orFalseif the document is not a processable invoice. - Tests: tagged
l10n_co_dian_attached. Run withodoo-bin -d <db> -i l10n_co_dian_vendor_bill_import --test-enable --test-tags l10n_co_dian_attached --stop-after-init. - Translations: ships with
es_CO; the.pottemplate is included for further localisation.
What it does not do
This module covers the receive side only — incoming vendor bills.
It does not emit documents to DIAN; that is the role of the standard
l10n_co_dian module, which is a hard dependency. There is no email
connector inside the module either: the public method
l10n_co_dian_create_invoice_from_attachment is exposed so any external
fetcher (Gmail, IMAP, a webhook) can pipe attachments in via XML-RPC.
Support
Author: Juan Esteban Pérez · Email: juanes361@gmail.com · License: OPL-1
Screenshots use synthetic vendor data — no real NIT, supplier name or invoice number is shown.
Odoo Proprietary License v1.0 This software and associated files (the "Software") may only be used (executed, modified, executed after modifications) if you have purchased a valid license from the authors, typically via Odoo Apps, or if you have received a written agreement from the authors of the Software (see the COPYRIGHT file). You may develop Odoo modules that use the Software as a library (typically by depending on it, importing it and using its resources), but without copying any source code or material from the Software. You may distribute those modules under the license of your choice, provided that this license is compatible with the terms of the Odoo Proprietary License (For example: LGPL, MIT, or proprietary licenses similar to this one). It is forbidden to publish, distribute, sublicense, or sell copies of the Software or modified copies of the Software. The above copyright notice and this permission notice must be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Please log in to comment on this module