Compare commits

..

2 Commits

Author SHA1 Message Date
Michał Zieliński
aa4a2a6ebb import apilo invoices 2025-09-25 22:33:49 +02:00
Michał Zieliński
508cde0a68 import apilo invoices 2025-09-25 21:50:59 +02:00
4 changed files with 343 additions and 1 deletions

View File

@@ -77,10 +77,18 @@ function getInvoices($source, $date, $type)
$row['register_date'] = date('d.m.Y', strtotime($row['register_date']));
$row['sell_date'] = date('d.m.Y', strtotime($row['sell_date']));
$row['products'] = getInvoicProducts($row['id']);
$row['sum_by_products'] = getInvoiceSumByProducts($row['id']);
$invoices[] = $row;
}
return $invoices;
}
function getInvoiceSumByProducts($invoiceId) {
$db = $GLOBALS['db'];
$query = sprintf("SELECT SUM(ip.price_netto * ip.quantity) as sum FROM ecommerce_invoices_products as ip WHERE ip.invoice_id='%s'", $invoiceId);
$result = $db->query($query);
$row = $db->fetchByAssoc($result);
return $row['sum'];
}
function getInvoicProducts($invoiceId) {
$db = $GLOBALS['db'];
$query = sprintf("SELECT p.id, p.code, p.name, ip.price_netto, ip.price_brutto, ip.quantity, ip.code as ecommerce_code, ip.vat_value FROM ecommerce_invoices_products as ip INNER JOIN ecmproducts AS p ON ip.ecmproduct_id = p.id WHERE ip.invoice_id='%s'", $invoiceId);

View File

@@ -0,0 +1,322 @@
<?php
function importApiloInvoices()
{
$apilo_config = loadApiloConfiguration();
$db = $GLOBALS['db'];
$dbRes = $db->query("SELECT COUNT(id) as last_id FROM ecommerce_invoices WHERE origin = 'apilo'");
$offset = intval($db->fetchByAssoc($dbRes)['last_id']);
$invoices = loadApiloInvoices($apilo_config['token'], $offset);
if (isset($invoices->error)) {
if (refreshApiloToken($apilo_config['refresh_token'], $apilo_config['client_id'], $apilo_config['client_secret']) == true) {
$apilo_config = loadApiloConfiguration();
$invoices = loadApiloInvoices($apilo_config['access_token'], $offset);
} else {
die('Nie udało się odświeżyć tokena apilo');
}
}
brecho(count($invoices->documents));
$platforms = loadApiloPlatformsList($apilo_config['token']);
if (isset($invoices->documents) && count($invoices->documents) > 0) {
foreach ($invoices->documents as $invoice) {
addapiloInvoice($invoice, $platforms, $apilo_config['token']);
}
}
return true;
}
function loadApiloConfiguration()
{
global $db;
$dbRes = $db->query("SELECT * FROM config WHERE category='apilo'");
$config = [];
while ($row = $db->fetchByAssoc($dbRes)) {
$config[$row['name']] = $row['value'];
}
return $config;
}
function loadApiloInvoices($token, $offset)
{
$url = "https://twinpol.apilo.com/rest/api/finance/documents/";
$params = [
'type' => 1,
'limit' => 50,
'offset' => $offset
];
$url .= '?' . http_build_query($params);
$headers = [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
'Accept: application/json'
];
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode !== 200) {
return (object)['error' => 'HTTP Error: ' . $httpCode];
}
return json_decode($response);
}
function refreshApiloToken($refreshToken, $clientId, $clientSecret)
{
$url = "https://api.apilo.com/oauth/token";
$data = [
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken,
'client_id' => $clientId,
'client_secret' => $clientSecret
];
$headers = [
'Content-Type: application/x-www-form-urlencoded',
'Accept: application/json'
];
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode !== 200) {
return false;
}
$tokenData = json_decode($response, true);
if (isset($tokenData['access_token'])) {
// Zapisujemy nowy token w bazie
global $db;
$db->query("UPDATE config SET value='" . $tokenData['access_token'] . "' WHERE category='apilo' AND name='access_token'");
if (isset($tokenData['refresh_token'])) {
$db->query("UPDATE config SET value='" . $tokenData['refresh_token'] . "' WHERE category='apilo' AND name='refresh_token'");
}
return true;
}
return false;
}
function addApiloInvoice($invoice, $platforms, $token)
{
$db = $GLOBALS['db'];
$platformId = loadApiloOrderPlatformId($token, $invoice->orderId);
$platformDescription = 'ERROR';
foreach ($platforms as $platform) {
if ($platform->id == $platformId) {
$platformDescription = $platform->description;
break;
}
}
$orderSource = 'Apilo | '.$platformDescription;
$invoiceType = 'normal';
if (isset($invoice->type)) {
switch ($invoice->type) {
case 31:
$invoiceType = 'correcting';
break;
case 1:
default:
$invoiceType = 'normal';
break;
}
}
$customerName = '';
$customerNip = '';
$customerCity = '';
$customerPostcode = '';
$customerAddress = '';
$customerCountry = '';
$customerCountryCode = '';
if (isset($invoice->documentReceiver)) {
$customer = $invoice->documentReceiver;
$customerName = isset($customer->companyName) ? $customer->companyName : $customer->name;
if (isset($customer->companyTaxNumber)) {
$customerNip = $customer->companyTaxNumber;
}
$customerCity = isset($customer->city) ? $customer->city : '';
$customerPostcode = isset($customer->zipCode) ? $customer->zipCode : '';
$customerAddress = isset($customer->streetName) ? $customer->streetName : '';
if (isset($customer->streetNumber)) {
$customerAddress .= ' ' . $customer->streetNumber;
}
$customerCountry = isset($customer->country) ? $customer->country : '';
$customerCountryCode = isset($customer->country) ? $customer->country : '';
}
$totalNetto = isset($invoice->originalAmountTotalWithoutTax) ? floatval($invoice->originalAmountTotalWithoutTax) : 0;
$totalBrutto = isset($invoice->originalAmountTotalWithTax) ? floatval($invoice->originalAmountTotalWithTax) : 0;
$totalVat = $totalBrutto - $totalNetto;
$currency = isset($invoice->originalCurrency) ? $invoice->originalCurrency : 'PLN';
$issueDate = isset($invoice->invoicedAt) ? date("Y-m-d", strtotime(substr($invoice->invoicedAt, 0, 10))) : date("Y-m-d");
$saleDate = isset($invoice->soldAt) ? date("Y-m-d", strtotime(substr($invoice->soldAt,0,10))) : $issueDate;
$correctedInvoiceId = ''; //isset($invoice->original_invoice_id) ? $invoice->original_invoice_id : '';
$db->query("SET NAMES utf8mb4");
$query = sprintf(
"INSERT INTO ecommerce_invoices VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%f', '%f', '%f', '%s', '%s', null, null, null, null);",
$db->quote($invoice->id),
$db->quote($invoice->documentNumber),
$invoiceType,
$issueDate,
$saleDate,
$orderSource,
isset($invoice->orderId) ? $invoice->orderId : '',
$db->quote($customerName),
$customerNip,
$db->quote($customerCity),
$customerPostcode,
$db->quote($customerAddress),
$db->quote($customerCountry),
$customerCountryCode,
$currency,
$totalNetto,
$totalBrutto,
$totalVat,
'',
$correctedInvoiceId
);
$db->query($query);
if ($db->last_error) {
error_log("Błąd dodawania faktury apilo: " . $db->last_error);
return;
}
if (isset($invoice->documentItems) && is_array($invoice->documentItems)) {
$db->query(sprintf("DELETE FROM ecommerce_invoices_products WHERE invoice_id='%s'", $db->quote($invoice->id)));
foreach ($invoice->documentItems as $item) {
addApiloInvoiceProduct($invoice->id, $item);
}
}
}
function addApiloInvoiceProduct($invoiceId, $item)
{
$db = $GLOBALS['db'];
$productId = '';
if (isset($item->sku) && !empty($item->sku)) {
$productResult = $db->query(sprintf("SELECT id FROM ecmproducts WHERE code = '%s'", $db->quote($item->sku)));
$productRow = $db->fetchByAssoc($productResult);
if ($productRow) {
$productId = $productRow['id'];
}
} else { // shipping
$productId = '165f364e-9301-25ac-5906-58e38f1de4ca';
}
$uuid = sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0xffff)
);
$quantity = isset($item->quantity) ? intval($item->quantity) : 1;
$priceNetto = isset($item->originalPriceWithoutTax) ? floatval($item->originalPriceWithoutTax) : 0;
$priceBrutto = isset($item->originalPriceWithTax) ? floatval($item->originalPriceWithTax) : 0;
$priceVat = $priceBrutto - $priceNetto;
$taxRate = isset($item->tax) ? floatval($item->tax) : 0;
$sku = isset($item->sku) ? $item->sku : $item->name;;
$query = sprintf(
"INSERT INTO ecommerce_invoices_products VALUES('%s', '%s', '%s', '%s', '%d', '%f', '%f', '%f', '%f', '%s')",
$uuid,
$productId,
$db->quote($invoiceId),
isset($item->id) ? $db->quote($item->id) : '',
$quantity,
$priceNetto,
$priceBrutto,
$priceVat,
$taxRate,
$db->quote($sku)
);
$db->query($query);
if ($db->last_error) {
error_log("Błąd dodawania pozycji faktury apilo: " . $db->last_error);
}
}
function loadApiloPlatformsList($token) {
$url = "https://twinpol.apilo.com/rest/api/orders/platform/map/";
$headers = [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
'Accept: application/json'
];
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode !== 200) {
return (object)['error' => 'HTTP Error: ' . $httpCode];
}
return json_decode($response);
}
function loadApiloOrderPlatformId($token, $orderId) {
$url = "https://twinpol.apilo.com/rest/api/orders/".$orderId."/";
$headers = [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
'Accept: application/json'
];
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode !== 200) {
return (object)['error' => 'HTTP Error: ' . $httpCode];
}
return json_decode($response)->platformAccountId;
}
function brecho($msg)
{
echo '<br><pre>';
var_dump($msg);
echo PHP_EOL;
echo '</pre><br>';
}

View File

@@ -16,7 +16,9 @@ if (isset($_REQUEST['import_baselinker'])) {
} else if (isset($_REQUEST['wnt'])) {
include_once(getcwd().'/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/amazonWDT/wntReader.php');
} else if (isset($_REQUEST['amazon-wz'])) {
include_once(getcwd().'/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/amazonWDT/amazonWZ.php');
include_once(getcwd() . '/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/amazonWDT/amazonWZ.php');
} else if (isset($_REQUEST['import_apilo'])) {
include_once(getcwd().'/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/importApiloInvoices.php');
} else {
include_once(getcwd().'/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/ecommerceInvoicesListView.php');
}

View File

@@ -68,6 +68,16 @@ $job_strings = array(
2 => 'importBaselinkerCorrectingInvoices'
);
function importApiloInvoices() {
try {
$GLOBALS['db']->query("USE preDb_0dcc87940d3655fa574b253df04ca1c3;");
require_once('modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/importApiloInvoices.php');
importApiloInvoices();
return true;
} catch (Exception $e) {
return false;
}
}
function importBaselinkerInvoices()
{
try {