3namespace Noalyss\XMLDocument;
28abstract class XML_Reader
31 protected \DOMDocument $domDocument;
32 protected readonly \DOMXPath $xpath;
34 public function __construct(\DOMDocument $domDocument)
36 $this->domDocument = $domDocument;
37 $this->xpath = new \DOMXPath($this->domDocument);
44 public function registerNS(
$xml=
null)
46 $a_namespace=$this->get_namespace();
49 foreach ($a_namespace as $pf=>$ns) {
50 $this->xpath->registerNamespace($pf,$ns);
53 elseif ( get_class(
$xml) ==
"SimpleXMLElement" )
55 foreach ($a_namespace as $pf=>$ns) {
56 $xml->registerXPathNamespace($pf,$ns);
61 foreach ($a_namespace as $pf=>$ns) {
62 $xml->registerNamespace($pf,$ns);
68 throw new \Exception (
"unknown object ".get_class(
$xml),57);
75 public function get_domDocument(): \DOMDocument
77 return $this->domDocument;
80 public function get_xpath(): \DOMXPath
85 public function set_domDocument($domDocument)
87 $this->domDocument = $domDocument;
97 static function build_from_file($filename)
99 if (!file_exists($filename))
101 throw new \Exception(
"XR101: file not found $filename", 101);
103 $dm = new \DOMDocument();
104 if ($dm->load($filename) ==
false)
106 throw new \Exception(
"XR106: cannot load file", 106);
108 if ( $dm->getElementsByTagName(
"CreditNote")->length == 1)
110 return new XMLCreditNote_Reader($dm);
112 if ( $dm->getElementsByTagName(
"Invoice")->length == 1)
114 return new XMLInvoice_Reader($dm);
116 throw new \Exception(
"XR116: unknown XML", 116);
125 static function build_from_string(
$string)
127 $dm = new \DOMDocument();
128 if ($dm->loadXML(
$string) ==
false)
130 throw new \Exception(
"XR130: cannot load XML", 130);
132 if ( $dm->getElementsByTagName(
"CreditNote")->length == 1)
134 return new XMLCreditNote_Reader($dm);
136 if ( $dm->getElementsByTagName(
"Invoice")->length == 1)
138 return new XMLInvoice_Reader($dm);
140 throw new \Exception(
"XR120: unknown XML", 120);
152 public function get_embedded_document()
154 $a_document_reference = array();
156 "AdditionalDocumentReference",
157 "ReceiptDocumentReference",
158 "StatementDocumentReference",
159 "OriginatorDocumentReference",
160 "ContractDocumentReference"
164 $document = $this->domDocument->getElementsByTagName($document);
165 if ($document->length == 0)
169 for (
$e = 0;
$e < $document->count();
$e++)
171 $item = $document->item(
$e);
173 if ($item->nodeType == XML_ELEMENT_NODE)
175 $id = $item->getElementsByTagName(
"ID")[0]?->nodeValue;
176 $description = $item->getElementsByTagName(
"DocumentDescription")[0]?->nodeValue;
177 $embedded_document = $item->getElementsByTagName(
"EmbeddedDocumentBinaryObject");
178 if ($embedded_document->length == 0)
182 $binary_object =
new Binary_Object;
183 $binary_object->filecontent = base64_decode($embedded_document[0]->nodeValue);
184 $binary_object->mimecode = $embedded_document[0]->getAttribute(
"mimeCode");
185 $binary_object->filename = $embedded_document[0]->getAttribute(
"filename");
186 $document_reference =
new Document_Reference();
187 $document_reference->setId(
$id)
189 ->setBinary_object($binary_object);
190 $a_document_reference[] = clone $document_reference;
194 return $a_document_reference;
202 public function get_node(
$query)
206 if ($this->xpath->query(
$query)->length == 0)
210 return $this->xpath->query(
$query);
220 return $this->get_node(
$query)?->item(
$ix)?->nodeValue;
227 function get_customer(): array
230 $result[
'ID'] = $this->get_node_value(
"//cac:AccountingCustomerParty[1]/cac:Party[1]/cbc:EndpointID[1]");
231 $result[
'name'] = $this->get_node_value(
'//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PartyName[1]/cbc:Name[1]');
233 $result[
'name'] = $this->get_node_value(
"//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PartyLegalEntity[1]/cbc:RegistrationName[1]");
235 $result[
'street'] = $this->get_node_value(
'//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:StreetName[1]');
236 $result[
'city'] = $this->get_node_value(
'//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:CityName[1]');
237 $result[
'postcode'] = $this->get_node_value(
'//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:PostalZone[1]');
238 $result[
'country_code'] = $this->get_node_value(
"//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PostalAddress[1]/cac:Country[1]/cbc:IdentificationCode[1]");
239 $result[
'company_id'] = $this->get_node_value(
"//cac:AccountingCustomerParty[1]/cac:Party[1]/cac:PartyTaxScheme[1]/cbc:CompanyID[1]");
240 $result[
'scheme'] = $this->get_node(
"//cac:AccountingCustomerParty[1]/cac:Party[1]/cbc:EndpointID[1]")[0]->getAttribute(
"schemeID");
248 function get_supplier(): array
251 $result[
'ID'] = $this->get_node_value(
"//cac:AccountingSupplierParty[1]/cac:Party[1]/cbc:EndpointID[1]");
252 $result[
'name'] = $this->get_node_value(
"//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PartyName[1]/cbc:Name[1]");
254 $result[
'name'] = $this->get_node_value(
"//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PartyLegalEntity[1]/cbc:RegistrationName[1]");
256 $result[
'street'] = $this->get_node_value(
"//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:StreetName[1]");
257 $result[
'city'] = $this->get_node_value(
"//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:CityName[1]");
258 $result[
'postcode'] = $this->get_node_value(
"//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PostalAddress[1]/cbc:PostalZone[1]");
259 $result[
'country_code'] = $this->get_node_value(
"//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PostalAddress[1]/cac:Country[1]/cbc:IdentificationCode[1]");
260 $result[
'company_id'] = $this->get_node_value(
"//cac:AccountingSupplierParty[1]/cac:Party[1]/cac:PartyTaxScheme[1]/cbc:CompanyID[1]");
261 $result[
'scheme'] = $this->get_node(
"//cac:AccountingSupplierParty[1]/cac:Party[1]/cbc:EndpointID[1]")[0]->getAttribute(
"schemeID");
271 function get_payment_mean(): array
274 $result[
'payment_code'] = $this->get_node_value(
"//cac:PaymentMeans[1]/cbc:PaymentMeansCode[1]");
275 $result[
'label'] = $this->get_node_value(
"//cac:PaymentMeans[1]/cbc:PaymentID[1]");
276 $result[
'iban'] = $this->get_node_value(
"//cac:PaymentMeans[1]/cac:PayeeFinancialAccount[1]/cbc:ID[1]");
277 $result[
'bic'] = $this->get_node_value(
"//cac:PaymentMeans[1]/cac:PayeeFinancialAccount[1]/cac:FinancialInstitutionBranch[1]/cbc:ID[1]");
279 $note = $this->get_node(
"//cac:PaymentTerms/cbc:Note");
306 protected function get_simple_xml_value(\SimpleXMLElement
$xml,
$query): string
308 $this->registerNS(
$xml);
319 function get_amount_summary(): array
322 $node = $this->get_node(
"//cac:LegalMonetaryTotal");
323 $xml = simplexml_import_dom($node->item(0));
324 $result[
'LineExtensionAmount'] = $this->get_simple_xml_value(
$xml,
"cbc:LineExtensionAmount");
325 $result[
'TaxExclusiveAmount'] = $this->get_simple_xml_value(
$xml,
"cbc:TaxExclusiveAmount");
326 $result[
'TaxInclusiveAmount'] = $this->get_simple_xml_value(
$xml,
"cbc:TaxInclusiveAmount");
327 $result[
'PayableAmount'] = $this->get_simple_xml_value(
$xml,
"cbc:PayableAmount");
328 $result[
'AllowanceTotalAmount'] = $this->get_simple_xml_value(
$xml,
"cbc:AllowanceTotalAmount");
329 $result[
'AllowanceTotalAmount'] = (
$result[
'AllowanceTotalAmount'] ==
"") ? 0 :
$result[
'AllowanceTotalAmount'];
330 $result[
'ChargeTotalAmount'] = $this->get_simple_xml_value(
$xml,
"cbc:ChargeTotalAmount");
331 $result[
'ChargeTotalAmount'] = (
$result[
'ChargeTotalAmount'] ==
"") ? 0 :
$result[
'ChargeTotalAmount'];
358 function get_allowance(): array
361 $node=$this->get_node(
"//cac:AllowanceCharge");
366 for (
$e = 0;
$e < $node->length;
$e++)
369 $row[
'ChargeIndicator'] = $this->get_node_value(
'//cac:AllowanceCharge/cbc:ChargeIndicator',
$e);
370 $row[
'AllowanceChargeReasonCode'] = $this->get_node_value(
'//cac:AllowanceCharge/cbc:AllowanceChargeReasonCode',
$e);
371 $row[
'AllowanceChargeReason'] = $this->get_node_value(
'//cac:AllowanceCharge/cbc:AllowanceChargeReason',
$e);
372 $row[
'amount'] = $this->get_node_value(
'//cac:AllowanceCharge/cbc:Amount',
$e);
373 $row[
'tva_id'] = $this->get_node_value(
'//cac:AllowanceCharge/cac:TaxCategory/cbc:ID',
$e);
374 $row[
'tva_percent'] = $this->get_node_value(
'//cac:AllowanceCharge/cac:TaxCategory/cbc:Percent',
$e);
383 abstract function get_document_type_code();
390 function get_info(): array
393 $result[
'id'] = $this->get_node_value(
'cbc:ID');
394 $result[
'IssueDate'] = $this->get_node_value(
'cbc:IssueDate');
395 $result[
'DueDate'] = $this->get_node_value(
'cbc:DueDate');
396 $result[
'InvoiceTypeCode'] =$this->get_document_type_code();
397 $result[
'DocumentCurrencyCode'] = $this->get_node_value(
'cbc:DocumentCurrencyCode');
398 $result[
'BuyerReference'] = $this->get_node_value(
'cbc:BuyerReference');
399 $result[
'ActualDeliveryDate'] = $this->get_node_value(
'//cac:Delivery[1]/cbc:ActualDeliveryDate[1]');
402 $result[
'info'][
'note']=$this->get_node_value(
"//cbc:Note");
416 public function to_pdf(): PDF
423 $pdf->AliasNbPages();
424 $pdf->setAuthor(
"Noalyss");
427 $pdf->setFont(
"DejaVu",
"B", 16);
428 $pdf->write_cell(20, 10,
"");
429 $pdf->write_cell(170, 10,
_(
"Résumé facture"),1,0,
'C');
431 $pdf->setFont(
"DejaVu",
"", 7);
432 $pdf->write(4, sprintf(
_(
"Document ID %s"),
$result[
'id']));
434 $pdf->write(4, sprintf(
_(
"Date facture %s"),
$result[
'IssueDate']));
436 $pdf->write(4, sprintf(
_(
"Date échéance %s"),
$result[
'DueDate']));
438 $pdf->write(4, sprintf(
_(
"Type et code document %s"),
$result[
'InvoiceTypeCode']));
440 $pdf->write(4, sprintf(
_(
"Devise document %s"),
$result[
'DocumentCurrencyCode']));
442 $pdf->write(4, sprintf(
_(
"Référence client %s"),
$result[
'BuyerReference']));
444 $pdf->write(4, sprintf(
_(
"Date Livraison %s"),
$result[
'ActualDeliveryDate']));
447 $pdf->setFont(
"DejaVu",
"B", 12);
448 $pdf->write_cell(60, 4,
_(
"Fournisseur"));
451 $pdf->setFont(
"DejaVu",
"", 7);
462 $customer = $this->get_customer();
463 $pdf->setFont(
"DejaVu",
"B", 12);
464 $pdf->write_cell(60, 4,
_(
"Client"));
466 $pdf->setFont(
"DejaVu",
"", 7);
467 $pdf->write_cell(60, 4, $customer[
'name']);
468 $pdf->write_cell(60, 4, $customer[
'company_id']);
469 $pdf->write_cell(60, 4, $customer[
'scheme'].
":".$customer[
'ID']);
471 $pdf->write_cell(60, 4, $customer[
'street']);
472 $pdf->write_cell(40, 4, $customer[
'postcode']);
473 $pdf->write_cell(60, 4, $customer[
'city']);
474 $pdf->write_cell(20, 4, $customer[
'country_code']);
479 if ( $info[
'info'][
'note'] !=
"")
481 $pdf->setFont(
"DejaVu",
"B", 12);
482 $pdf->write_cell(60, 4,
_(
"Notes"));
484 $pdf->setFont(
"DejaVu",
"", 7);
485 $pdf->write_multi(50, 4,$info[
'info'][
'note']);
491 $pdf->setFont(
"DejaVu",
"B", 12);
492 $pdf->write_cell(60, 4,
_(
"Articles"));
494 $pdf->setFont(
"DejaVu",
"", 7);
495 $result = $this->get_invoiceLine();
496 $pdf->write_cell(50, 4,
_(
"Code"), border:
'B');
497 $pdf->write_cell(50, 4,
_(
"Description"), border:
'B');
498 $pdf->write_cell(30, 4,
_(
"TVA"), border:
'B', align:
'R');
499 $pdf->write_cell(25, 4,
_(
"Quantité"), border:
'B', align:
'R');
500 $pdf->write_cell(25, 4,
_(
"Montant HT"), border:
'B', align:
'R');
504 for (
$i = 0;
$i < $nb_inline;
$i++)
508 $pdf->write_cell(25, 4,
$result[
$i][
'tva_percent'], align:
'R');
510 $pdf->write_cell(25, 4,
$result[
$i][
'quantity'], align:
'R');
516 $pdf->setFont(
"DejaVu",
"B", 12);
517 $pdf->write_cell(60, 4,
_(
"Totaux"));
519 $pdf->setFont(
"DejaVu",
"", 7);
520 $result = $this->get_amount_summary();
522 $pdf->write_cell(50, 4,
_(
"Base taxe"));
523 $pdf->write_cell(50, 4,
nbm(
$result[
'LineExtensionAmount']),align:
'R');
525 $pdf->write_cell(50, 4,
_(
"Total Hors Taxe"));
526 $pdf->write_cell(50, 4,
nbm(
$result[
'TaxExclusiveAmount']),align:
'R');
528 $pdf->write_cell(50, 4,
_(
"Total avec Taxe"));
529 $pdf->write_cell(50, 4,
nbm(
$result[
'TaxInclusiveAmount']),align:
'R');
531 $pdf->write_cell(50, 4,
_(
"Total à payer"));
534 $pdf->write_cell(50, 4,
_(
"Total réduction"));
535 $pdf->write_cell(50, 4,
nbm(
$result[
'AllowanceTotalAmount']),align:
'R');
537 $pdf->write_cell(50, 4,
_(
"Total charge"));
538 $pdf->write_cell(50, 4,
nbm(
$result[
'ChargeTotalAmount']),align:
'R');
540 $result=$this->get_allowance();
544 $pdf->setFont(
"DejaVu",
"B", 12);
545 $pdf->write_cell(60, 4,
_(
"Charge et déduction"));
547 $pdf->setFont(
"DejaVu",
"", 7);
548 $pdf->write_cell(20, 4,
_(
"code"), align:
'L', border:
'1');
549 $pdf->write_cell(20, 4,
_(
"Type"), border:
'1');
550 $pdf->write_cell(55, 4,
_(
"Raison"), align:
'L', border:
'1');
551 $pdf->write_cell(30, 4,
_(
"Montant"), align:
'R', border:
'1');
552 $pdf->write_cell(30, 4,
_(
"TVA"), align:
'L', border:
'1');
554 for (
$i = 0;
$i < $nb_inline;
$i++)
556 $pdf->write_cell(20, 4,
$result[
$i][
'AllowanceChargeReasonCode'], align:
'L');
557 if (
$result[
$i][
'ChargeIndicator'] ==
'false')
559 $pdf->write_cell(20, 4,
_(
"Déduction"), align:
'L');
562 $pdf->write_cell(20, 4,
_(
"Charge suppl."), align:
'L');
565 $pdf->write_cell(55, 4,
$result[
$i][
'AllowanceChargeReason'], align:
'L');
568 $pdf->write_cell(25, 4,
$result[
$i][
'tva_percent'], align:
'R');
573 $pdf->setFont(
"DejaVu",
"B", 12);
574 $pdf->write_cell(60, 4,
_(
"TVA"));
576 $pdf->setFont(
"DejaVu",
"", 7);
578 $pdf->write_cell(25, 4,
_(
"% Taxe"), align:
'R', border:
'B');
579 $pdf->write_cell(5, 4,
_(
"Code taxe"), border:
'B');
580 $pdf->write_cell(50, 4,
_(
"Base"), align:
'R', border:
'B');
581 $pdf->write_cell(50, 4,
_(
"Taxe"), align:
'R', border:
'B');
584 for (
$i = 0;
$i < $nb_inline;
$i++)
586 $pdf->write_cell(25, 4,
$result[
$i][
'tax_percent'], align:
'R');
597 $pdf->setFont(
"DejaVu",
"B", 12);
598 $pdf->write_cell(60, 4,
_(
"Paiement"));
600 $pdf->setFont(
"DejaVu",
"", 7);
601 $result = $this->get_payment_mean();
602 $pdf->write_cell(50, 4,
_(
"Code"));
605 $pdf->write_cell(50, 4,
_(
"IBAN"));
608 $pdf->write_cell(50, 4,
_(
"BIC"));
611 $pdf->write_cell(50, 4,
_(
"Communication"));
614 $nb_note = count(
$result[
'note']);
615 for (
$i = 0;
$i < $nb_note;
$i++)
617 $pdf->write_cell(40, 4,
_(
"note") .
" " .
$i);
618 $pdf->write_multi(140, 4, str_replace([
"\n",
"\r",
"\t"],
" ",
$result[
'note'][
$i]));
625 $result=$this->get_embedded_document();
628 $pdf->setFont(
"DejaVu",
"B", 12);
629 $pdf->write_cell(60,4,
_(
'Documents inclus'));
631 $pdf->setFont(
"DejaVu",
"", 7);
637 $pdf->write_multi(50,4,$binary->filename);
nbm($p_number, $p_dec=2)
format the number with a sep.
for( $i=0;$i< $nb_match;$i++) if(empty($result)) $nb_result
_("actif, passif,charge,...")
if( $delta< 0) elseif( $delta==0)