formatOutput = true; $root = $dom->createElementNS('urn:oasis:names:specification:ubl:schema:xsd:Invoice-2', 'Invoice'); $root->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:cac', 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'); $root->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:cbc', 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2'); $dom->appendChild($root); // 1. Basic Information $root->appendChild($dom->createElement('cbc:UBLVersionID', '2.1')); $root->appendChild($dom->createElement('cbc:CustomizationID', 'TRADACO-2.1')); $root->appendChild($dom->createElement('cbc:ProfileID', 'reporting:1.0')); $root->appendChild($dom->createElement('cbc:ID', $invoice['invoice_number'])); $root->appendChild($dom->createElement('cbc:IssueDate', $invoice['invoice_date'])); $typeCode = $dom->createElement('cbc:InvoiceTypeCode', $invoice['ubl_type_code'] ?? '388'); $typeCode->setAttribute('name', $invoice['invoice_category'] ?? '01'); $root->appendChild($typeCode); $root->appendChild($dom->createElement('cbc:DocumentCurrencyCode', 'JOD')); $root->appendChild($dom->createElement('cbc:TaxCurrencyCode', 'JOD')); // 2. AccountingSupplierParty $supplierParty = $dom->createElement('cac:AccountingSupplierParty'); $party = $dom->createElement('cac:Party'); $partyId = $dom->createElement('cac:PartyIdentification'); $idNode = $dom->createElement('cbc:ID', $company['tax_identification_number']); $idNode->setAttribute('schemeID', 'TN'); $partyId->appendChild($idNode); $party->appendChild($partyId); $partyName = $dom->createElement('cac:PartyName'); $partyName->appendChild($dom->createElement('cbc:Name', $company['name'])); $party->appendChild($partyName); $addr = $dom->createElement('cac:PostalAddress'); $addr->appendChild($dom->createElement('cbc:CityName', $company['city'] ?? 'Amman')); $country = $dom->createElement('cac:Country'); $country->appendChild($dom->createElement('cbc:IdentificationCode', 'JO')); $addr->appendChild($country); $party->appendChild($addr); $taxScheme = $dom->createElement('cac:PartyTaxScheme'); $taxScheme->appendChild($dom->createElement('cbc:RegistrationName', $company['name'])); $taxScheme->appendChild($dom->createElement('cbc:CompanyID', $company['tax_identification_number'])); $ts = $dom->createElement('cac:TaxScheme'); $ts->appendChild($dom->createElement('cbc:ID', 'VAT')); $taxScheme->appendChild($ts); $party->appendChild($taxScheme); $legalEntity = $dom->createElement('cac:PartyLegalEntity'); $legalEntity->appendChild($dom->createElement('cbc:RegistrationName', $company['name'])); $party->appendChild($legalEntity); $supplierParty->appendChild($party); $root->appendChild($supplierParty); // 3. AccountingCustomerParty $customerParty = $dom->createElement('cac:AccountingCustomerParty'); $cParty = $dom->createElement('cac:Party'); $cName = $dom->createElement('cac:PartyName'); $cName->appendChild($dom->createElement('cbc:Name', $invoice['buyer_name'] ?? 'عميل عام')); $cParty->appendChild($cName); if (!empty($invoice['buyer_tin'])) { $cId = $dom->createElement('cac:PartyIdentification'); $cidNode = $dom->createElement('cbc:ID', $invoice['buyer_tin']); $cidNode->setAttribute('schemeID', 'TN'); $cId->appendChild($cidNode); $cParty->appendChild($cId); } $customerParty->appendChild($cParty); $root->appendChild($customerParty); // 4. PaymentMeans $paymentMeans = $dom->createElement('cac:PaymentMeans'); $paymentMeans->appendChild($dom->createElement('cbc:PaymentMeansCode', $invoice['payment_method_code'] ?? '10')); $root->appendChild($paymentMeans); // 5. TaxTotal $taxTotal = $dom->createElement('cac:TaxTotal'); $taxAmt = $dom->createElement('cbc:TaxAmount', number_format((float)$invoice['tax_amount'], 3, '.', '')); $taxAmt->setAttribute('currencyID', 'JOD'); $taxTotal->appendChild($taxAmt); $root->appendChild($taxTotal); // 6. LegalMonetaryTotal $monetaryTotal = $dom->createElement('cac:LegalMonetaryTotal'); $fields = [ 'LineExtensionAmount' => $invoice['subtotal'], 'TaxExclusiveAmount' => $invoice['subtotal'], 'TaxInclusiveAmount' => $invoice['grand_total'], 'AllowanceTotalAmount' => $invoice['discount_total'] ?? 0, 'PayableAmount' => $invoice['grand_total'] ]; foreach ($fields as $field => $val) { $node = $dom->createElement('cbc:' . $field, number_format((float)$val, 3, '.', '')); $node->setAttribute('currencyID', 'JOD'); $monetaryTotal->appendChild($node); } $root->appendChild($monetaryTotal); // 7. Invoice Lines foreach ($lines as $line) { $iLine = $dom->createElement('cac:InvoiceLine'); $iLine->appendChild($dom->createElement('cbc:ID', (string)$line['line_number'])); $qty = $dom->createElement('cbc:InvoicedQuantity', number_format((float)$line['quantity'], 3, '.', '')); $qty->setAttribute('unitCode', 'PCE'); $iLine->appendChild($qty); $lineExt = $dom->createElement('cbc:LineExtensionAmount', number_format((float)$line['line_total'], 3, '.', '')); $lineExt->setAttribute('currencyID', 'JOD'); $iLine->appendChild($lineExt); $item = $dom->createElement('cac:Item'); $item->appendChild($dom->createElement('cbc:Description', $line['description'])); $iLine->appendChild($item); $price = $dom->createElement('cac:Price'); $pAmt = $dom->createElement('cbc:PriceAmount', number_format((float)$line['unit_price'], 3, '.', '')); $pAmt->setAttribute('currencyID', 'JOD'); $price->appendChild($pAmt); $iLine->appendChild($price); $root->appendChild($iLine); } return $dom->saveXML(); } }