Files
crm.e5.pl/modules/EcmInvoiceOuts/invoiceEdiXML.php
2024-04-27 09:23:34 +02:00

510 lines
25 KiB
PHP

<?php
class invoiceEdiXML
{
private $xml;
private $id;
private $i;
private $ediInvoicesPath = '/var/edi/e5/invoices/';
function invoiceEdiXML ($id)
{
$this->id = $id;
$this->i = new EcmInvoiceOut();
$this->i->retrieve($this->id);
}
public function getXML () {
$i = $this->i;
if ($i->type == 'normal')
$this->xml = $this->createInvoiceXML();
elseif ($i->type == 'correct')
$this->xml = $this->createCorrectInvoiceXML();
$this->xml->flush();
}
private function createInvoiceXML () {
global $timedate;
$db = $GLOBALS['db'];
$i = $this->i;
// get data
// get WZ && Sale info
$wz = $db->fetchByAssoc(
$db->query(
"SELECT shipping_iln,parent_id, document_no, register_date, ecmsale_id FROM ecmstockdocouts WHERE id ='$i->wz_id'"));
$sale = $db->fetchByAssoc(
$db->query(
"SELECT document_no, register_date, parent_document_no FROM ecmsales WHERE id = '" .
$wz['ecmsale_id'] . "'"));
// get ILNs
$shipping_iln = $db->fetchByAssoc($db->query("SELECT iln FROM "));
$xml = new XMLWriter();
$name = str_replace('/', '_', $i->document_no);
$name = str_replace(' ', '', $name);
$name = str_replace('FV', '', $name);
$xml->openURI($this->ediInvoicesPath . $name . '.xml');
// $this->p->openMemory();
$xml->startDocument('1.0', 'UTF-8');
$xml->startElement('Document-Invoice');
$xml->startElement('Invoice-Header');
$xml->writeElement('InvoiceNumber', $i->document_no);
$xml->writeElement('InvoiceDate',
$timedate->to_db_date($i->register_date));
$xml->writeElement('SalesDate', $timedate->to_db_date($i->sell_date));
$c = new Currency();
$c->retrieve($i->currency_id);
$xml->writeElement('InvoiceCurrency', $c->iso4217);
unset($c);
$xml->writeElement('InvoicePaymentDueDate',
$timedate->to_db_date($i->payment_date));
$pc = new EcmPaymentCondition();
$pc->retrieve($i->ecmpaymentcondition_id);
$xml->writeElement('InvoicePaymentTerms', $pc->days);
unset($pc);
$xml->writeElement('InvoicePostDate',
$timedate->to_db_date($i->register_date));
$xml->writeElement('DocumentFunctionCode', 'O');
$xml->startElement('Order');
$xml->writeElement('BuyerOrderNumber', $sale['parent_document_no']);
$xml->writeElement('BuyerOrderDate', $sale['register_date']);
$xml->endElement(); // </Line-Order>
$xml->startElement('Delivery');
$xml->writeElement('DeliveryLocationNumber', $wz['shipping_iln']);
$xml->writeElement('DespatchNumber', $wz['document_no']);
$xml->writeElement('DeliveryDate', $wz['register_date']);
$xml->endElement(); // </Line-Delivery>
$xml->endElement(); // </Invoice-Header>
$xml->startElement('Invoice-Parties');
$xml->startElement('Buyer');
$a = new Account();
$a->retrieve($i->parent_id);
if (! $i->parent_iln || $i->parent_iln == '')
$i->parent_iln = $a->iln;
unset($a);
$xml->writeElement('ILN', $i->parent_iln);
$xml->writeElement('TaxID', $i->parent_nip);
$xml->writeElement('Name', $i->parent_name);
$xml->writeElement('StreetAndNumber', $i->parent_address_street);
$xml->writeElement('CityName', $i->parent_address_city);
$xml->writeElement('PostalCode', $i->parent_address_postalcode);
$xml->writeElement('Country', 'PL');
$xml->endElement(); // </Buyer>
$xml->startElement('Invoicee');
$a = new Account();
$a->retrieve($i->parent_id);
if (! $i->parent_iln || $i->parent_iln == '')
$i->parent_iln = $a->iln;
unset($a);
$xml->writeElement('ILN', $i->parent_iln);
$xml->writeElement('TaxID', $i->parent_nip);
$xml->writeElement('Name', $i->parent_name);
$xml->writeElement('StreetAndNumber', $i->parent_address_street);
$xml->writeElement('CityName', $i->parent_address_city);
$xml->writeElement('PostalCode', $i->parent_address_postalcode);
$xml->writeElement('Country', 'PL');
$xml->endElement(); // </Invoicee>
$xml->startElement('Payer');
if ($i->parent_payer_address_name && $i->parent_payer_address_name != "") {
$iln = $db->fetchByAssoc(
$db->query(
"SELECT iln, to_vatid FROM accounts WHERE name = '" .
$i->parent_payer_address_name . "'"));
$xml->writeElement('ILN', $iln['iln']);
$xml->writeElement('TaxID', $iln['to_vatid']);
$xml->writeElement('Name', 'Carrefour Polska Sp z o.o.');
$xml->writeElement('StreetAndNumber',
$i->parent_payer_address_street);
$xml->writeElement('CityName', $i->parent_payer_address_city);
$xml->writeElement('PostalCode',
$i->parent_payer_address_postalcode);
$xml->writeElement('Country', 'PL');
} else {
$a = new Account();
$a->retrieve($i->parent_id);
if (! $i->parent_iln || $i->parent_iln == '')
$i->parent_iln = $a->iln;
unset($a);
$xml->writeElement('ILN', $i->parent_iln);
$xml->writeElement('TaxID', $i->parent_nip);
$xml->writeElement('Name', 'Carrefour Polska Sp z o.o.');
$xml->writeElement('StreetAndNumber', $i->parent_address_street);
$xml->writeElement('CityName', $i->parent_address_city);
$xml->writeElement('PostalCode', $i->parent_address_postalcode);
$xml->writeElement('Country', 'PL');
}
$xml->endElement(); // </Payer>
$e5_info = array(
'Seller',
'Payee',
'SellerHeadquarters'
);
foreach ($e5_info as $val) {
$xml->startElement($val);
$xml->writeElement('ILN', '5909000035836');
if ($val != 'SellerHeadquarters')
$xml->writeElement('TaxID', '5252173990');
$xml->writeElement('Name', 'e5 Polska Sp. z o.o.');
$xml->writeElement('StreetAndNumber', 'Wąwozowa 11');
$xml->writeElement('CityName', 'Warszawa');
$xml->writeElement('PostalCode', '02-796');
$xml->writeElement('Country', 'PL');
if ($val == 'Seller')
$xml->writeElement('CodeByBuyer', '23862');
$xml->endElement();
}
$xml->endElement(); // </Invoice-Parties>
$xml->startElement('Invoice-Lines');
$pl = $i->getPositionList(true);
foreach ($pl as $p) {
$xml->startElement('Line');
$xml->startElement('Line-Item');
$xml->writeElement('LineNumber', $p['position'] + 1);
$xml->writeElement('BuyerItemCode', $p['recipient_code']);
$xml->writeElement('EAN', $p['product_ean']);
$xml->writeElement('SupplierItemCode', $p['product_code']);
// prepare name
if (strlen($p['name']) > 70){
mb_internal_encoding("UTF-8");
$p['name'] = mb_substr($p['name'], 0, 67, "utf-8") . '...';
}
$xml->writeElement('ItemDescription', $p['name']);
$xml->writeElement('ItemType', 'CU');
$xml->writeElement('InvoiceQuantity', $p['quantity']);
$xml->writeElement('UnitOfMeasure', 'PCE');
$xml->writeElement('InvoiceUnitPacksize', '1');
$xml->writeElement('PackItemUnitOfMeasure', 'PCE');
$xml->writeElement('InvoiceUnitNetPrice', $p['price_netto']);
$xml->writeElement('TaxRate', $p['ecmvat_value']);
$xml->writeElement('TaxCategoryCode', 'S');
$xml->writeElement('TaxAmount', $p['total_vat']);
$xml->writeElement('NetAmount', $p['total_netto']);
$xml->endElement(); // </Line>
$xml->endElement(); // </Line-Item>
}
$xml->endElement(); // </Invoice-Lines>
$xml->startElement('Invoice-Summary');
$xml->writeElement('TotalLines', sizeof($pl));
$xml->writeElement('TotalNetAmount', $i->total_netto);
$xml->writeElement('TotalTaxableBasis', $i->total_netto);
$xml->writeElement('TotalTaxAmount', $i->total_vat);
$xml->writeElement('TotalGrossAmount', $i->total_brutto);
$xml->startElement('Tax-Summary');
$vats = explode(',', $i->vats_summary);
array_pop($vats);
foreach ($vats as $v) {
$vat = explode(':',$v);
$xml->startElement('Tax-Summary-Line');
$xml->writeElement('TaxRate', explode('%', $vat[0])[0]);
$xml->writeElement('TaxCategoryCode', 'S');
$xml->writeElement('TaxAmount', $vat[2]);
$xml->writeElement('TaxableBasis', $vat[1]);
$xml->writeElement('TaxableAmount', $vat[1]);
$xml->writeElement('GrossAmount', $vat[3]);
$xml->endElement(); // </Tax-Summary-Line>
}
$xml->endElement(); // </Tax-Summary>
$xml->endElement(); // </Invoice-Summary>
$xml->endElement(); // </Document-Invoice>
return $xml;
}
private function createCorrectInvoiceXML () {
global $timedate;
$db = $GLOBALS['db'];
$i = $this->i;
$oldInvoice = $db->fetchByAssoc($db->query("
SELECT total_netto, total_brutto, total_vat, vats_summary, document_no, register_date
FROM ecminvoiceouts WHERE id='".$i->ecminvoiceout_id."'"));
$xml = new XMLWriter();
$name = str_replace('/', '_', $i->document_no);
$name = str_replace(' ', '', $name);
$name = str_replace('FV', '', $name);
$xml->openURI($this->ediInvoicesPath . $name . '.xml');
$xml->startDocument('1.0', 'UTF-8');
$xml->startElement('Document-Invoice');
$xml->startElement('Invoice-Header');
// FIX $xml->writeElement('InvoiceNumber', $i->document_no);
$xml->writeElement('InvoiceNumber', 'FVKOR 04/TEST/23');
// FIX $xml->writeElement('InvoiceDate',
// $timedate->to_db_date($i->register_date));
$xml->writeElement('InvoiceDate', '2023-08-01');
// FIX $xml->writeElement('SalesDate', $timedate->to_db_date($i->sell_date));
$xml->writeElement('SalesDate', '2023-08-01');
$c = new Currency();
$c->retrieve($i->currency_id);
$xml->writeElement('InvoiceCurrency', $c->iso4217);
unset($c);
$xml->writeElement('InvoicePaymentDueDate',
$timedate->to_db_date($i->payment_date));
$pc = new EcmPaymentCondition();
$pc->retrieve($i->ecmpaymentcondition_id);
$xml->writeElement('InvoicePaymentTerms', $pc->days);
unset($pc);
$xml->writeElement('InvoicePostDate',
$timedate->to_db_date($i->register_date));
$xml->writeElement('DocumentFunctionCode', 'C');
$xml->writeElement('CorrectionReason', 'zgł. rekl.030/19/P320');
$xml->startElement('Order');
$xml->writeElement('BuyerOrderNumber', end(explode(' ', $i->order_no)));
// FIX $xml->writeElement('BuyerOrderDate', $timedate->to_db_date($i->register_date));
$xml->writeElement('BuyerOrderDate', '2023-08-01');
$xml->endElement(); // </Line-Order>
$xml->startElement('Reference');
$xml->writeElement('InvoiceReferenceNumber', $oldInvoice['document_no']);
$xml->writeElement('InvoiceReferenceDate', $timedate->to_db_date($oldInvoice['register_date']));
$xml->endElement(); // </Reference>
$xml->startElement('Delivery');
$xml->writeElement('DeliveryLocationNumber', $i->parent_shipping_address_iln);
$xml->writeElement('DespatchNumber', $i->document_no);
$xml->writeElement('DeliveryDate', $timedate->to_db_date($i->register_date));
$xml->endElement(); // </Line-Delivery>
$xml->endElement(); // </Invoice-Header>
$xml->startElement('Invoice-Parties');
$xml->startElement('Buyer');
$a = new Account();
$a->retrieve($i->parent_id);
if (! $i->parent_iln || $i->parent_iln == '')
$i->parent_iln = $a->iln;
unset($a);
$xml->writeElement('ILN', $i->parent_iln);
$xml->writeElement('TaxID', $i->parent_nip);
$xml->writeElement('Name', $i->parent_name);
$xml->writeElement('StreetAndNumber', $i->parent_address_street);
$xml->writeElement('CityName', $i->parent_address_city);
$xml->writeElement('PostalCode', $i->parent_address_postalcode);
$xml->writeElement('Country', 'PL');
$xml->endElement(); // </Buyer>
$xml->startElement('Invoicee');
$a = new Account();
$a->retrieve($i->parent_id);
if (! $i->parent_iln || $i->parent_iln == '')
$i->parent_iln = $a->iln;
unset($a);
$xml->writeElement('ILN', $i->parent_iln);
$xml->writeElement('TaxID', $i->parent_nip);
$xml->writeElement('Name', $i->parent_name);
$xml->writeElement('StreetAndNumber', $i->parent_address_street);
$xml->writeElement('CityName', $i->parent_address_city);
$xml->writeElement('PostalCode', $i->parent_address_postalcode);
$xml->writeElement('Country', 'PL');
$xml->endElement(); // </Invoicee>
$xml->startElement('Payer');
if ($i->parent_payer_address_name && $i->parent_payer_address_name != "") {
$iln = $db->fetchByAssoc(
$db->query(
"SELECT iln, to_vatid FROM accounts WHERE name = '" .
$i->parent_payer_address_name . "'"));
$xml->writeElement('ILN', $iln['iln']);
$xml->writeElement('TaxID', $iln['to_vatid']);
$xml->writeElement('Name', 'Carrefour Polska Sp z o.o.');
$xml->writeElement('StreetAndNumber',
$i->parent_payer_address_street);
$xml->writeElement('CityName', $i->parent_payer_address_city);
$xml->writeElement('PostalCode',
$i->parent_payer_address_postalcode);
$xml->writeElement('Country', 'PL');
} else {
$a = new Account();
$a->retrieve($i->parent_id);
if (! $i->parent_iln || $i->parent_iln == '')
$i->parent_iln = $a->iln;
unset($a);
$xml->writeElement('ILN', $i->parent_iln);
$xml->writeElement('TaxID', $i->parent_nip);
$xml->writeElement('Name', 'Carrefour Polska Sp z o.o.');
$xml->writeElement('StreetAndNumber', $i->parent_address_street);
$xml->writeElement('CityName', $i->parent_address_city);
$xml->writeElement('PostalCode', $i->parent_address_postalcode);
$xml->writeElement('Country', 'PL');
}
$xml->endElement(); // </Payer>
$e5_info = array(
'Seller',
'Payee',
'SellerHeadquarters'
);
foreach ($e5_info as $val) {
$xml->startElement($val);
// FIX $xml->writeElement('ILN', '5909000035836');
$xml->writeElement('ILN', '5909000896239');
if ($val != 'SellerHeadquarters')
// FIX $xml->writeElement('TaxID', '5252173990');
$xml->writeElement('TaxID', '8792676609');
// FIX $xml->writeElement('Name', 'e5 Polska Sp. z o.o.');
$xml->writeElement('Name', 'Twinpol Sp. z o.o.');
// FIX $xml->writeElement('StreetAndNumber', 'Wąwozowa 11');
$xml->writeElement('StreetAndNumber', 'Al. Lipowa 48');
// FIX $xml->writeElement('CityName', 'Warszawa');
$xml->writeElement('CityName', 'Obrowo');
// FIX $xml->writeElement('PostalCode', '02-796');
$xml->writeElement('PostalCode', '87-126');
$xml->writeElement('Country', 'PL');
if ($val == 'Seller')
// FIX $xml->writeElement('CodeByBuyer', '23862');
$xml->writeElement('CodeByBuyer', '017776');
$xml->endElement();
}
$xml->endElement(); // </Invoice-Parties>
$xml->startElement('Invoice-Lines');
$products = $db->query("
SELECT i.code, i.position, i.recipient_code, i.ean, i.name,
i.quantity, i.price_netto, i.total_netto, i.total_vat, i.total_brutto, i.ecmvat_value,
c.quantity as c_quantity, c.price_netto as c_price_netto,
c.total_netto as c_total_netto, c.total_vat as c_total_vat,
c.total_brutto as c_total_brutto, c.ecmvat_value as c_ecmvat_value
FROM ecminvoiceoutitems as i
LEFT JOIN ecminvoiceoutitems as c ON i.id = c.ecminvoiceoutitem_id
WHERE i.ecminvoiceout_id = '".$i->ecminvoiceout_id."'
");
$sum = Array();
$sum['total_netto'] = 0;
$sum['total_vat'] = 0;
$sum['total_brutto'] = 0;
$sum['c_total_netto'] = 0;
$sum['c_total_vat'] = 0;
$sum['c_total_brutto'] = 0;
$sum['vats'] = array();
while ($p = $db->fetchByAssoc($products)) {
$xml->startElement('Line');
$xml->startElement('Line-Item');
$xml->writeElement('LineNumber', $p['position'] + 1);
$xml->writeElement('BuyerItemCode', $p['recipient_code']);
$xml->writeElement('EAN', $p['ean']);
$xml->writeElement('SupplierItemCode', $p['code']);
// prepare name
if (strlen($p['name']) > 70){
mb_internal_encoding("UTF-8");
$p['name'] = mb_substr($p['name'], 0, 67, "utf-8") . '...';
}
$xml->writeElement('ItemDescription', $p['name']);
$xml->writeElement('ItemType', 'CU');
$xml->writeElement('UnitOfMeasure', 'PCE');
$xml->writeElement('InvoiceUnitPacksize', '1');
$xml->writeElement('PackItemUnitOfMeasure', 'PCE');
if ($p['c_quantity'] == null) {
$p['c_quantity'] = $p['quantity'];
$p['c_price_netto'] = $p['price_netto'];
$p['c_total_netto'] = $p['total_netto'];
$p['c_total_vat'] = $p['total_vat'];
$p['c_total_brutto'] = $p['total_brutto'];
$p['c_ecmvat_value'] = $p['ecmvat_value'];
}
$xml->writeElement('InvoiceQuantity', $p['c_quantity']);
$xml->writeElement('InvoiceUnitNetPrice', $p['c_price_netto']);
$xml->writeElement('TaxRate', $p['c_ecmvat_value']);
$xml->writeElement('TaxCategoryCode', 'S');
$xml->writeElement('TaxAmount', $p['c_total_vat']);
$xml->writeElement('NetAmount', $p['c_total_netto']);
$xml->writeElement('PreviousInvoiceQuantity', $p['quantity']);
$xml->writeElement('PreviousInvoiceUnitNetPrice', $p['price_netto']);
// $xml->writeElement('PreviousTaxRate', $p['total_vat']);
$xml->writeElement('PreviousTaxCategoryCode', 'S');
$xml->writeElement('PreviousTaxRate', $p['ecmvat_value']);
$xml->writeElement('PreviousTaxAmount', $p['total_vat']);
$xml->writeElement('PreviousNetAmount', $p['total_netto']);
$xml->writeElement('CorrectionInvoiceQuantity', round($p['c_quantity'] - $p['quantity'],2));
$xml->writeElement('CorrectionInvoiceUnitNetPrice', round($p['c_price_netto'] - $p['price_netto'],2));
$xml->writeElement('CorrectionTaxAmount', round($p['c_total_vat'] - $p['total_vat'],2));
$xml->writeElement('CorrectionNetAmount', round($p['c_total_netto'] - $p['total_netto'],2));
$xml->endElement(); // </Line>
$xml->endElement(); // </Line-Item>
$sum['total_netto'] += $p['total_netto'];
$sum['c_total_netto'] += $p['c_total_netto'];
$sum['total_vat'] += $p['total_vat'];
$sum['c_total_vat'] += $p['c_total_vat'];
$sum['total_brutto'] += $p['total_brutto'];
$sum['c_total_brutto'] += $p['c_total_brutto'];
if ($sum['vats'][$p['ecmvat_value']] == null) {
$sum['vats'][$p['ecmvat_value']]['netto'] = $p['total_netto'];
$sum['vats'][$p['ecmvat_value']]['vat'] = $p['total_vat'];
$sum['vats'][$p['ecmvat_value']]['brutto'] = $p['total_brutto'];
$sum['vats'][$p['ecmvat_value']]['c_netto'] = 0;
$sum['vats'][$p['ecmvat_value']]['c_netto'] = 0;
$sum['vats'][$p['ecmvat_value']]['c_netto'] = 0;
} else {
$sum['vats'][$p['ecmvat_value']]['netto'] += $p['total_netto'];
$sum['vats'][$p['ecmvat_value']]['vat'] += $p['total_vat'];
$sum['vats'][$p['ecmvat_value']]['brutto'] += $p['total_brutto'];
}
if ($sum['vats'][$p['c_ecmvat_value']] == null) {
$sum['vats'][$p['c_ecmvat_value']]['c_netto'] = $p['c_total_netto'];
$sum['vats'][$p['c_ecmvat_value']]['c_vat'] = $p['c_total_vat'];
$sum['vats'][$p['c_ecmvat_value']]['c_brutto'] = $p['c_total_brutto'];
$sum['vats'][$p['c_ecmvat_value']]['netto'] = 0;
$sum['vats'][$p['c_ecmvat_value']]['netto'] = 0;
$sum['vats'][$p['c_ecmvat_value']]['netto'] = 0;
} else {
$sum['vats'][$p['c_ecmvat_value']]['c_netto'] += $p['c_total_netto'];
$sum['vats'][$p['c_ecmvat_value']]['c_vat'] += $p['c_total_vat'];
$sum['vats'][$p['c_ecmvat_value']]['c_brutto'] += $p['c_total_brutto'];
}
}
$xml->endElement(); // </Invoice-Lines>
$xml->startElement('Invoice-Summary');
$xml->writeElement('TotalLines', $products->num_rows);
$xml->writeElement('TotalNetAmount', $sum['c_total_netto']);
$xml->writeElement('TotalTaxableBasis', $sum['c_total_netto']);
$xml->writeElement('TotalTaxAmount', $sum['c_total_vat']);
$xml->writeElement('TotalGrossAmount', $sum['c_total_brutto']);
$xml->writeElement('PreviousTotalNetAmount', $sum['total_netto']);
$xml->writeElement('PreviousTotalTaxableBasis', $sum['total_netto']);
$xml->writeElement('PreviousTotalTaxAmount', $sum['total_vat']);
$xml->writeElement('PreviousTotalGrossAmount', $sum['total_brutto']);
$xml->writeElement('CorrectionTotalNetAmount', round($sum['c_total_netto'] - $sum['total_netto'],2));
$xml->writeElement('CorrectionTotalTaxableBasis', round($sum['c_total_netto'] - $sum['total_netto'],2));
$xml->writeElement('CorrectionTotalTaxAmount', round($sum['c_total_vat'] - $sum['total_vat'],2));
$xml->writeElement('CorrectionTotalGrossAmount', round($sum['c_total_brutto'] - $sum['total_brutto'],2));
$xml->startElement('Tax-Summary');
// checking
if ($i->total_netto != round($sum['c_total_netto'] - $sum['total_netto'],2)) {
die("Błąd sumy podczas generowania pliku XML. Skontaktuj się z administratorem.");
}
foreach ($sum['vats'] as $k=>$v) {
$xml->startElement('Tax-Summary-Line');
$xml->writeElement('TaxRate', $k);
$xml->writeElement('TaxCategoryCode', 'S');
$xml->writeElement('TaxAmount', $v['c_vat']);
$xml->writeElement('TaxableAmount', $v['c_netto']);
$xml->writeElement('PreviousTaxRate', $k);
$xml->writeElement('PreviousTaxCategoryCode', 'S');
$xml->writeElement('PreviousTaxAmount', $v['vat']);
$xml->writeElement('PreviousTaxableAmount', $v['netto']);
$xml->writeElement('CorrectionTaxAmount', round($v['c_vat'] - $v['vat'],2));
$xml->writeElement('CorrectionTaxableAmount', round($v['c_netto'] - $v['netto'],2));
$xml->endElement(); // </Tax-Summary-Line>
}
$xml->endElement(); // </Tax-Summary>
$xml->endElement(); // </Invoice-Summary>
$xml->endElement(); // </Document-Invoice>
return $xml;
}
}
?>