Files
crm.e5.pl/REST/functions.php
zzdrojewskipaw e8054f08fa createCSVReorts()
2025-08-26 22:14:04 +02:00

506 lines
18 KiB
PHP

<?php
function sendInvoice($record) {
require_once('modules/EcmInvoiceOuts/EcmInvoiceOut.php');
$inv = new EcmInvoiceOut();
$inv->retrieve($record);
$pl = $inv->getPositionList();
$response = array (
'document_no' => $inv->document_no,
'register_date' => $inv->register_date,
'payment_date' => $inv->payment_date,
'total_netto' => $inv->total_netto,
'total_brutto' => $inv->total_brutto,
'currency_id' => $inv->currency_id,
'currency_value' => $inv->currency_value,
'vats_summary' => $inv->vats_summary,
'position_list' => $pl
);
echo json_encode($response);
}
function sendProduct($record) {
require_once('modules/EcmProducts/EcmProduct.php');
$prod = new EcmProduct();
$prod->retrieve($record);
$response = array (
'name' => $prod->name,
'code' => $prod->code,
'ean' => $prod->ean,
'vat' => $prod->vat_value,
'unit_id' => $prod->unit_id,
'product_category_id' => $prod->product_category_id,
'product_category_name' => $prod->product_category_name
);
echo json_encode($response);
}
function copySaleFromTwinpol($record) {
$db = $GLOBALS['db'];
// check if sale exists
$exists = $db->fetchByAssoc($db->query("SELECT id, document_no FROM ecmsales WHERE edi_zs_id='$record'"));
if (isset($exists)) {
echo "ZS istnieje: ";
echo '<a target="new" href="https://crm.e5.pl/index.php?module=EcmSales&action=DetailView&record='.$exists['id'].'">'.$exists['document_no'].'</a>';
die();
}
$res = makeCUrlRequest("https://crm.twinpol.com/REST/index.php?key=d68dac4c-f784-4e1b-8267-9ffcfa0eda4c&action=getSale&record=".$record);
$sale = json_decode($res);
$sale->position_list = json_decode($sale->position_list);
echo "Numer dokumentu TwinPol: <b>".$sale->document_no."</b><br>";
$gotAllProducts = true; // hope :)
$newPositionList = array();
$total_netto = 0; $total_brutto = 0; $total_discount = 0; $vats = array();
foreach ( $sale->position_list as $product ) {
echo 'Produkt: '.$product->product_code;
$p = getProduct(trim($product->product_code));
if (!$p) {
echo '&nbsp;&nbsp;(produkt nie istnieje w bazie E5)<br>';
$gotAllProducts = false;
continue;
} else {
// pricebook price?
$pricebookPrice = $db->fetchByAssoc($db->query("
SELECT price FROM ecmpricebooks_ecmproducts
WHERE ecmpricebook_id = '3e78ac33-7c46-1b94-0a67-653a17c06f9e'
AND ecmproduct_id='$p->id'
AND deleted=0 LIMIT 0,1"));
if (isset($pricebookPrice)) {
$price_start = $pricebookPrice['price'];
echo " Cena: ".$price_start." (<a href=\"https://crm.e5.pl/index.php?module=EcmPriceBooks&action=DetailView&record=3e78ac33-7c46-1b94-0a67-653a17c06f9e\" target=\"new\">Amazon_2023</a>)<br>";
} else {
// invoice price?
$fvPrice = $db->fetchByAssoc($db->query("
SELECT i.id, i.document_no, ii.price_start, ii.ecmvat_value, ii.ecmvat_name, ii.ecmvat_id
FROM ecminvoiceoutitems AS ii
INNER JOIN ecminvoiceouts AS i
ON i.id = ii.ecminvoiceout_id
WHERE
i.parent_id= '1b9643ca-5b1a-8f9b-b809-586b5619b068' AND
i.currency_id = 'PLN' AND
ii.ecmproduct_id = '$p->id'
ORDER BY i.register_date DESC
LIMIT 0,1
"));
if (!isset($fvPrice)) {
$price_start = 0;
echo " <b>Brak ceny</b><br>";
$vat_id = $product->ecmvat_id;
$vat_name = $product->ecmvat_name;
$vat_value = $product->ecmvat_value;
} else {
$price_start = $fvPrice['price_start'];
$vat_id = $fvPrice['ecmvat_id'];
$vat_name = $fvPrice['ecmvat_name'];
$vat_value = $fvPrice['ecmvat_value'];
echo " Cena: ".$price_start." (<a href=\"https://crm.e5.pl/index.php?module=EcmInvoiceOuts&action=DetailView&record=".$fvPrice['id']."\" target=\"new\">".$fvPrice['document_no']."</a>)<br>";
}
}
$prod = array();
if (!isset($product->discount)) {
$product->discount = 0;
}
$prod['quantity'] = $product->quantity;
$prod['discount'] = $product->discount;
$prod['price_start'] = $price_start;
$prod['price_netto'] = round($price_start - ($price_start * ($product->discount / 100)),2);
$prod['ecmvat_id'] = $vat_id;
$prod['ecmvat_value'] = $vat_value;
$prod['ecmvat_name'] = $vat_name;
$prod['price_brutto'] = round($prod['price_netto']+($prod['price_netto']*($prod['ecmvat_value']/100)),2);
$prod['total_netto'] = round($prod['price_netto'] * $prod['quantity'], 2);
$prod['total_brutto'] = round($prod['total_netto']+($prod['total_netto']*($prod['ecmvat_value']/100)),2);
$total_netto += $prod['total_netto'];
$total_brutto += $prod['total_brutto'];
$total_discount = ($prod['price_start'] - $prod['price_netto']) * $prod['quantity'];
if (isset($vats[$prod['ecmvat_value']])) {
$vats[$prod['ecmvat_value']] += $prod['total_netto'];
} else {
$vats[$prod['ecmvat_value']] = $prod['total_netto'];
}
$prod['date_entered'] = date('Y-m-d H:i:s');
$prod['date_modified'] = date('Y-m-d H:i:s');
$prod['modified_user_id'] = null;
$prod['assigned_user_id'] = null;
$prod['created_by'] = null;
$prod['deleted'] = '0';
$prod['product_id'] = $p->id;
$prod['position'] = $product->position;
$prod['product_code'] = $p->code;
$prod['name'] = $product->name;
$prod['unit_id'] = $product->unit_id;
$prod['unit_name'] = $product->unit_name;
$prod['category_id'] = $p->product_category_id;
$prod['recipient_code'] = $product->recipient_code;
$prod['ean'] = $p->ean;
array_push($newPositionList, $prod);
}
}
$vats_summary = '';
foreach ($vats as $k=>$v ) {
$vats_summary .= $k.'%:'.$v.',';
}
if (!$gotAllProducts) {
echo 'Brak produktow w bazie E5. Dokument nie zostal skopiowany.';
die();
}
require_once('modules/EcmSales/EcmSale.php');
$new = new EcmSale();
$new->position_list = $newPositionList;
$new->parent_id = "1b9643ca-5b1a-8f9b-b809-586b5619b068";
$new->parent_name = "Twinpol Sp. z o.o.";
$new->parent_address_street = "al. Lipowa 48";
$new->parent_address_city = "Obrowo";
$new->parent_address_postalcode = "87-126";
$new->parent_address_country = "Polska";
$new->parent_nip = "8792676609";
$new->parent_iln = "5909000837119";
$new->pricebook_id = "13b29aa1-48f0-de58-7630-59c22756c5e4";
$new->status = "s30";
$new->type = "sales_order";
$new->name = $sale->name;
$new->ecmpaymentcondition_name = "90 dni";
$new->ecmpaymentcondition_id = "28de9f83-abd3-9a5d-4df9-4df9b7e0031f";
$new->parent_document_no = $sale->parent_document_no;
$new->register_date = $sale->register_date;
$new->send_date = $sale->send_date;
$new->delivery_date = $sale->delivery_date;
$new->ecmlanguage = "pl_pl";
$new->currency_id = 'PLN';
$new->total_netto = $total_netto;
$new->total_brutto = $total_brutto;
$new->discount = $total_discount;
$new->vats_summary = $vats_summary;
$new->shipping_address_name = $sale->parent_name;
$new->shipping_address_street = $sale->parent_address_street;
$new->shipping_address_postalcode = $sale->parent_address_postalcode;
$new->shipping_address_city = $sale->parent_address_city;
$new->shipping_address_country = $sale->parent_address_country;
$new->shipping_iln = $sale->parent_iln;
$new->shipping_nip = $sale->parent_nip;
$new->edi_zs_id = $sale->id;
$new->edi_zs_document_no = $sale->document_no;
$new->pdf_text =
"Dostawa
".$sale->shipping_address_name."
".$sale->shipping_address_street."
".$sale->shipping_address_postalcode." ".$sale->shipping_address_city."
".$sale->shipping_address_country."
NIP: ".$sale->shipping_nip."
ILN: ".$sale->shipping_iln;
$newId = $new->save(true);
//update E5 number in Twinpol
$res = $db->fetchByAssoc($db->query("SELECT document_no FROM ecmsales WHERE id='$newId'"));
$document_no = str_replace(" ", "%20", $res['document_no']);
makeCUrlRequest("https://crm.twinpol.com/REST/index.php?key=d68dac4c-f784-4e1b-8267-9ffcfa0eda4c&action=updateSaleE5Number&record=$record&e5_record=$newId&e5_document_no=$document_no");
echo '<a target="new" href="https://crm.e5.pl/index.php?module=EcmSales&action=DetailView&record='.$newId.'">Utworzono ZS.</a>';
die();
}
// local helpers
function getProduct($code) {
$db = $GLOBALS['db'];
$res = $db->fetchByAssoc($db->query("SELECT * FROM ecmproducts WHERE code='$code' AND deleted=0"));
if (!$res) {
return null;
} else {
require_once('modules/EcmProducts/EcmProduct.php');
$prod = new EcmProduct();
$prod->retrieve($res['id']);
return $prod;
}
}
function makeCUrlRequest($url) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET' );
curl_setopt($curl, CURLOPT_VERBOSE, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_URL, $url);
return curl_exec($curl);
}
function brecho($msg) {
echo '<br><br>';
var_dump($msg);
echo '<br><br>';
}
function createCSVReports()
{
{
$db = $GLOBALS['db'];
$exportDir = __DIR__ . "/export";
$jobs = [
[
'sql' => "
SELECT
i.document_no,
i.register_date,
i.parent_name,
p.code,
p.name,
CASE p.group_ks
WHEN 1 THEN 'Towar handlowy'
WHEN 2 THEN 'Wyrób gotowy'
WHEN 3 THEN 'Usługi'
WHEN '530547ef-2dea-7622-843b-59d745b14c64' THEN 'Materiały'
WHEN '8451dded-710f-51c2-7ed1-60a377eaa7b7' THEN 'Surowce'
ELSE 'Nieznane'
END AS group_ks,
GROUP_CONCAT(c.name ORDER BY cb.position SEPARATOR ' | ') AS category,
ii.quantity,
ii.price_netto
FROM ecminvoiceouts AS i
INNER JOIN ecminvoiceoutitems AS ii ON i.id = ii.ecminvoiceout_id
INNER JOIN ecmproducts AS p ON ii.ecmproduct_id = p.id
LEFT JOIN ecmproductcategories_bean AS cb ON cb.bean_id COLLATE utf8_general_ci = p.id COLLATE utf8_general_ci
AND cb.bean_name = 'EcmProducts'
AND cb.deleted = 0
LEFT JOIN ecmproductcategories AS c ON c.id = cb.ecmproductcategory_id
WHERE i.type = 'normal' AND YEAR(i.register_date) = 2024
GROUP BY
i.document_no,
i.register_date,
i.parent_name,
p.code,
p.name,
p.group_ks,
ii.quantity,
ii.price_netto
ORDER BY i.register_date DESC;
",
'filename' => 'invoices_2024.csv',
],
[
'sql' => "
SELECT
i.document_no,
i.register_date,
i.parent_name,
p.code,
p.name,
CASE p.group_ks
WHEN 1 THEN 'Towar handlowy'
WHEN 2 THEN 'Wyrób gotowy'
WHEN 3 THEN 'Usługi'
WHEN '530547ef-2dea-7622-843b-59d745b14c64' THEN 'Materiały'
WHEN '8451dded-710f-51c2-7ed1-60a377eaa7b7' THEN 'Surowce'
ELSE 'Nieznane'
END AS group_ks,
GROUP_CONCAT(c.name ORDER BY cb.position SEPARATOR ' | ') AS category,
ii.quantity,
ii.price_netto
FROM ecminvoiceouts AS i
INNER JOIN ecminvoiceoutitems AS ii ON i.id = ii.ecminvoiceout_id
INNER JOIN ecmproducts AS p ON ii.ecmproduct_id = p.id
LEFT JOIN ecmproductcategories_bean AS cb ON cb.bean_id COLLATE utf8_general_ci = p.id COLLATE utf8_general_ci
AND cb.bean_name = 'EcmProducts'
AND cb.deleted = 0
LEFT JOIN ecmproductcategories AS c ON c.id = cb.ecmproductcategory_id
WHERE i.type = 'normal' AND YEAR(i.register_date) = 2025
GROUP BY
i.document_no,
i.register_date,
i.parent_name,
p.code,
p.name,
p.group_ks,
ii.quantity,
ii.price_netto
ORDER BY i.register_date DESC;
",
'filename' => 'invoices_2025.csv',
],
[
'sql' => "
SELECT
i.document_no,
i.register_date,
i.parent_name,
p.code,
p.name,
CASE p.group_ks
WHEN 1 THEN 'Towar handlowy'
WHEN 2 THEN 'Wyrób gotowy'
WHEN 3 THEN 'Usługi'
WHEN '530547ef-2dea-7622-843b-59d745b14c64' THEN 'Materiały'
WHEN '8451dded-710f-51c2-7ed1-60a377eaa7b7' THEN 'Surowce'
ELSE 'Nieznane'
END AS group_ks,
GROUP_CONCAT(c.name ORDER BY cb.position SEPARATOR ' | ') AS category,
ii.quantity,
ii.price_netto
FROM ecommerce_invoices AS i
INNER JOIN ecommerce_invoices_products AS ii ON i.id = ii.invoice_id
INNER JOIN ecmproducts AS p ON ii.ecmproduct_id = p.id
LEFT JOIN ecmproductcategories_bean AS cb ON cb.bean_id COLLATE utf8_general_ci = p.id COLLATE utf8_general_ci
AND cb.bean_name = 'EcmProducts'
AND cb.deleted = 0
LEFT JOIN ecmproductcategories AS c ON c.id = cb.ecmproductcategory_id
WHERE i.type = 'normal' AND YEAR(i.register_date) = 2024
GROUP BY
i.document_no,
i.register_date,
i.parent_name,
p.code,
p.name,
p.group_ks,
ii.quantity,
ii.price_netto
ORDER BY i.register_date DESC;
",
'filename' => 'ecommerce_invoices_2024.csv',
],
[
'sql' => "
SELECT
i.document_no,
i.register_date,
i.parent_name,
p.code,
p.name,
CASE p.group_ks
WHEN 1 THEN 'Towar handlowy'
WHEN 2 THEN 'Wyrób gotowy'
WHEN 3 THEN 'Usługi'
WHEN '530547ef-2dea-7622-843b-59d745b14c64' THEN 'Materiały'
WHEN '8451dded-710f-51c2-7ed1-60a377eaa7b7' THEN 'Surowce'
ELSE 'Nieznane'
END AS group_ks,
GROUP_CONCAT(c.name ORDER BY cb.position SEPARATOR ' | ') AS category,
ii.quantity,
ii.price_netto
FROM ecommerce_invoices AS i
INNER JOIN ecommerce_invoices_products AS ii ON i.id = ii.invoice_id
INNER JOIN ecmproducts AS p ON ii.ecmproduct_id = p.id
LEFT JOIN ecmproductcategories_bean AS cb ON cb.bean_id COLLATE utf8_general_ci = p.id COLLATE utf8_general_ci
AND cb.bean_name = 'EcmProducts'
AND cb.deleted = 0
LEFT JOIN ecmproductcategories AS c ON c.id = cb.ecmproductcategory_id
WHERE i.type = 'normal' AND YEAR(i.register_date) = 2025
GROUP BY
i.document_no,
i.register_date,
i.parent_name,
p.code,
p.name,
p.group_ks,
ii.quantity,
ii.price_netto
ORDER BY i.register_date DESC;
",
'filename' => 'ecommerce_invoices_2025.csv',
],
[
'sql' => "
SELECT
ss.product_code,
ss.product_name,
COALESCE(NULLIF(ss.quantity, ''), 0) AS quantity,
s.name
FROM ecmstockstates AS ss
JOIN ecmstocks AS s ON ss.stock_id = s.id
ORDER BY quantity + 0 DESC;",
'filename' => 'stocks.csv',
],
];
$report = [];
foreach ($jobs as $job) {
$sql = $job['sql'];
$filename = $job['filename'];
$headers = isset($job['headers']) ? $job['headers'] : null;
$res = $db->query($sql);
$fullpath = rtrim($exportDir, "/") . "/" . $filename;
$result = exportToCSVFile($res, $fullpath, $headers, ';', true);
if ($result['ok']) {
$report[] = "OK → {$result['path']} (wiersze: {$result['rows']})".PHP_EOL;
} else {
$report[] = "ERR → {$result['path']} ({$result['error']})".PHP_EOL;;
}
}
echo implode("\n", $report);
exit;
}
}
function exportToCSVFile($res, $fullpath, array $headers = null, $delimiter = ';', $withBom = true)
{
$db = $GLOBALS['db'];
$dir = dirname($fullpath);
if (!is_dir($dir)) {
if (!@mkdir($dir, 0775, true)) {
return ['ok'=>false, 'path'=>$fullpath, 'rows'=>0, 'error'=>"Nie mogę utworzyć katalogu: $dir"];
}
}
if (!is_writable($dir)) {
return ['ok'=>false, 'path'=>$fullpath, 'rows'=>0, 'error'=>"Katalog nie jest zapisywalny: $dir"];
}
$fp = @fopen($fullpath, 'w');
if ($fp === false) {
return ['ok'=>false, 'path'=>$fullpath, 'rows'=>0, 'error'=>"Nie mogę otworzyć pliku do zapisu: $fullpath"];
}
// BOM dla Excel PL
if ($withBom) {
fwrite($fp, "\xEF\xBB\xBF");
}
// pobierz pierwszy wiersz, by ewentualnie zbudować nagłówki
$first = $db->fetchByAssoc($res);
// brak danych → pusty plik z ewentualnym nagłówkiem (jeśli podany ręcznie)
if (!$first) {
if ($headers !== null) {
fputcsv($fp, $headers, $delimiter);
}
fclose($fp);
return ['ok'=>true, 'path'=>$fullpath, 'rows'=>0, 'error'=>null];
}
// dynamiczne nagłówki, jeśli nie podano
if ($headers === null) {
$headers = array_keys($first);
}
// wypisz nagłówki
fputcsv($fp, $headers, $delimiter);
// zapisz pierwszy wiersz w kolejności nagłówków
$line = [];
foreach ($headers as $h) { $line[] = isset($first[$h]) ? $first[$h] : ''; }
fputcsv($fp, $line, $delimiter);
$count = 1;
// pozostałe wiersze
while ($row = $db->fetchByAssoc($res)) {
$line = [];
foreach ($headers as $h) { $line[] = isset($row[$h]) ? $row[$h] : ''; }
fputcsv($fp, $line, $delimiter);
$count++;
}
fclose($fp);
$chmod_ok = @chmod($fullpath, 0664);
return ['ok'=>true, 'path'=>$fullpath, 'rows'=>$count, 'chmod'=>$chmod_ok, 'error'=>null];
}