buildInvoiceMapFromXml method

Map<String, dynamic> buildInvoiceMapFromXml(
  1. XmlDocument xml
)

Implementation

Map<String, dynamic> buildInvoiceMapFromXml(XmlDocument xml) {
// Define namespaces used in the document
final namespaces = {
  'cbc': 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2',
  'cac': 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2',
  'sts': 'dian:gov:co:facturaelectronica:Structures-2-1',
  'ext': 'urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2',
};

// Helper function to get elements with namespace
XmlElement? getElementNS(XmlElement? parent, String namespace, String name) {
  if (parent == null) return null;
  return parent.findElements(name, namespace: namespaces[namespace]).firstOrNull;
}

// Helper function to get text content with namespace
String getTextNS(XmlElement? parent, String namespace, String name) {
  final element = getElementNS(parent, namespace, name);
  return element?.innerText ?? '';
}

try {
  final invoiceElement = xml.rootElement;

  // Basic invoice information
  final invoiceId = getTextNS(invoiceElement, 'cbc', 'ID');
  final issueDate = getTextNS(invoiceElement, 'cbc', 'IssueDate');
  final issueTime = getTextNS(invoiceElement, 'cbc', 'IssueTime');
  final invoiceTypeCode = getTextNS(invoiceElement, 'cbc', 'InvoiceTypeCode');
  final documentCurrency = getTextNS(invoiceElement, 'cbc', 'DocumentCurrencyCode');
  final uuid = getTextNS(invoiceElement, 'cbc', 'UUID');

  // QR Code information
  final extensionsElement = getElementNS(invoiceElement, 'ext', 'UBLExtensions');
  final extensionElement = getElementNS(extensionsElement, 'ext', 'UBLExtension');
  final extensionContent = getElementNS(extensionElement, 'ext', 'ExtensionContent');
  final dianExtensions = extensionContent?.findElements('DianExtensions', namespace: namespaces['sts']).firstOrNull;
  final qrCode = dianExtensions?.findElements('QRCode', namespace: namespaces['sts']).firstOrNull?.innerText ?? '';

  // Supplier information
  final supplierParty = getElementNS(invoiceElement, 'cac', 'AccountingSupplierParty');
  final supplierPartyElement = getElementNS(supplierParty, 'cac', 'Party');
  final supplierLegalEntity = getElementNS(supplierPartyElement, 'cac', 'PartyLegalEntity');
  final supplierName = getTextNS(supplierLegalEntity, 'cbc', 'RegistrationName');
  final supplierID = getTextNS(
    getElementNS(supplierPartyElement, 'cac', 'PartyIdentification'),
    'cbc',
    'ID'
  );

  // Supplier contact information
  final supplierContact = getElementNS(supplierPartyElement, 'cac', 'Contact');
  final supplierPhone = getTextNS(supplierContact, 'cbc', 'Telephone');
  final supplierEmail = getTextNS(supplierContact, 'cbc', 'ElectronicMail');

  // Supplier address
  final supplierLocation = getElementNS(supplierPartyElement, 'cac', 'PhysicalLocation');
  final supplierAddress = getElementNS(supplierLocation, 'cac', 'Address');
  final supplierAddressLine = getTextNS(
    getElementNS(supplierAddress, 'cac', 'AddressLine'),
    'cbc',
    'Line'
  );
  final supplierCity = getTextNS(supplierAddress, 'cbc', 'CityName');
  final supplierState = getTextNS(supplierAddress, 'cbc', 'CountrySubentity');

  // Customer information
  final customerParty = getElementNS(invoiceElement, 'cac', 'AccountingCustomerParty');
  final customerPartyElement = getElementNS(customerParty, 'cac', 'Party');
  final customerLegalEntity = getElementNS(customerPartyElement, 'cac', 'PartyLegalEntity');
  final customerName = getTextNS(customerLegalEntity, 'cbc', 'RegistrationName');
  final customerID = getTextNS(
    getElementNS(customerPartyElement, 'cac', 'PartyIdentification'),
    'cbc',
    'ID'
  );

  // Payment information
  final paymentMeans = getElementNS(invoiceElement, 'cac', 'PaymentMeans');
  final paymentMeansCode = getTextNS(paymentMeans, 'cbc', 'PaymentMeansCode');
  final paymentDueDate = getTextNS(paymentMeans, 'cbc', 'PaymentDueDate');

  // Tax information
  final taxTotal = getElementNS(invoiceElement, 'cac', 'TaxTotal');
  final taxAmount = getTextNS(taxTotal, 'cbc', 'TaxAmount');

  // Monetary totals
  final legalMonetaryTotal = getElementNS(invoiceElement, 'cac', 'LegalMonetaryTotal');
  final lineExtensionAmount = getTextNS(legalMonetaryTotal, 'cbc', 'LineExtensionAmount');
  final taxExclusiveAmount = getTextNS(legalMonetaryTotal, 'cbc', 'TaxExclusiveAmount');
  final taxInclusiveAmount = getTextNS(legalMonetaryTotal, 'cbc', 'TaxInclusiveAmount');
  final payableAmount = getTextNS(legalMonetaryTotal, 'cbc', 'PayableAmount');

  // Invoice lines (items)
  final invoiceLines = invoiceElement.findElements('InvoiceLine', namespace: namespaces['cac']).map((lineElement) {
    final lineId = getTextNS(lineElement, 'cbc', 'ID');
    final quantity = getTextNS(lineElement, 'cbc', 'InvoicedQuantity');
    final lineExtensionAmount = getTextNS(lineElement, 'cbc', 'LineExtensionAmount');

    final itemElement = getElementNS(lineElement, 'cac', 'Item');
    final description = getTextNS(itemElement, 'cbc', 'Description');

    final priceElement = getElementNS(lineElement, 'cac', 'Price');
    final priceAmount = getTextNS(priceElement, 'cbc', 'PriceAmount');

    return {
      'code': lineId,
      'quantity': int.tryParse(quantity) ?? 0,
      'lineExtensionAmount': double.tryParse(lineExtensionAmount) ?? 0,
      'description': description,
      'price': double.tryParse(priceAmount) ?? 0,
    };
  }).toList();

  // Build the complete invoice map
  return {
    'id': invoiceId,
    //'invoiceInfo': {
      'uuid': uuid,
      'issueDate': issueDate,
      'issueTime': issueTime,
      //'documentTypeId': invoiceTypeCode,
      'documentCurrency': documentCurrency,
   // },
    'qrCode': qrCode,
    'supplier': {
      'id': supplierID,
      'name': supplierName,
      'contact': {
        'phone': supplierPhone,
        'email': supplierEmail,
      },
      'address': {
        'line': supplierAddressLine,
        'city': supplierCity,
        'state': supplierState,
      },
    },
    'customer': {
      'identificationNumber': customerID,
      'name': customerName,
    },
    'paymentForm': {
      'meansCode': paymentMeansCode,
      'dueDate': paymentDueDate,
    },
    'taxes': [
      {
        'amount': double.tryParse(taxAmount) ?? 0,
      }
    ],
    'totals': {
      'lineExtensionAmount': double.tryParse(lineExtensionAmount) ?? 0,
      'taxExclusiveAmount': double.tryParse(taxExclusiveAmount) ?? 0,
      'taxInclusiveAmount': double.tryParse(taxInclusiveAmount) ?? 0,
      'payableAmount': double.tryParse(payableAmount) ?? 0,
    },
    'items': invoiceLines,
  };
} catch (e) {
  developer.log('Error parsing XML: $e');
  return {
    'error': e.toString(),
  };
}
}