2363 lines
87 KiB
PHP
2363 lines
87 KiB
PHP
<?php
|
||
|
||
/**
|
||
* Plik wymiany danych z systemem Baselinker
|
||
* @author Sewer Skrzypiński <info@baselinker.com>
|
||
* @version 4
|
||
* @package baselinker
|
||
*/
|
||
|
||
/** -----------------------------------------------------------------------------------------------------------
|
||
* Ustawienia wpisywane przez sprzedawcę
|
||
* - Należy uzupełnić dane wprowadzając je między apostrofy
|
||
*/
|
||
$options['baselinker_pass'] = 'femwtyqlyy8bhglqe0x8584vv2i9xxqp'; //hasło do komunikacji (dostępne w panelu Baselinkera w zakładce 'sklep internetowy')
|
||
|
||
$options['db_host'] = 'localhost'; //adres hosta bazy danych (najczęściej localhost)
|
||
$options['db_user'] = 'rsduvqkeer_grzanie'; //użytkownik bazy danych
|
||
$options['db_pass'] = '[QD-*l7%0M-Hicik'; //hasło bazy danych
|
||
$options['db_name'] = 'rsduvqkeer_grzanieplus-pl'; //nazwa bazy danych
|
||
$options['db_prefix'] = ''; //prefiks tabel bazy danych - domyślnie pozostaw pusty aby wykryć automatycznie
|
||
|
||
$options['images_folder'] = 'http://grzanieplus.pl/'; //adres folderu zawierającego zdjęcia produktów i producentów (rozpoczęty 'http://', zakończony /)
|
||
|
||
$options['special_price'] = 1; //czy używać ceny promocyjnej jeśli produkt jest w promocji? (0 - nie, 1 - tak)
|
||
$options['charset'] = 'UTF-8'; //zestaw znaków bazy danych (standardowo UTF-8)
|
||
$options['ean_fld'] = 'man_code'; // pole w bazie sklepu, z którego ma być pobierany kod EAN dla produktów głównych
|
||
$options['vean_fld'] = ''; // pole w bazie sklepu, z którego ma być pobierany kod EAN dla wariantów
|
||
|
||
$options['sote_shophash'] = 'f9862393534ee289a67584de0b0768a0'; // klucz rozkodowywania danych zamówienia (zawarty w pliku core/data/config/__stRegister.yml)
|
||
$options['sote_dir'] = '..'; // ścieżka do głównego katalogu sote (zwykle nazwya się soteshop)
|
||
$options['og_host'] = ''; // jeśli wypełniony, ogranicza pobieranie zamówień tylko do podanego hosta
|
||
$options['lang'] = ''; // język tłumaczeń - zostaw pusty aby wykryć automatycznie
|
||
$options['use_order_numbers'] = 0; // indeksuj zamówienia wg 0: ID lub 1: numeru
|
||
$options['pa_fields'] = ''; // mapowanie pól dodatkowych produktu w formacie A:nazwa_pola_1, B:nazwa_pola_2, itd.
|
||
|
||
|
||
error_reporting(E_ERROR | E_WARNING);
|
||
date_default_timezone_set('Europe/Warsaw');
|
||
|
||
/** -----------------------------------------------------------------------------------------------------------
|
||
* Funkcje zarządzające komunikacją (przedrostek Conn_) oraz funkcje ułatwiające zapytania SQL (przedrostek DB_)
|
||
* - Jednakowe niezależnie od platformy
|
||
* - Nie należy edytować poniższego kodu
|
||
*/
|
||
|
||
|
||
|
||
/**
|
||
* Definicja funkcji json_encode oraz json_decode dla PHP4 (istnieją domyślnie w PHP5.2), iconv() dla tablic, oraz array_walk_recursive()
|
||
* Nie należy edytować. Credits goes to Steve http://usphp.com/manual/en/function.json-encode.php#82904
|
||
*/
|
||
if (!function_exists('json_encode'))
|
||
{
|
||
function json_encode($a=false,$is_key=false)
|
||
{if (is_null($a)) return 'null';if ($a === false) return 'false';if ($a === true) return 'true';
|
||
if (is_scalar($a)){if(is_int($a)&&$is_key){return '"'.$a.'"';} if (is_float($a)){return floatval(str_replace(",", ".", strval($a)));}if (is_string($a)){
|
||
static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'));
|
||
return '"' . str_replace($jsonReplaces[0], $jsonReplaces[1], $a) . '"';} else return $a;} $isList = true;
|
||
for ($i = 0, reset($a); $i < count($a); $i++, next($a)){if (key($a) !== $i){$isList = false;break;}}
|
||
$result = array(); if ($isList){foreach ($a as $v) $result[] = json_encode($v); return '[' . join(',', $result) . ']';}
|
||
else {foreach ($a as $k => $v) $result[] = json_encode($k,true).':'.json_encode($v); return '{' . join(',', $result) . '}';}}
|
||
}
|
||
if (!function_exists('json_decode'))
|
||
{
|
||
function json_decode($json, $assoc = true)
|
||
{$comment = false; $out = '$x='; for ($i=0; $i<strlen($json); $i++) { if (!$comment) {if (($json[$i] == '{') || ($json[$i] == '['))
|
||
$out .= ' array('; else if (($json[$i] == '}') || ($json[$i] == ']')) $out .= ')'; else if ($json[$i] == ':') $out .= '=>';
|
||
else $out .= $json[$i]; } else $out .= $json[$i]; if ($json[$i] == '"' && $json[($i-1)]!="\\") $comment = !$comment;} eval($out . ';'); return $x;}
|
||
}
|
||
if (!function_exists('array_walk_recursive'))
|
||
{
|
||
function array_walk_recursive(&$input, $funcname, $userdata = "")
|
||
{if (!is_callable($funcname)){return false;}if (!is_array($input)){return false;}foreach ($input AS $key => $value){
|
||
if (is_array($input[$key])){array_walk_recursive($input[$key], $funcname, $userdata);}else{$saved_value = $value;
|
||
if (!empty($userdata)){$funcname($value, $key, $userdata);}else{$funcname($value, $key);}if ($value != $saved_value)
|
||
{$input[$key] = $value;}}}return true;}
|
||
}
|
||
|
||
function array_iconv(&$val, $key, $userdata)
|
||
{$val = iconv($userdata[0], $userdata[1], $val);}
|
||
function recursive_iconv($in_charset, $out_charset, $arr)
|
||
{if (!is_array($arr)){return iconv($in_charset, $out_charset, $arr);}$ret = $arr;
|
||
array_walk_recursive($ret, "array_iconv", array($in_charset, $out_charset));return $ret;}
|
||
|
||
|
||
// środowisko odkodowywania danych z nowej wersji Sote
|
||
if (!function_exists('random_bytes'))
|
||
{
|
||
function random_bytes($octets)
|
||
{
|
||
$out = '';
|
||
|
||
for ($i = 0; $i < $octets; $i++)
|
||
{
|
||
$out .= chr(rand(0, 255));
|
||
}
|
||
|
||
return $out;
|
||
}
|
||
}
|
||
|
||
if (file_exists($options['sote_dir'] . '/plugins/stSecurityPlugin/lib/vendor/defuse/autoload.php'))
|
||
{
|
||
@include $options['sote_dir'] . '/plugins/stSecurityPlugin/lib/vendor/defuse/autoload.php';
|
||
}
|
||
elseif (file_exists($options['sote_dir'] . '/plugins/stSecurityPlugin/lib/vendor/DefuseCrypto/Core.php'))
|
||
{
|
||
@include $options['sote_dir'] . '/plugins/stSecurityPlugin/lib/vendor/DefuseCrypto/Core.php';
|
||
@include $options['sote_dir'] . '/plugins/stSecurityPlugin/lib/vendor/DefuseCrypto/Crypto.php';
|
||
@include $options['sote_dir'] . '/plugins/stSecurityPlugin/lib/vendor/DefuseCrypto/Key.php';
|
||
@include $options['sote_dir'] . '/plugins/stSecurityPlugin/lib/vendor/DefuseCrypto/Encoding.php';
|
||
@include $options['sote_dir'] . '/plugins/stSecurityPlugin/lib/vendor/DefuseCrypto/KeyOrPassword.php';
|
||
@include $options['sote_dir'] . '/plugins/stSecurityPlugin/lib/vendor/DefuseCrypto/RuntimeTests.php';
|
||
@include $options['sote_dir'] . '/plugins/stSecurityPlugin/lib/vendor/DefuseCrypto/DerivedKeys.php';
|
||
@include $options['sote_dir'] . '/plugins/stSecurityPlugin/lib/vendor/DefuseCrypto/Exception/CryptoException.php';
|
||
@include $options['sote_dir'] . '/plugins/stSecurityPlugin/lib/vendor/DefuseCrypto/Exception/WrongKeyOrModifiedCiphertextException.php';
|
||
}
|
||
|
||
/**
|
||
* Funkcje wykonujące zapytania SQL
|
||
*/
|
||
function DB_Query($sql)
|
||
{
|
||
global $dbh;
|
||
|
||
if (func_num_args() > 1){$i = 0; foreach(func_get_args() as $val){if ($i==0){$i++; continue;}$sql = str_replace("{".($i-1)."}", substr($dbh->quote($val), 1, -1), $sql); $i++;}}
|
||
|
||
if (!($sth = $dbh->prepare($sql)))
|
||
{
|
||
$err = $dbh->errorInfo();
|
||
Conn_error('db_query', 'SQL error: ' . $err[2]);
|
||
}
|
||
|
||
if (!($sth->execute()))
|
||
{
|
||
$err = $sth->errorInfo();
|
||
Conn_error('db_query', 'SQL error: ' . $err[2]);
|
||
}
|
||
|
||
return $sth;
|
||
}
|
||
|
||
function DB_Result($sth, $num = 0) { if (DB_NumRows($sth) > $num){return $sth->fetchColumn($num);} return false; }
|
||
|
||
function DB_Identity() { global $dbh; return $dbh->lastInsertId(); }
|
||
|
||
function DB_NumRows($sth) { return $sth->rowCount(); }
|
||
|
||
function DB_Fetch($sth) { return $sth->fetch(PDO::FETCH_ASSOC); }
|
||
|
||
|
||
/**
|
||
* Funkcja obsługująca żądania i wysyłająca odpowiedź.
|
||
* Zalecane jest pozostawienie funkcji w tej postaci niezależnie od platformy
|
||
* @global array $options : tablica z ustawieniami ogólnymi
|
||
*/
|
||
function Conn_Init()
|
||
{
|
||
global $options;
|
||
|
||
//sprawdzanie poprawności hasła wymiany danych
|
||
if(!isset($_POST['bl_pass']))
|
||
{Conn_Error("no_password","Odwołanie do pliku bez podania hasła. Jest to poprawny komunikat jeśli plik integracyjny został otworzony w przeglądarce internetowej.");}
|
||
elseif($options['baselinker_pass'] == "" || $options['baselinker_pass'] !== $_POST['bl_pass'])
|
||
{Conn_Error("incorrect_password");}
|
||
|
||
//zmiana kodowania danych wejściowych
|
||
if($options['charset'] != "UTF-8")
|
||
{
|
||
foreach($_POST as $key => $val)
|
||
{$_POST[$key] = iconv('UTF-8', $options['charset'].'//IGNORE', $val);}
|
||
}
|
||
|
||
//łączenie z bazą danych sklepu
|
||
Shop_ConnectDatabase($_POST);
|
||
|
||
//rozbijanie tablic z danymi
|
||
if(isset($_POST['orders_ids'])){$_POST['orders_ids'] = explode(',', $_POST['orders_ids']);}
|
||
if(isset($_POST['products_id'])){$_POST['products_id'] = explode(',', $_POST['products_id']);}
|
||
if(isset($_POST['fields'])){$_POST['fields'] = explode(',', $_POST['fields']);}
|
||
if(isset($_POST['products'])){$_POST['products'] = json_decode($_POST['products'], true);}
|
||
|
||
//sprawdzanie czy podana metoda jest zaimplementowana
|
||
if(function_exists("Shop_".$_POST['action']))
|
||
{
|
||
$method = "Shop_".$_POST['action'];
|
||
Conn_SendResponse($method($_POST));
|
||
}
|
||
else
|
||
{Conn_Error("unsupported_action", "No action: ".$_POST['action']);}
|
||
}
|
||
|
||
|
||
/**
|
||
* Funkcja generująca odpowiedź do systemu w formacie JSON
|
||
* @global array $options tablica z ustawieniami ogólnymi
|
||
*/
|
||
function Conn_SendResponse($response)
|
||
{
|
||
global $options;
|
||
|
||
//zmiana kodowania danych wyjściowych
|
||
if($options['charset'] != "UTF-8" && count($response) > 0)
|
||
{
|
||
foreach($response as $key => $val)
|
||
{$response[$key] = recursive_iconv($options['charset'], 'UTF-8//IGNORE', $val);}
|
||
}
|
||
|
||
print json_encode($response);
|
||
exit();
|
||
}
|
||
|
||
|
||
/**
|
||
* Funkcja wypisująca kominukat błędu w formacie JSON i kończąca skrypt
|
||
* Zalecane jest pozostawienie funkcji w tej postaci niezależnie od platformy
|
||
* @param string $error_code kod błędu (standardowe wartości: db_connect, db_query, no_action)
|
||
* @param string $error_text opis błędu
|
||
*/
|
||
function Conn_Error($error_code, $error_text = '')
|
||
{
|
||
print json_encode(array('error' => true, 'error_code' => $error_code, 'error_text' => $error_text));
|
||
exit();
|
||
}
|
||
|
||
|
||
/**
|
||
* Ewentualne wczytanie dodatkowych funkcji z pliku baselinker_pm.php (BaseLinker Product Managment)
|
||
* Zawarte w dodatkowym pliku funkcje rozszerzają możliwości integracji ze sklepem o funkcje pozwalające dodawać i zmieniać kategorie, produkty oraz warianty.
|
||
* Obsługa tych funkcji jest wymagana przez niektóre moduły BaseLinkera (np. moduły integrujące system z programami typu ERP)
|
||
* Plik baselinker_pm.php jest dostępny dla wybranych platform sklepów. Skontaktuj się z administratorem w cely uzyskania pliku.
|
||
*/
|
||
if(file_exists("baselinker_pm.php"))
|
||
{include("baselinker_pm.php");}
|
||
|
||
|
||
//inicjacja komunikacji
|
||
Conn_Init();
|
||
|
||
|
||
|
||
|
||
/** -----------------------------------------------------------------------------------------------------------
|
||
* Funkcje obsługiwania żądań (przedrostek Shop_)
|
||
* - Zależne od platformy sklepu
|
||
* - Do edycji dla deweloperów
|
||
*/
|
||
|
||
|
||
|
||
/**
|
||
* Funkcja zwracająca wersję pliku wymiany danych
|
||
* Przy tworzeniu pliku należy skonsultować numer wersji i nazwę platformy
|
||
* z administracją systemu Baselinker
|
||
* @param array $request tablica z żadaniem od systemu, w przypadku tej funkcji nie używana
|
||
* @return array $response tablica z danymi platformy z polami:
|
||
* platform => nazwa platformy
|
||
* version => numer wersji pliku
|
||
*/
|
||
function Shop_FileVersion($request)
|
||
{
|
||
$response['platform'] = "SoteShop";
|
||
$response['version'] = "4.1.69"; //wersja pliku integracyjnego, nie wersja sklepu!
|
||
$response['standard'] = 4; //standard struktury pliku integracyjnego - obecny standard to 4.
|
||
|
||
return $response;
|
||
}
|
||
|
||
|
||
/**
|
||
* Funkcja zwracająca listę zaimplementowanych metod pliku
|
||
* Zalecane jest pozostawienie funkcji w tej postaci niezależnie od platformy
|
||
*/
|
||
function Shop_SupportedMethods()
|
||
{
|
||
$result = array();
|
||
$methods = get_defined_functions();
|
||
|
||
foreach($methods['user'] as $m)
|
||
{
|
||
if (stripos($m, 'shop_') === 0)
|
||
{$result[] = substr($m,5);}
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Funkcja nawiązująca komunikację z bazą danych sklepu
|
||
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
|
||
* @param array $request tablica z żadaniem od systemu, w przypadku tej funkcji nie używana
|
||
* @return boolean wartość logiczna określajaca sukces połączenia z bazą danych
|
||
*/
|
||
function Shop_ConnectDatabase($request)
|
||
{
|
||
global $options; //globalna tablica z ustawieniami
|
||
global $dbh; // handler bazy danych
|
||
|
||
$dbp = $options['db_prefix']; //Data Base Prefix - prefix tabel bazy
|
||
|
||
// wydzielenie portu z nazwy hosta
|
||
if (preg_match('/^\s*([\w\-\.]+):(\d+)\s*$/', $options['db_host'], $m))
|
||
{
|
||
$options['db_host'] = $m[1];
|
||
$options['db_port'] = $m[2];
|
||
}
|
||
|
||
// wygenerowanie DSN
|
||
$dsn = "mysql:dbname=${options['db_name']};host=${options['db_host']}";
|
||
|
||
if ($options['db_port'])
|
||
{
|
||
$dsn .= ";port=${options['db_port']}";
|
||
}
|
||
|
||
// nawiązanie połączenia z bazą danych sklepu
|
||
try {
|
||
$dbh = new PDO($dsn, $options['db_user'], $options['db_pass']);
|
||
} catch (Exception $ex) {
|
||
Conn_Error('db_connection', $ex->getMessage());
|
||
}
|
||
|
||
if($options['charset'] == "UTF-8")
|
||
{DB_Query("SET NAMES utf8");}
|
||
|
||
DB_Query("SET SESSION sql_mode = 'NO_ENGINE_SUBSTITUTION'");
|
||
|
||
// automatyczne wyszukiwanie prefiksu bazy danych
|
||
if ($dbp == '')
|
||
{
|
||
// wyszukiwanie tabeli z unikalną nazwą
|
||
$unique_table = 'st_product_has_category';
|
||
$search_table = DB_Query("SHOW TABLES LIKE '%${unique_table}'");
|
||
|
||
if (DB_NumRows($search_table) == 1)
|
||
{
|
||
$options['db_prefix'] = str_replace($unique_table, '', DB_Result($search_table));
|
||
$dbp = $options['db_prefix'];
|
||
}
|
||
else // nie wykryto jednoznacznie prefiksu
|
||
{
|
||
Conn_Error("database_prefix");
|
||
}
|
||
}
|
||
|
||
if (!$options['lang'])
|
||
{
|
||
$options['lang'] = DB_Result(DB_Query("SELECT language FROM `${dbp}st_language` WHERE active ORDER BY is_default DESC LIMIT 1"));
|
||
}
|
||
|
||
if ($options['ean_code']) // weryfikacja pola EAN
|
||
{
|
||
if (!DB_NumRows(DB_Query("SHOW FIELDS FROM `${dbp}st_product` LIKE '${options['ean_code']}'")))
|
||
{
|
||
$options['ean_code'] = '';
|
||
}
|
||
}
|
||
|
||
// zniżki już wliczone w opt_price_brutto
|
||
$options['use_discounts'] = false;//$options['special_price'] && DB_NumRows(DB_Query("SHOW TABLES LIKE '${dbp}st_discount_has_product'"));
|
||
}
|
||
|
||
|
||
/**
|
||
* Funkcja zwraca listę kategorii sklepowych
|
||
* Zwracana tabela powinna być posortowana alfabetycznie
|
||
* W nazwie kategorii podrzędnej powinna być zawrta nazwa nadkategorii - np "Komputery/Karty graficzne" zamiast "Karty graficzne"
|
||
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
|
||
* @param array $request tablica z żadaniem od systemu, w przypadku tej funkcji nie używana
|
||
* @return array $response tablica z listą kategori sklepowch w formacie:
|
||
* id kategorii => nazwa kategorii
|
||
*/
|
||
function Shop_ProductsCategories($request)
|
||
{
|
||
global $options; // globalna tablica z ustawieniami
|
||
$dbp = $options['db_prefix']; // Data Base Prefix - prefix tabel bazy
|
||
|
||
|
||
// pobieranie kategorii z bazy i zapisywanie do tabeli
|
||
$sql = "SELECT c.*, ci.name FROM `${dbp}st_category` c
|
||
LEFT JOIN `${dbp}st_category_i18n` ci ON ci.id = c.id AND ci.culture = '{0}'
|
||
WHERE is_active = 1 AND is_hidden = 0";
|
||
$res = DB_Query($sql, $options['lang']);
|
||
|
||
while ($category = DB_Fetch($res))
|
||
{
|
||
$categories[$category['id']] = empty($category['name']) ? $category['opt_name'] : $category['name'];
|
||
$parents[$category['id']] = $category['parent_id'];
|
||
}
|
||
|
||
// budowanie drzewa kategorii na podstawie tablicy
|
||
$category_tree = array();
|
||
|
||
foreach ($categories as $id => $name)
|
||
{
|
||
$cat_name = "";
|
||
$this_id = $id;
|
||
|
||
while (isset($parents[$this_id]) and $parents[$this_id] != 0)
|
||
{
|
||
if (isset($categories[$parents[$this_id]]))
|
||
{
|
||
$cat_name = $categories[$parents[$this_id]] .'/' . $cat_name;
|
||
}
|
||
|
||
$this_id = $parents[$this_id];
|
||
}
|
||
$category_tree[$id] = $cat_name.$name;
|
||
}
|
||
|
||
// sortowanie alfabetycznie wg nazw
|
||
asort($category_tree);
|
||
|
||
return $category_tree;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/**
|
||
* Funkcja zwraca listę produktów z bazy sklepu
|
||
* Zwracane liczby (np ceny) powinny mieć format typu: 123456798.12 (kropka oddziela część całkowitą, 2 miejsca po przecinku)
|
||
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
|
||
* @param array $request tablica z żadaniem od systemu zawierająca pola:
|
||
* category_id => id kategori (wartość 'all' jeśli wszystkie przedmioty)
|
||
* filter_limit => limit zwróconych kategorii w formacie SQLowym ("ilość pomijanych, ilość pobieranych")
|
||
* filter_sort => wartość po której ma być sortowana lista produktów. Możliwe wartości:
|
||
* "id [ASC|DESC]", "name [ASC|DESC]", "quantity [ASC|DESC]", "price [ASC|DESC]"
|
||
* filter_id => ograniczenie wyników do konkretnego id produktu
|
||
* filter_ean => ograniczenie wyników do konkretnego ean
|
||
* filter_sku => ograniczenie wyników do konkretnego sku (numeru magazynowego)
|
||
* filter_name => filtr nazw przedmiotów (fragment szukanej nazwy lub puste pole)
|
||
* filter_price_from => dolne ograniczenie ceny (nie wyświetlane produkty z niższą ceną)
|
||
* filter_price_to => górne ograniczenie ceny
|
||
* filter_quantity_from => dolne ograniczenie ilości produktów
|
||
* filter_quantity_to => górne ograniczenie ilości produktów
|
||
* filter_available => wyświetlanie tylko produktów oznaczonych jako dostępne (wartość 1) lub niedostępne (0) lub wszystkich (pusta wartość)
|
||
* @return array $response tablica z listą produktów w formacie:
|
||
* id produktu =>
|
||
'name' => nazwa produktu
|
||
'quantity' => dostępna ilość
|
||
'price' => cena w PLN
|
||
*/
|
||
function Shop_ProductsList($request)
|
||
{
|
||
global $options; //globalna tablica z ustawieniami
|
||
$dbp = $options['db_prefix']; //Data Base Prefix - prefix tabel bazy
|
||
|
||
// wyrażenie SQL zwracające cenę, nazwę, stan mag.
|
||
$price_spec = 'p.opt_price_brutto';
|
||
$name_spec = 'p.opt_name';
|
||
$name_spec = 'pi.name';
|
||
$qty_spec = 'p.stock';
|
||
|
||
// zmiana nazw kolumn na nazwy pól
|
||
$request['filter_sort'] = str_replace(array('id', 'name', 'quantity', 'price'), array('p.id', $name_spec, $qty_spec, $price_spec), $request['filter_sort']);
|
||
|
||
//pobieranie produktow z bazy danych
|
||
$sql = "SELECT p.id, $name_spec name, code, $price_spec price, $qty_spec stock
|
||
FROM `${dbp}st_product` p
|
||
LEFT JOIN `${dbp}st_product_i18n` pi ON pi.id = p.id AND pi.culture = '{0}'
|
||
WHERE 1";
|
||
|
||
// pobieranie zniżek
|
||
if ($options['use_discounts'])
|
||
{
|
||
$sql = "SELECT p.id, $name_spec name, code, $price_spec price, $qty_spec stock,
|
||
d.value discount, d.conditions, d.price_type
|
||
FROM `${dbp}st_product` p
|
||
LEFT JOIN `${dbp}st_discount_has_product` dp ON dp.product_id = p.id
|
||
LEFT JOIN `${dbp}st_discount` d ON d.id = dp.discount_id AND d.active = 1 AND d.type = 'P'
|
||
LEFT JOIN `${dbp}st_product_i18n` pi ON pi.id = p.id AND pi.culture = '{0}'
|
||
WHERE 1";
|
||
}
|
||
|
||
|
||
if ($request['category_id'] != 'all' && $request['category_id'] != '') // wybór kategorii
|
||
{
|
||
$sql = preg_replace('/(\s+WHERE\s+)/', "\nJOIN `${dbp}st_product_has_category` phc ON phc.product_id = p.id$1", $sql);
|
||
$sql .= " AND phc.category_id = '${request['category_id']}'";
|
||
}
|
||
|
||
if ($request['filter_id'] != '') { $sql .= " AND p.id = '${request['filter_id']}'"; } //filtrowanie id
|
||
if ($request['filter_name'] != '') { $sql .= " AND $name_spec LIKE '%${request['filter_name']}%'"; } //filtrowanie nazwy
|
||
if ($request['filter_sku'] != '') { $sql .= " AND p.code LIKE '%${request['filter_sku']}%'"; } //filtrowanie SKU
|
||
|
||
if ($options['ean_fld'])
|
||
{
|
||
$sql = preg_replace('/^SELECT/is', '$0 '.$options['ean_fld'].',', $sql);
|
||
if ($request['filter_ean'] != '') { $sql .= " AND p.${options['ean_fld']} LIKE '%${request['filter_ean']}%'"; } // filtrowanie EAN
|
||
}
|
||
|
||
if ($request['filter_quantity_from'] != '') { $sql .= " AND $qty_spec >= '${request['filter_quantity_from']}'"; } //filtrowanie ilości
|
||
if ($request['filter_quantity_to'] != '') { $sql .= " AND $qty_spec <= '${request['filter_quantity_to']}'"; } //filtrowanie ilości
|
||
if ($request['filter_available'] != '') { $sql .= " AND p.active = '${request['filter_available']}'"; } //produkty dostępne/niedostępne
|
||
if ($request['filter_price_from'] != '') { $sql .= " AND $price_spec >= '${request['filter_price_from']}'"; }
|
||
if ($request['filter_price_to'] != '') { $sql .= " AND $price_spec <= '${request['filter_price_to']}'"; }
|
||
|
||
if ($request['filter_sort'] != '') { $sql .= " ORDER BY ${request['filter_sort']}"; }
|
||
if ($request['filter_limit'] != '') { $sql .= " LIMIT ${request['filter_limit']}"; }
|
||
|
||
$response = array();
|
||
$result = DB_Query($sql, $options['lang']);
|
||
|
||
while ($prod = DB_Fetch($result))
|
||
{
|
||
if (isset($prod['discount']) and $prod['discount'] > 0) // produkt posiada zniżkę ...
|
||
{
|
||
if ($prod['price_type'] == '%' and $prod['discount'] < 100) // procentową
|
||
{
|
||
$prod['price'] = number_format($prod['price']*(100-$prod['discount'])/100, 2, '.', '');
|
||
}
|
||
elseif ($prod['price'] > $prod['discount']) // kwotową
|
||
{
|
||
$prod['price'] = number_format($prod['price']-$prod['discount'], 2, '.', '');
|
||
}
|
||
}
|
||
|
||
$response[$prod['id']] = array('name' => $prod['name'], 'quantity' => (int)$prod['stock'], 'price' => $prod['price'], 'sku' => $prod['code'], 'ean' => $prod[$options['ean_fld']]);
|
||
}
|
||
|
||
return $response;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/**
|
||
* Funkcja zwraca szczegółowe dane wybranych produktów
|
||
* Zwracane liczby (np ceny) powinny mieć format typu: 123456798.12 (kropka oddziela część całkowitą, 2 miejsca po przecinku)
|
||
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
|
||
* @param array $request tablica z żadaniem od systemu zawierająca pola:
|
||
* products_id => tablica z numerami id produktów
|
||
* fields => tablica z nazwami pól do zwrócenia (jeśli pusta zwracany jest cały wynik)
|
||
* @return array $response tablica z listą produktów w formacie:
|
||
* id produktu =>
|
||
'name' => nazwa produktu, 'ean' => Kod EAN, 'sku' => numer katalogowy, 'model' => nazwa modelu lub inny identyfikator np ISBN,
|
||
'description' => opis produktu (może zawierać tagi HTML), 'description_extra1' => drugi opis produktu (np opis krótki) 'weight' => waga produktu w kg,
|
||
'quantity' => dostępna ilość, 'man_name' => nazwa producenta, 'man_image' => pełny adres obrazka loga producenta,
|
||
'category_id' => numer ID głównej kategorii, 'category_name' => nazwa kategori do której należy przedmiot, 'tax' => wielkość podatku w formie liczby (np 23)
|
||
'price' => cena brutto w PLN,
|
||
'images' => tablica z pełnymi adresami dodatkowych obrazków (pierwsze zdjęcie główne, reszta w odpowiedniej kolejności),
|
||
'features' => tablica z opisem cech produktu. Poszczególny element tablicy zawiera nazwę i wartość cechy, np array('Rozdzielczość','Full HD')
|
||
'variants' => tablica z wariantami produktu do wyboru (np kolor, rozmiar). Format pola opisany jest w kodzie poniżej
|
||
*/
|
||
function Shop_ProductsData($request)
|
||
{
|
||
global $options; // globalna tablica z ustawieniami
|
||
$dbp = $options['db_prefix']; //Data Base Prefix - prefix tabel bazy
|
||
|
||
$category_tree = Shop_ProductsCategories($request);
|
||
$response = array();
|
||
$prodcat = array();
|
||
$has_desc2 = DB_NumRows(DB_Query("SHOW FIELDS FROM `${dbp}st_product_i18n` LIKE 'description2'"));
|
||
$afs = array();
|
||
|
||
if (preg_match_all('/([A-E])\s*:\s*(.+?)(?=[A-EZ]:)/', $options['pa_fields'].'Z:', $m, PREG_SET_ORDER))
|
||
{
|
||
foreach ($m as $fld)
|
||
{
|
||
$afs['field'.(ord($fld[1])-64)] = trim($fld[2], ',; ');
|
||
}
|
||
}
|
||
|
||
// mapowanie produktów do kategorii
|
||
$sql = "SELECT product_id, category_id
|
||
FROM `${dbp}st_product_has_category`
|
||
WHERE product_id IN ({0})
|
||
ORDER BY is_default";
|
||
$res = DB_Query($sql, implode(', ', $request['products_id']));
|
||
|
||
while ($map = DB_Fetch($res))
|
||
{
|
||
$prodcat[$map['product_id']] = $map['category_id'];
|
||
}
|
||
|
||
// pobieranie danych produktów z bazy danych
|
||
$sql = "SELECT p.id, p.code sku, p.code model, m.opt_name man_name,
|
||
m.image man_image, p.stock quantity, p.opt_url url,
|
||
p.opt_vat tax, p.weight, p.opt_price_brutto price, pi.name, pi.description,
|
||
pi.short_description description_extra1, " . ($has_desc2 ? 'pi.description2 description_extra2,' : '') . "
|
||
p.width, p.height, p.depth
|
||
" . ($afs ? (', ' . implode(', ', array_keys($afs))) : '') . "
|
||
FROM `${dbp}st_product` p
|
||
LEFT JOIN `${dbp}st_product_i18n` pi ON pi.id = p.id AND pi.culture = '{1}'
|
||
LEFT JOIN `${dbp}st_producer` m ON m.id = p.producer_id
|
||
WHERE
|
||
p.id IN ({0})";
|
||
|
||
if ($options['ean_fld'])
|
||
{
|
||
$sql = preg_replace('/^SELECT/is', '$0 p.'.$options['ean_fld'].' ean,', $sql);
|
||
}
|
||
|
||
$res = DB_Query($sql, implode(', ', $request['products_id']), $options['lang']);
|
||
$site_root_url = preg_replace('/^(https?:\/\/[^\/]+).*?$/', '$1', $options['images_folder']);
|
||
|
||
while ($p = DB_Fetch($res))
|
||
{
|
||
$product_id = $p['id'];
|
||
$price_add = 0;
|
||
$price_mult = 1;
|
||
|
||
// link do strony produktu
|
||
if ($p['url'])
|
||
{
|
||
$p['url'] = "$site_root_url/${p['url']}.html";
|
||
}
|
||
|
||
// pobieranie zniżek
|
||
if ($options['use_discounts'])
|
||
{
|
||
$sql = "SELECT d.value, d.conditions, d.price_type
|
||
FROM `${dbp}st_discount_has_product` dp
|
||
LEFT JOIN `${dbp}st_discount` d ON d.id = dp.discount_id AND d.active = 1 AND d.type = 'P'
|
||
WHERE dp.product_id = $product_id";
|
||
|
||
if ($disc = DB_Fetch(DB_Query($sql)))
|
||
{
|
||
if (isset($disc['value']) and $disc['value'] > 0) // produkt posiada zniżkę ...
|
||
{
|
||
if ($disc['price_type'] == '%' and $disc['value'] < 100) // procentową
|
||
{
|
||
$price_mult = (100-$disc['value'])/100;
|
||
}
|
||
elseif ($disc['price'] > $disc['value']) // kwotową
|
||
{
|
||
$price_add = -$disc['value'];
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
// zdjęcie producenta
|
||
if ($p['man_image'])
|
||
{
|
||
$p['man_image'] = $options['images_folder'] . $p['man_image'];
|
||
}
|
||
|
||
// uzupełnienie powiązania z kategorią
|
||
if ($prodcat[$product_id])
|
||
{
|
||
$p['category_id'] = $prodcat[$product_id];
|
||
$p['category_name'] = $category_tree[$prodcat[$product_id]];
|
||
}
|
||
|
||
// warianty
|
||
$sql = "SELECT pov.id pov_id, if(isnull(povi.value), pov.opt_value, povi.value) name,
|
||
if(isnull(pofi.name), pof.opt_name, pofi.name) opt_name,
|
||
pov.price, pov.stock, depth, product_options_field_id field_id,
|
||
pov.use_product sku" . (empty($options['vean_fld']) ? '' : ", pov.${options['vean_fld']} ean") . "
|
||
FROM `${dbp}st_product_options_value` pov
|
||
LEFT JOIN `${dbp}st_product_options_value_i18n` povi ON povi.id = pov.id AND povi.culture = '{2}'
|
||
LEFT JOIN `${dbp}st_product_options_field` pof ON pof.id = pov.product_options_field_id
|
||
LEFT JOIN `${dbp}st_product_options_field_i18n` pofi ON pofi.id = pov.product_options_field_id AND pofi.culture = '{2}'
|
||
WHERE pov.product_id = {0} AND NOT isnull(pov.opt_value)
|
||
ORDER by pov.depth, pov.lft";
|
||
$res2 = DB_Query($sql, $product_id, $options['lang']);
|
||
|
||
$multiopt2 = array(array('name' => '', 'price' => $p['price']));
|
||
$depth = 0;
|
||
$field_id = 0;
|
||
|
||
while ($opt = DB_Fetch($res2))
|
||
{
|
||
$vfeatures = array(array($opt['opt_name'], $opt['name']));
|
||
|
||
if ($opt['depth'] != $depth)
|
||
{
|
||
$depth_col = 0;
|
||
$multiopt = $multiopt2;
|
||
$multiopt2 = array();
|
||
$depth = $opt['depth'];
|
||
}
|
||
elseif ($opt['field_id'] != $field_id)
|
||
{
|
||
$depth_col++;
|
||
}
|
||
|
||
$v = array(
|
||
'id' => $opt['pov_id'],
|
||
'name' => $multiopt[$depth_col]['name'] . ' ' . $opt['name'],
|
||
'quantity' => (int)$opt['stock'],
|
||
'price' => $opt['price'],
|
||
'sku' => $opt['sku'],
|
||
'ean' => empty($opt['ean']) ? $p['ean'] : $opt['ean'],
|
||
'features' => $vfeatures,
|
||
);
|
||
|
||
if (!$opt['price'])
|
||
{
|
||
$v['price'] = $multiopt[$depth_col]['price']; //cena z poprzedniego poziomu
|
||
}
|
||
// opcja zmienia cenę o N %
|
||
elseif (preg_match('/([\+-]?[\.\d]+)%/', $v['price'], $m))
|
||
{
|
||
$v['price'] = number_format($multiopt[$depth_col]['price']*(100+$m[1])/100, 2, '.', '');
|
||
}
|
||
// opcja zmienia cenę o określoną kwotę
|
||
elseif (preg_match('/([\+-]?[\.\d]+)/', $v['price'], $m))
|
||
{
|
||
$v['price'] = number_format($multiopt[$depth_col]['price']+$m[1], 2, '.', '');
|
||
}
|
||
|
||
$v['vfeatures'][] = $vfeatures;
|
||
$multiopt2[] = $v;
|
||
$field_id = $opt['field_id'];
|
||
}
|
||
|
||
$p['variants'] = array();
|
||
|
||
foreach ($multiopt2 as $v)
|
||
{
|
||
if (empty($v['id'])) { continue; }
|
||
|
||
$p['variants'][$v['id']] = array(
|
||
'full_name' => $p['name'] . ' ' . $v['name'],
|
||
'name' => $v['name'],
|
||
'price' => $v['price'],
|
||
'quantity' => $v['quantity'],
|
||
'sku' => $v['sku'],
|
||
'ean' => $v['ean'],
|
||
'features' => $v['features'],
|
||
);
|
||
}
|
||
|
||
if ($price_add or $price_mult != 1)
|
||
{
|
||
$p['price'] = number_format($p['price']*$price_mult + $price_add, 2, '.', '');
|
||
|
||
foreach ($p['variants'] as $vid => $v)
|
||
{
|
||
$p['variants'][$vid]['price'] = number_format($v['price']*$price_mult + $price_add, 2, '.', '');
|
||
}
|
||
}
|
||
|
||
// pobieranie obrazków
|
||
$p['images'] = array();
|
||
|
||
$sql = "SELECT relative_path, filename
|
||
FROM `${dbp}st_product_has_sf_asset` sphsa
|
||
JOIN `${dbp}sf_asset` sa ON sphsa.sf_asset_id = sa.id
|
||
JOIN `${dbp}sf_asset_folder` saf ON sa.folder_id = saf.id
|
||
WHERE sphsa.product_id = '{0}'
|
||
ORDER BY is_default DESC, sphsa.id";
|
||
$res2 = DB_Query($sql, $product_id);
|
||
|
||
while ($img = DB_Fetch($res2))
|
||
{
|
||
$p['images'][] = "${options['images_folder']}${img['relative_path']}/${img['filename']}";
|
||
}
|
||
|
||
//pobieranie cech produktu (np. długość, kolor, rozmiar itp.)
|
||
$p['features'] = array();
|
||
|
||
$sql = "SELECT a.opt_name AS name, av.opt_value AS value
|
||
FROM `${dbp}app_product_attribute_variant_has_product` vhp
|
||
INNER JOIN `${dbp}app_product_attribute_variant` av ON av.id = vhp.variant_id
|
||
INNER JOIN `${dbp}app_product_attribute_has_variant` ahv ON ahv.variant_id = vhp.variant_id
|
||
INNER JOIN `${dbp}app_product_attribute` a ON a.id = ahv.attribute_id
|
||
WHERE vhp.product_id = '{0}' AND a.is_visible_on_pp";
|
||
$res2 = DB_Query($sql, $product_id);
|
||
|
||
while ($f = DB_Fetch($res2))
|
||
{
|
||
$p['features'][$f['name']] = isset($p['features'][$f['name']]) ? ($p['features'][$f['name']] . "|${f['value']}") : $f['value'];
|
||
}
|
||
|
||
foreach (array_keys($p['features']) as $f)
|
||
{
|
||
$p['features'][] = array($f, $p['features'][$f]);
|
||
unset($p['features'][$f]);
|
||
}
|
||
|
||
// wymiary produktu
|
||
foreach (array('width' => 'szerokość', 'height' => 'wysokość', 'depth' => 'głębokość') as $fld => $fld_name)
|
||
{
|
||
if ($p[$fld])
|
||
{
|
||
$p['features'][] = array($fld_name, $p[$fld]);
|
||
}
|
||
}
|
||
|
||
foreach ($afs as $af => $label)
|
||
{
|
||
$p['features'][] = array($label, $p[$af]);
|
||
unset($p[$af]);
|
||
}
|
||
|
||
//pobieranie wartości tagu [special] z zewnętrznego skryptu
|
||
//poniższy warunek może pozostać identyczny niezależnie od platformy sklepu
|
||
if (file_exists("baselinker_extra.php"))
|
||
{
|
||
//pobranie dodatkowych informacji z zewnętrznego pliku pliku.
|
||
//Plik tworzony jest indywidualnie dla każdego sprzedawcy jeśli zgłosi potrzebę pobierania dodatkowych danych ze sklepu.
|
||
//Pozwala to uniknąć ingerowania w standardowy plik baselinker.php
|
||
include("baselinker_extra.php");
|
||
}
|
||
|
||
|
||
//wyrzucanie niepotrzebnych wartości jeśli określono pola do pobrania
|
||
//poniższy kod może pozostać identyczny niezależnie od platformy sklepu
|
||
if (isset($request['fields']) and is_array($request['fields']) and !(count($request['fields']) == 1 && $request['fields'][0] == "") && !count($request['fields']) == 0)
|
||
{
|
||
$temp_p = array();
|
||
foreach($request['fields'] as $field)
|
||
{$temp_p[$field] = $p[$field];}
|
||
$p = $temp_p;
|
||
}
|
||
|
||
$response[$product_id] = $p;
|
||
}
|
||
|
||
return $response;
|
||
}
|
||
|
||
|
||
/**
|
||
* Funkcja zwraca ceny wszystkich produktów i ich wariantów
|
||
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
|
||
* @param array $request tablica z żadaniem od systemu, w przypadku tej funkcji nie używana
|
||
* @return array $response tablica z cenami wszystkich produktów, w formacie:
|
||
* id produktu => ID produktu jest kluczem tablicy, wartością jest tablica składająca się z cen wariantów
|
||
* id wariantu => kluczem tablicy jest ID wariantu (0 w przypadku produktu głównego)
|
||
* cena => wartościa jest cena brutto produktu lub wariantu
|
||
*
|
||
* Przykład: array('432' => array('0' => 230.00, '543' => 210.00, '567' => 230.00)) - produkt ID 432, cena głównego
|
||
* produktu to 230, posiada dwa warianty (ID 543 i 563), pierwszy w cenie niższej o 20.00.
|
||
*/
|
||
function Shop_ProductsPrices($request)
|
||
{
|
||
global $options; // globalna tablica z ustawieniami
|
||
$dbp = $options['db_prefix']; //Data Base Prefix - prefix tabel bazy
|
||
|
||
$response = array();
|
||
$page = isset($request['page']) ? (int)$request['page'] : 1;
|
||
$page = $page ? $page : 1;
|
||
$per_page = 1000;
|
||
|
||
// pobieranie danych produktów z bazy danych
|
||
$sql = "SELECT id, opt_price_brutto price
|
||
FROM `${dbp}st_product`
|
||
ORDER BY id LIMIT " . ($per_page*($page-1)) . ", $per_page";
|
||
|
||
$res = DB_Query($sql);
|
||
|
||
while ($p = DB_Fetch($res))
|
||
{
|
||
$product_id = $p['id'];
|
||
$price_add = 0;
|
||
$price_mult = 1;
|
||
|
||
// pobieranie zniżek
|
||
if ($options['use_discounts'])
|
||
{
|
||
$sql = "SELECT d.value, d.conditions, d.price_type
|
||
FROM `${dbp}st_discount_has_product` dp
|
||
LEFT JOIN `${dbp}st_discount` d ON d.id = dp.discount_id AND d.active = 1 AND d.type = 'P'
|
||
WHERE dp.product_id = $product_id";
|
||
|
||
if ($disc = DB_Fetch(DB_Query($sql)))
|
||
{
|
||
if (isset($disc['value']) and $disc['value'] > 0) // produkt posiada zniżkę ...
|
||
{
|
||
if ($disc['price_type'] == '%' and $disc['value'] < 100) // procentową
|
||
{
|
||
$price_mult = (100-$disc['value'])/100;
|
||
}
|
||
elseif ($disc['price'] > $disc['value']) // kwotową
|
||
{
|
||
$price_add = -$disc['value'];
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
// warianty
|
||
$sql = "SELECT pov.id pov_id,
|
||
pov.price, depth, product_options_field_id field_id, pov.opt_value
|
||
FROM `${dbp}st_product_options_value` pov
|
||
LEFT JOIN `${dbp}st_product_options_field` pof ON pof.id = pov.product_options_field_id
|
||
WHERE pov.product_id = {0} AND NOT isnull(pov.opt_value)
|
||
ORDER by pov.depth, pov.lft";
|
||
$res2 = DB_Query($sql, $product_id);
|
||
|
||
$multiopt2 = array(array('price' => $p['price'], 'opt_vals' => array()));
|
||
$depth = 0;
|
||
$field_id = 0;
|
||
|
||
while ($opt = DB_Fetch($res2))
|
||
{
|
||
$vfeatures = array(array($opt['opt_name'], $opt['name']));
|
||
|
||
if ($opt['depth'] != $depth)
|
||
{
|
||
$depth_col = 0;
|
||
$multiopt = $multiopt2;
|
||
$multiopt2 = array();
|
||
$depth = $opt['depth'];
|
||
}
|
||
elseif ($opt['field_id'] != $field_id)
|
||
{
|
||
$depth_col++;
|
||
}
|
||
|
||
$v = array(
|
||
'id' => $opt['pov_id'],
|
||
'price' => $opt['price'],
|
||
);
|
||
|
||
if (!empty($opt['opt_value']))
|
||
{
|
||
$v['opt_vals'] = array_merge((isset($multiopt[$depth_col]['opt_vals']) and is_array($multiopt[$depth_col]['opt_vals'])) ? $multiopt[$depth_col]['opt_vals'] : array(), array($opt['pov_id']));
|
||
}
|
||
|
||
if (!$opt['price'])
|
||
{
|
||
$v['price'] = $multiopt[$depth_col]['price']; //cena z poprzedniego poziomu
|
||
}
|
||
// opcja zmienia cenę o N %
|
||
elseif (preg_match('/([\+-]?[\d\.]+)%/', $v['price'], $m))
|
||
{
|
||
$v['price'] = number_format($multiopt[$depth_col]['price']*(100+$m[1])/100, 2, '.', '');
|
||
}
|
||
// opcja zmienia cenę o określoną kwotę
|
||
elseif (preg_match('/([\+-]?[\d\.]+)/', $v['price'], $m))
|
||
{
|
||
$v['price'] = number_format($multiopt[$depth_col]['price']+$m[1], 2, '.', '');
|
||
}
|
||
|
||
$v['vfeatures'][] = $vfeatures;
|
||
$multiopt2[] = $v;
|
||
$field_id = $opt['field_id'];
|
||
}
|
||
|
||
$p = array($p['price']);
|
||
|
||
foreach ($multiopt2 as $v)
|
||
{
|
||
if (empty($v['opt_vals'])) { continue; }
|
||
if (!$v['id']) { continue; }
|
||
$p[implode('_', $v['opt_vals'])] = $v['price'];
|
||
}
|
||
|
||
if ($price_add or $price_mult != 1)
|
||
{
|
||
|
||
foreach ($p as $vid => $vprice)
|
||
{
|
||
$p[$vid] = number_format($vprice*$price_mult + $price_add, 2, '.', '');
|
||
}
|
||
}
|
||
|
||
$response[$product_id] = $p;
|
||
}
|
||
|
||
$response['pages'] = ceil((int)DB_Result(DB_Query("SELECT COUNT(*) FROM `${dbp}st_product`"))/$per_page);
|
||
|
||
return $response;
|
||
}
|
||
|
||
/**
|
||
* Funkcja ustawia ceny wybranych produktów i ich wariantów
|
||
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
|
||
* @param array $request tablica z żadaniem od systemu:
|
||
* products => tablica zawierająca informacje o zmianach stanu produktu. Każdy element tablicy jest
|
||
* również tablicą składającą się z pól:
|
||
* product_id => ID produktu
|
||
* variant_id => ID wariantu (0 jeśli produkt główny)
|
||
* price => nowa cena
|
||
* @return array $response tablica zawierajaca pole z ilością zmienionych produktów:
|
||
* counter => ilość zmienionych produktów
|
||
*/
|
||
function Shop_ProductsPriceUpdate($request)
|
||
{
|
||
global $options; // globalna tablica z ustawieniami
|
||
$dbp = $options['db_prefix']; //Data Base Prefix - prefix tabel bazy
|
||
|
||
$set_price = array();
|
||
$counter = 0;
|
||
|
||
foreach ($request['products'] as $p)
|
||
{
|
||
if (isset($p['variant_id']) and !empty($p['variant_id']))
|
||
{
|
||
return array('error' => true, 'error_code' => 'NOT_SUPPORTED', 'Zmiana cen wariantów nie obsługiwana w tej wersji integracji');
|
||
}
|
||
|
||
$set_price[(int)$p['product_id']] = $p['price'];
|
||
}
|
||
|
||
$sql = "SELECT p.id, p.opt_price_brutto price, p.price net_price, p.opt_vat tax
|
||
FROM `${dbp}st_product` p
|
||
WHERE p.id IN (" . implode(', ', array_keys($set_price)) . ")";
|
||
$res = DB_Query($sql);
|
||
|
||
$sql = "UPDATE `${dbp}st_product`
|
||
SET opt_price_brutto = '{0}', price = '{1}'
|
||
WHERE id = '{2}' LIMIT 1";
|
||
|
||
while ($p = DB_Fetch($res))
|
||
{
|
||
if (isset($set_price[$p['id']]) and $set_price[$p['id']] >= 0.01)
|
||
{
|
||
$price = $set_price[$p['id']];
|
||
$counter += (DB_Query($sql, $price, $price/(1+$p['tax']/100), $p['id']) ? 1 : 0);
|
||
}
|
||
}
|
||
|
||
return array('counter' => $counter);
|
||
}
|
||
/**
|
||
* Funkcja zwraca stan magazynowy wszystkich produktów i ich wariantów
|
||
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
|
||
* @param array $request tablica z żadaniem od systemu, w przypadku tej funkcji nie używana
|
||
* @return array $response tablica ze stanem magazynowym wszystkich produktów, w formacie:
|
||
* id produktu => ID produktu jest kluczem tablicy, wartością jest tablica składająca się ze stanów wariantów
|
||
* id wariantu => kluczem tablicy jest ID wariantu (0 w przypadku produktu głównego)
|
||
* stan => wartościa jest stan magazynowy
|
||
* Przykład: array('432' => array('0' => 4, '543' => 2, '567' => 3)) - produkt ID 432, stan głównego produktu to 4, posiada dwa warianty (ID 543 i 563) o stanach 2 i 3.
|
||
*/
|
||
function Shop_ProductsQuantity($request)
|
||
{
|
||
global $options; //globalna tablica z ustawieniami
|
||
$dbp = $options['db_prefix']; //Data Base Prefix - prefix tabel bazy
|
||
|
||
$response = array();
|
||
|
||
$sql = "SELECT p.id product_id, p.stock qty,
|
||
pov.id pov_id, pov.stock, pov.depth
|
||
FROM `${dbp}st_product` p
|
||
LEFT JOIN `${dbp}st_product_options_value` pov ON pov.product_id = p.id AND NOT isnull(pov.product_options_value_id)
|
||
ORDER by p.id, pov.depth DESC";
|
||
$res = DB_Query($sql, $product_id);
|
||
//TODO join with product_options_value_id = null to get true main product count
|
||
//or check for null in the loop! Also fix PL with join to pov
|
||
//Actually here just use the last level without all this fuancy logic!
|
||
|
||
$prod_id = 0;
|
||
$depth = 0;
|
||
|
||
while ($opt = DB_Fetch($res))
|
||
{
|
||
if ($prod_id == $opt['product_id'] and $depth > $opt['depth'])
|
||
{
|
||
continue;
|
||
}
|
||
|
||
$response[$opt['product_id']][0] = (int)$opt['qty'];
|
||
|
||
if ($opt['pov_id'])
|
||
{
|
||
$response[$opt['product_id']][$opt['pov_id']] = (int)$opt['stock'];
|
||
}
|
||
|
||
$prod_id = $opt['product_id'];
|
||
$depth = $opt['depth'];
|
||
}
|
||
|
||
return $response;
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Funkcja ustawia stan magazynowy wybranych produktów i ich wariantów
|
||
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
|
||
* @param array $request tablica z żadaniem od systemu:
|
||
* products => tablica zawierająca informacje o zmianach stanu produktu. Każdy element tablicy jest również tablicą składającą się z pól:
|
||
* product_id => ID produktu
|
||
* variant_id => ID wariantu (0 jeśli produkt główny)
|
||
* operation => rodzaj zmiany, dopuszczalne wartości to: 'set' (ustawia konkretny stan), 'change' (dodaje do stanu magazynowego, ujemna liczba w polu quantity zmniejszy stan o daną ilość sztuk, dodatnia zwiększy)
|
||
* quantity => zmiana stanu magazynowego (ilośc do ustawienia/zmniejszenia/zwiększenia zależnie od pola operation)
|
||
* @return array $response tablica zawierajaca pole z ilością zmienionych produktów:
|
||
* counter => ilość zmienionych produktów
|
||
*/
|
||
function Shop_ProductsQuantityUpdate($request)
|
||
{ global $options; // globalna tablica z ustawieniami
|
||
$dbp = $options['db_prefix']; // Data Base Prefix - prefix tabel bazy
|
||
|
||
foreach ($request['products'] as $prod)
|
||
{
|
||
$prod['quantity'] = (int)$prod['quantity'];
|
||
|
||
if ($prod['variant_id'])
|
||
{
|
||
$sql = "SELECT stock, lft, rgt FROM `${dbp}st_product_options_value`
|
||
WHERE product_id = '{0}' AND id = '{1}'";
|
||
$res = DB_Query($sql, $prod['product_id'], $prod['variant_id']);
|
||
|
||
if (!DB_NumRows($res))
|
||
{
|
||
continue; // nie znaleziono wariantu
|
||
}
|
||
|
||
$node = DB_Fetch($res);
|
||
}
|
||
|
||
if ($prod['operation'] == 'change') // zmiana względem aktualnego stanu
|
||
{
|
||
$mod = "if(stock >= -${prod['quantity']}, stock+${prod['quantity']}, 0)";
|
||
}
|
||
elseif ($prod['variant_id']) // podana liczba sztuk wariantu
|
||
{
|
||
// dla wszystkich powiązanych rekordów (gałęzie pov + produkt gł)
|
||
// używamy wartości względnej
|
||
$prod['quantity'] = $prod['quantity'] - (int)$node['stock'];
|
||
$mod = "if(stock >= -${prod['quantity']}, stock+${prod['quantity']}, 0)";
|
||
}
|
||
else // ustawienie konkretnej ilości sztuk dla produktu głównego
|
||
{
|
||
$mod = $prod['quantity'];
|
||
}
|
||
|
||
// aktualizacja stanu produktu głównego w tabeli st_product
|
||
DB_Query("UPDATE `${dbp}st_product` SET stock = $mod WHERE id = '{0}'", $prod['product_id']);
|
||
|
||
// aktualizacja stanu produktu głównego w tabeli st_product_options_value
|
||
DB_Query("UPDATE `${dbp}st_product_options_value` SET stock = $mod
|
||
WHERE product_id = '{0}' AND depth = 0", $prod['product_id']);
|
||
|
||
if ($prod['variant_id'])
|
||
{
|
||
$upd = "UPDATE `${dbp}st_product_options_value` SET stock = $mod
|
||
WHERE product_id = {0} AND id = {1}";
|
||
|
||
// aktualizacja stanów wszystkich atrybutów wariantu
|
||
$sql = "SELECT id FROM `${dbp}st_product_options_value`
|
||
WHERE product_id = {0} AND depth > 0 AND lft <= {1} AND rgt >= {2}";
|
||
$res = DB_Query($sql, $prod['product_id'], $node['lft'], $node['rgt']);
|
||
|
||
while ($opt = DB_Fetch($res))
|
||
{
|
||
DB_Query($upd, $prod['product_id'], $opt['id']);
|
||
}
|
||
}
|
||
}
|
||
|
||
return array('counter' => count($request['products']));
|
||
}
|
||
|
||
|
||
/**
|
||
* Funkcja tworzy zamówienie w sklepie na podstawie nadesłanych danych
|
||
* Jeśli funkcja otrzyuje na wejściu ID zamówienia, aktualizuje dane zamówienie zamiast tworzyć nowe
|
||
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
|
||
* @param array $request tablica z żadaniem od systemu, zawiera informacje o zamówieniu w formacie:
|
||
* previous_order_id => ID zamówienia (jeśli pierwszy raz dodawane do sklepu, wartość jest pusta. Jeśli było już wcześniej dodane, wartość zawiera poprzedni numer zamówienia)
|
||
* delivery_fullname, delivery_company, delivery_address, delivery_city, delivery_postcode, delivery_country => dane dotyczące adresu wysyłki
|
||
* invoice_fullname, invoice_company, invoice_address, invoice_city, invoice_postcode, invoice_country, invoice_nip => dane dotyczące adresu płatnika faktury
|
||
* phone => nr telefonu, email => adres email,
|
||
* delivery_method => nazwa sposóbu wysyłki, delivery_method_id => numer ID sposobu wysyłki, delivery_price => cena wysyłki
|
||
* user_comments => komentarz kupującego, currency => waluta zamówienia, status_id => status nowego zamówienia
|
||
* change_products_quantity => flaga (bool) informująca, czy po stworzeniu zamówienia zmniejszony ma zostać stan zakupionych produktów
|
||
* products => tablica z zakupionymi produktami w formacie:
|
||
* [] =>
|
||
* id => ID produktu
|
||
* variant_id => ID wariantu
|
||
* name => nazwa produktu (używana jeśli nie można pobrać jej z bazy na podstawie id)
|
||
* price => cena brutto w PLN
|
||
* currency => waluta
|
||
* quantity => zakupiona ilość
|
||
* attributes => tablica z atrybutami produktu w formacie:
|
||
* [] =>
|
||
* name => nazwa atrybutu (np. "kolor")
|
||
* value => wartość atybutu (np. "czerwony")
|
||
* price => różnica ceny dla tego produktu (np. "-10.00")
|
||
* zmiana ceny jest już uwzględniona w cenie produktu
|
||
* @return array $response tablica zawierająca numer nowego zamówienia:
|
||
* 'order_id' => numer utworzonego zamówienia
|
||
*/
|
||
function Shop_OrderAdd($request)
|
||
{
|
||
global $options; // globalna tablica z ustawieniami
|
||
$dbp = $options['db_prefix']; // Data Base Prefix - prefix tabel bazy
|
||
|
||
// zdefiniowanie waluty
|
||
$request['currency'] = $request['currency'] ? $request['currency'] : 'PLN';
|
||
$sql = "SELECT * FROM `${dbp}st_currency` WHERE shortcut = '${request['currency']}' LIMIT 1";
|
||
$res = DB_Query($sql);
|
||
$currency = DB_Fetch($res);
|
||
|
||
// jeśli zamówienie jest ponownie dodawane do bazy sklepu, wcześniejsze dane są usuwane
|
||
// przy ponownym dodawaniu zamówienia (aktualizowaniu), $request['previous_order_id'] zawiera poprzedni numer danego zamówienia w sklepie
|
||
if ($request['previous_order_id'] != "")
|
||
{
|
||
if ($options['use_order_numbers'])
|
||
{
|
||
if (!($request['previous_order_id'] = DB_Result(DB_Query("SELECT id FROM `${dbp}st_order` WHERE number = '{0}' ORDER BY id DESC", $request['previous_order_id']))))
|
||
{
|
||
return array('error' => true, 'error_code' => 'NO_MATCH', 'error_text' => "Zamówienie #${request['previous_order_id']} nie istnieje."); // nie udało się dopasować zamówienia po numerze
|
||
}
|
||
}
|
||
|
||
$sql = "SELECT o.* FROM `${dbp}st_order` o WHERE o.id = '${request['previous_order_id']}' ";
|
||
$old = DB_Fetch(DB_Query($sql));
|
||
|
||
DB_Query("DELETE FROM `${dbp}st_order_delivery` WHERE `id` = '{0}'", $old['order_delivery_id']);
|
||
DB_Query("DELETE FROM `${dbp}st_order_user_data_billing` WHERE `id` = '{0}'", $old['order_user_data_billing_id']);
|
||
DB_Query("DELETE FROM `${dbp}st_order_user_data_delivery` WHERE `id` = '{0}'", $old['order_user_data_delivery_id']);
|
||
DB_Query("DELETE FROM `${dbp}st_order_currency` WHERE `id` = '{0}'", $old['order_currency_id']);
|
||
DB_Query("DELETE FROM `${dbp}st_order_product` WHERE `order_id` = '{0}'", $old['id']);
|
||
DB_Query("DELETE FROM `${dbp}st_order` WHERE `id` = '{0}'", $old['id']);
|
||
DB_Query("DELETE FROM `${dbp}st_order_has_payment` WHERE `order_id` = '{0}'", $old['id']);
|
||
}
|
||
|
||
// dodawanie waluty zamówienia
|
||
$sql = "INSERT INTO `${dbp}st_order_currency` (created_at, updated_at,
|
||
exchange, shortcut, front_symbol, back_symbol, name)
|
||
VALUES (now(), now(), '{0}', '{1}', '{2}', '{3}', '{4}')";
|
||
$res = DB_Query($sql, $currency['exchange'], $request['currency'], $currency['front_symbol'],
|
||
$currency['back_symbol'], $currency['opt_name']);
|
||
$currency_id = DB_Identity();
|
||
|
||
// pobieranie id kraju
|
||
$sql = "SELECT id FROM `${dbp}st_countries`
|
||
WHERE iso_a2 = '{0}' OR opt_name = '{1}' LIMIT 1";
|
||
$invoice_country_id = DB_Result(DB_Query($sql, $request['invoice_country_code'], $request['invoice_country']));
|
||
|
||
$sql = "SELECT id FROM `${dbp}st_countries`
|
||
WHERE iso_a2 = '{0}' OR opt_name = '{1}' LIMIT 1";
|
||
$delivery_country_id = DB_Result(DB_Query($sql, $request['delivery_country_code'], $request['delivery_country']));
|
||
|
||
// język
|
||
$culture = strtolower($request['invoice_country_code']);
|
||
|
||
if ($culture == 'pl')
|
||
{
|
||
$culture .= '_PL';
|
||
}
|
||
elseif ($culture == 'uk' or $culture == 'us' or $culture == 'au' or $culture == 'ca' or $culture == 'ie' or $culture == 'gb')
|
||
{
|
||
$culture = 'en_US';
|
||
}
|
||
|
||
// dodstawa do punktu odbioru
|
||
$has_paczkomaty = false; // czy sote obsługuje dodatkowe pole w st_order_delivery
|
||
$has_pickup_point = false; // czy sote obsługuje pole pickup_point w st_order_delivery
|
||
|
||
if (isset($request['delivery_point_name']) and !empty($request['delivery_point_name']))
|
||
{
|
||
if (!empty($request['delivery_point_name']) and preg_match('/paczkomat/i', $request['delivery_method']) and DB_NumRows(DB_Query("SHOW FIELDS FROM `${dbp}st_order_delivery` LIKE 'paczkomaty_number'")))
|
||
{
|
||
$has_paczkomaty = true;
|
||
}
|
||
elseif (DB_NumRows(DB_Query("SHOW FIELDS FROM `${dbp}st_order_delivery` LIKE 'pickup_point'")))
|
||
{
|
||
$has_pickup_point = true;
|
||
}
|
||
else
|
||
{
|
||
$request['delivery_fullname'] = $request['delivery_point_name'];
|
||
}
|
||
|
||
foreach (array('city', 'postcode', 'address') as $fld)
|
||
{
|
||
$request["delivery_$fld"] = $request["delivery_point_$fld"];
|
||
}
|
||
}
|
||
|
||
|
||
// sprawdzanie czy użytkownik już istnieje w bazie danych
|
||
$sql = "SELECT id FROM `${dbp}sf_guard_user` WHERE username = '{0}'";
|
||
$res = DB_Query($sql, $request['email']);
|
||
|
||
if (DB_NumRows($res) > 0)
|
||
{
|
||
$user_id = DB_Result($res);
|
||
}
|
||
else
|
||
{
|
||
// dodawanie użytkownika do tabeli sf_guard_user
|
||
$sql = "INSERT INTO `${dbp}sf_guard_user`
|
||
(username, algorithm, salt, password, created_at,
|
||
last_login, is_active, is_super_admin, is_confirm, is_admin_confirm,
|
||
hash_code, language, external_account, wholesale, points,
|
||
points_available, points_release) VALUES
|
||
('{0}', 'sha1', 'allegro_user', 'allegro_user', '{1}',
|
||
'{1}', 1, 0, 0, 0,
|
||
'{2}', '{3}', NULL, '', 0,
|
||
1, 0);";
|
||
DB_Query($sql, $request['email'], date('Y-m-d H:i:s'), md5(microtime(true)*rand(10,10000000)), $culture);
|
||
$user_id = DB_Identity();
|
||
|
||
$sql = "INSERT INTO `sf_guard_user_group` (`user_id`, `group_id`) VALUES ('{0}', 2);";
|
||
DB_Query($sql, $user_id);
|
||
}
|
||
|
||
$invoice_street = explode(' ',$request['invoice_address']);
|
||
$invoice_house = array_pop($invoice_street);
|
||
$invoice_street = implode(' ',$invoice_street);
|
||
|
||
$request['invoice_country'] = $request['invoice_country'] ? $request['invoice_country'] : 'Polska';
|
||
$request['delivery_country'] = $request['delivery_country'] ? $request['delivery_country'] : 'Polska';
|
||
|
||
// prawidłowa nazwa kraju - ważna w niektórych instalacjach Sote
|
||
$sql = "SELECT name
|
||
FROM `st_countries` c
|
||
JOIN `st_countries_i18n` ci ON c.id = ci.id AND ci.culture = 'pl_PL'
|
||
WHERE iso_a2 = '{0}'";
|
||
|
||
foreach (array('invoice', 'delivery') as $type)
|
||
{
|
||
if (!empty($request["${type}_country_code"]))
|
||
{
|
||
if ($cname = DB_Result(DB_Query($sql, $request["${type}_country_code"])))
|
||
{
|
||
$request["${type}_country"] = $cname;
|
||
}
|
||
}
|
||
}
|
||
|
||
// wybór funkcji szyfrującej
|
||
if (!empty($options['sote_dir']))
|
||
{
|
||
$crypt = 2;
|
||
}
|
||
else
|
||
{
|
||
$crypt = ('a' == Sote_Encrypt('a')) ? 0 : 1;
|
||
}
|
||
|
||
// dodawanie adresu płatnika do tabeli st_order_user_data_billing
|
||
$sql = "INSERT INTO `${dbp}st_order_user_data_billing` (
|
||
created_at, updated_at, country , full_name, company,
|
||
address ,code , town , street, house,
|
||
phone, vat_number, countries_id, crypt) VALUES (
|
||
'{0}', '{0}', '{1}', '{2}', '{3}',
|
||
'{4}', '{5}', '{6}', NULL, NULL,
|
||
'{9}' , '{10}', '{11}', '{12}')";
|
||
DB_Query($sql, date('Y-m-d H:i:s'), $request['invoice_country'], $request['invoice_fullname'], $request['invoice_company'],
|
||
Sote_Encrypt($request['invoice_address'], $crypt), Sote_Encrypt($request['invoice_postcode'], $crypt), Sote_Encrypt($request['invoice_city'], $crypt), Sote_Encrypt($invoice_street, $crypt), Sote_Encrypt($invoice_house, $crypt),
|
||
Sote_Encrypt($request['phone'], $crypt), $request['invoice_nip'], $invoice_country_id, $crypt);
|
||
$invoice_address_id = DB_Identity();
|
||
|
||
$delivery_street = explode(' ', $request['delivery_address']);
|
||
$delivery_house = array_pop($delivery_street);
|
||
$delivery_street = implode(' ', $delivery_street);
|
||
|
||
// dodawanie adresu dostawy do tabeli st_order_user_data_delivery
|
||
$sql = "INSERT INTO `${dbp}st_order_user_data_delivery` (
|
||
created_at, updated_at, country, full_name, company,
|
||
address, code, town, street, house,
|
||
phone, countries_id, crypt) VALUES (
|
||
'{0}', '{0}', '{1}', '{2}', '{3}',
|
||
'{4}', '{5}', '{6}', NULL, NULL,
|
||
'{9}', '{10}', '{11}')";
|
||
DB_Query($sql, date('Y-m-d H:i:s'), $request['delivery_country'], $request['delivery_fullname'], $has_paczkomaty ? "Paczkomat - ${request['delivery_point_id']}" : $request['delivery_company'],
|
||
Sote_Encrypt($request['delivery_address'], $crypt), Sote_Encrypt($request['delivery_postcode'], $crypt), Sote_Encrypt($request['delivery_city'], $crypt), Sote_Encrypt($delivery_street, $crypt), Sote_Encrypt($delivery_house, $crypt),
|
||
Sote_Encrypt($request['phone'], $crypt), $delivery_country_id, $crypt);
|
||
$delivery_address_id = DB_Identity();
|
||
|
||
// VAT kosztów wysyłki
|
||
$sql = "SELECT d.tax_id, t.vat
|
||
FROM `${dbp}st_delivery` d JOIN `st_tax` t ON d.tax_id = t.id
|
||
ORDER BY (d.id = '{0}') DESC, d.is_default DESC, d.is_system_default DESC LIMIT 1";
|
||
$res = DB_Query($sql, $request['delivery_method_id']);
|
||
|
||
if (!($delivery_tax = DB_Fetch($res)))
|
||
{
|
||
$delivery_tax = array('tax_id' => 0, 'vat' => 23);
|
||
}
|
||
|
||
// dodawanie informacji o dostawie do tabeli st_order_delivery
|
||
$delivery_netto = number_format($request['delivery_price']/(100+$delivery_tax['vat'])*100, 2, '.', '');
|
||
$sql = "INSERT INTO `${dbp}st_order_delivery`
|
||
(created_at, updated_at, name, cost, opt_tax,
|
||
cost_brutto, delivery_id, tax_id" . ($has_paczkomaty ? ', paczkomaty_number' : ($has_pickup_point ? ', pickup_point' : '')) . ")
|
||
VALUES ('{0}', '{0}', '{1}', '{2}', '{3}',
|
||
'{4}', '{5}', '{6}'" . (($has_paczkomaty or $has_pickup_point) ? ", '{7}'" : '') . ")";
|
||
DB_Query($sql, date('Y-m-d H:i:s'), $request['delivery_method'], $delivery_netto, $delivery_tax['vat'], $request['delivery_price'],
|
||
$request['delivery_method_id'], $delivery_tax['tax_id'], ($has_paczkomaty or $has_pickup_point) ? $request['delivery_point_id'] : '');
|
||
$delivery_id = DB_Identity();
|
||
|
||
// karta klienta - adresy dostawy i płatności
|
||
$sql = "INSERT INTO `${dbp}st_user_data`
|
||
(crypt, created_at, updated_at, is_billing, is_default,
|
||
sf_guard_user_id, countries_id, street, house, code,
|
||
town, phone, full_name, address,
|
||
company, vat_number)
|
||
VALUES
|
||
('{11}', '{0}', '{0}', {10}, 1,
|
||
{1}, '{2}', NULL, NULL, '{5}',
|
||
'{6}', '{7}', '{8}', '{9}',
|
||
'{12}', '{13}')
|
||
ON DUPLICATE KEY UPDATE is_billing = {10}";
|
||
DB_Query($sql, date('Y-m-d H:i:s'),
|
||
$user_id, $invoice_country_id, Sote_Encrypt($invoice_street, $crypt), Sote_Encrypt($invoice_house, $crypt), Sote_Encrypt($request['invoice_postcode'], $crypt),
|
||
Sote_Encrypt($request['invoice_city'], $crypt), Sote_Encrypt($request['phone'], $crypt), $request['invoice_fullname'], Sote_Encrypt($request['invoice_address'], $crypt), 1, $crypt, $request['invoice_company'], $request['invoice_nip']);
|
||
DB_Query($sql, date('Y-m-d H:i:s'),
|
||
$user_id, $delivery_country_id, Sote_Encrypt($delivery_street, $crypt), Sote_Encrypt($delivery_house, $crypt), Sote_Encrypt($request['delivery_postcode'], $crypt),
|
||
Sote_Encrypt($request['delivery_city'], $crypt), Sote_Encrypt($request['phone'], $crypt), $request['delivery_fullname'], Sote_Encrypt($request['delivery_address'], $crypt), 0, $crypt, $request['delivery_company'], '');
|
||
|
||
// klucz bezpieczeństwa klienta
|
||
$secure_key = md5(microtime(true)*rand(10,10000000));
|
||
$secure_key2 = md5(microtime(true)*rand(10,10000000));
|
||
|
||
// wyliczanie całkowitego kosztu zamówienia
|
||
$total_sum = 0;
|
||
|
||
foreach ($request['products'] as $prod)
|
||
{
|
||
$total_sum += $prod['price'] * $prod['quantity'];
|
||
}
|
||
|
||
$total_sum += $request['delivery_price'];
|
||
$lock = false; // lock zapobiegający dublowaniu numeracji
|
||
|
||
// pobieranie numeru ostatniego zamowienia
|
||
if ($request['previous_order_id'] != '')
|
||
{
|
||
$last_nr = $request['previous_order_id'];
|
||
}
|
||
else
|
||
{
|
||
if ($lock = @fopen('bl.lock', 'r+'))
|
||
{
|
||
flock($lock, LOCK_EX);
|
||
}
|
||
|
||
$sql = "SELECT number FROM `${dbp}st_order` ORDER BY ABS(number) DESC LIMIT 1";
|
||
$res = DB_Query($sql);
|
||
$last_nr = (int)DB_Result($res)+1;
|
||
}
|
||
|
||
// dodanie zamowienia do tabeli orders
|
||
$sql = "INSERT INTO `${dbp}st_order` (
|
||
created_at, updated_at, id, order_delivery_id, order_user_data_delivery_id,
|
||
order_user_data_billing_id, order_currency_id, order_status_id, sf_guard_user_id, hash_code,
|
||
number, description, client_culture, is_confirmed, opt_client_name,
|
||
opt_client_email, opt_client_company, opt_total_amount)
|
||
VALUES ('{0}', '{0}', '{1}' , '{2}', '{3}',
|
||
'{4}', '{5}', '{6}', '{7}', '{8}',
|
||
'{9}', '{10}', '{11}', '1', '{12}',
|
||
'{13}', '{14}', '{15}')";
|
||
DB_Query($sql, date('Y-m-d H:i:s'), $request['previous_order_id'], $delivery_id, $delivery_address_id,
|
||
$invoice_address_id, $currency_id, $request['status_id'], $user_id, $secure_key,
|
||
$last_nr, $request['user_comments'], $culture, $request['invoice_fullname'],
|
||
$request['email'], $request['invoice_company'], $total_sum);
|
||
// pobieranie numeru nowego zamówienia
|
||
$this_order_id = $request['previous_order_id'] ? $request['previous_order_id'] : DB_Identity();
|
||
|
||
if (!$request['previous_order_id'] and $this_order_id)
|
||
{
|
||
// jeżeli w przeciągu 10 sekund dodało się zamówienie z tym samym numerem
|
||
while (DB_Result(DB_Query("SELECT count(*) FROM `${dbp}st_order` WHERE number = '{0}' AND created_at > '{1}'", $last_nr, date('Y-m-d H:i:s', time()-10))) > 1)
|
||
{
|
||
// zwiększamy numer zamówienia
|
||
DB_Query("UPDATE `${dbp}st_order` SET number = '{0}' WHERE id = '{1}' LIMIT 1", ++$last_nr, $this_order_id);
|
||
}
|
||
}
|
||
|
||
if ($lock)
|
||
{
|
||
flock($lock, LOCK_UN);
|
||
fclose($lock);
|
||
}
|
||
|
||
// typ płatności
|
||
if (empty($request['payment_method_id']))
|
||
{
|
||
$sql = "SELECT id FROM `${dbp}st_payment_type`
|
||
WHERE active ORDER BY (module_name = 'stStandardPayment') DESC,
|
||
(opt_name {0} like '%pobran%') DESC LIMIT 1";
|
||
$res = DB_Query($sql, $request['payment_method_cod'] ? '' : 'not');
|
||
$payment_type_id = DB_Result($res);
|
||
}
|
||
else
|
||
{
|
||
$payment_type_id = $request['payment_method_id'];
|
||
}
|
||
|
||
// dodawanie płatności
|
||
$sql = "INSERT INTO `${dbp}st_payment`
|
||
(created_at, updated_at, sf_guard_user_id, payment_type_id, amount,
|
||
status, cancel, hash, version) VALUES
|
||
('{0}', '{0}', '{1}', '{2}', '{3}',
|
||
0, 0, '{4}', 2)";
|
||
DB_Query($sql, date('Y-m-d H:i:s'), $user_id, $payment_type_id, $total_sum, $secure_key2);
|
||
$this_payment_id = DB_Identity();
|
||
|
||
if (DB_NumRows(DB_Query("SHOW FIELDS FROM `${dbp}st_order_has_payment` LIKE 'created_at'")))
|
||
{
|
||
$sql = "INSERT INTO `${dbp}st_order_has_payment`
|
||
(created_at, updated_at, order_id, payment_id) VALUES
|
||
('{0}', '{0}', '{1}', '{2}')";
|
||
}
|
||
else
|
||
{
|
||
$sql = "INSERT INTO `${dbp}st_order_has_payment`
|
||
(order_id, payment_id) VALUES
|
||
('{1}', '{2}')";
|
||
}
|
||
|
||
DB_Query($sql, date('Y-m-d H:i:s'), $this_order_id, $this_payment_id);
|
||
|
||
// obsługa produktów w zamówieniu
|
||
foreach ($request['products'] as $prod)
|
||
{
|
||
$sql = "SELECT * FROM `${dbp}st_product` p WHERE p.id = '{0}'";
|
||
$res = DB_Query($sql, $prod['id']);
|
||
$prod_data = DB_Fetch($res);
|
||
|
||
if (!$prod_data)
|
||
{
|
||
$prod_data = array('opt_vat' => isset($prod['tax']) ? $prod['tax'] : 0);
|
||
}
|
||
|
||
$price_netto = $prod['price'] / (1+$prod_data['opt_vat']/100);
|
||
$price_modifiers = array();
|
||
|
||
// obsługa wariantu
|
||
if (!empty($prod['variant_id']))
|
||
{
|
||
$sql = "SELECT pov.depth, pov.lft, pov.rgt, pov.opt_value, pov.use_product,
|
||
pov.color, pof.opt_name
|
||
FROM `${dbp}st_product_options_value` pov
|
||
LEFT JOIN `${dbp}st_product_options_field` pof ON pof.id = pov.product_options_field_id
|
||
WHERE pov.product_id = '{0}' AND pov.id = '{1}'";
|
||
$res = DB_Query($sql, $prod['id'], $prod['variant_id']);
|
||
|
||
if (DB_NumRows($res))
|
||
{
|
||
$leaf = DB_Fetch($res);
|
||
|
||
$price_modifiers[] = array(
|
||
'value' => (float)0,
|
||
'type' => 'percent',
|
||
'level' => (int)$leaf['depth'],
|
||
'prefix' => '+',
|
||
'custom' => array(
|
||
'id' => (int)$prod['variant_id'],
|
||
'color' => $leaf['color'],
|
||
'field' => $leaf['opt_name'],
|
||
'type' => 'product_options',
|
||
),
|
||
'label' => $leaf['opt_value']
|
||
);
|
||
|
||
$prod_data['code'] = $leaf['use_product'];
|
||
|
||
// pozostałe opcje wyboru dla tego wariantu
|
||
$sql = "SELECT id, depth, opt_value
|
||
FROM `${dbp}st_product_options_value`
|
||
WHERE product_id = {0} AND depth > 0 AND lft < {1} and rgt > {2}
|
||
ORDER BY depth desc";
|
||
$res = DB_Query($sql, $prod['id'], $leaf['lft'], $leaf['rgt']);
|
||
|
||
while ($opt = DB_Fetch($res))
|
||
{
|
||
array_unshift($price_modifiers, array(
|
||
'value' => (float)0,
|
||
'type' => 'percent',
|
||
'level' => $opt['depth'],
|
||
'prefix' => '+',
|
||
'custom' => array(
|
||
'id' => (int)$opt['id'],
|
||
'type' => 'product_options',
|
||
),
|
||
'label' => $opt['opt_name'],
|
||
));
|
||
}
|
||
}
|
||
|
||
// nazwa produktu pobrana ze sklepu
|
||
if ($prod_data['name'] and $prod['name'])
|
||
{
|
||
$prod['name'] = $prod_data['name'];
|
||
}
|
||
}
|
||
|
||
|
||
// dodawanie produktu do zamowienia
|
||
$sql = "INSERT INTO `${dbp}st_order_product` (
|
||
created_at, updated_at, order_id, product_id, quantity,
|
||
code, name, image, price, price_brutto,
|
||
vat, price_modifiers, version, tax_id, discount)
|
||
VALUES (
|
||
'{0}', '{0}', '{1}', '{2}', '{3}',
|
||
'{4}', '{5}', '{6}', '{7}', '{8}',
|
||
'{9}', '{10}', '{11}', '{12}', '{13}')";
|
||
DB_Query($sql, date('Y-m-d H:i:s'), $this_order_id, $prod['id'], $prod['quantity'],
|
||
$prod_data['code'], $prod['name'], $prod_data['opt_image'], $price_netto, $prod['price'],
|
||
$prod_data['opt_vat'], serialize($price_modifiers), 3, $prod_data['tax_id'],
|
||
serialize(array()));
|
||
|
||
|
||
// zmniejszanie stanu magazynowego produktu (jeśli ustawiona flaga change_products_quantity)
|
||
if ($request['previous_order_id'] == '' and $request['change_products_quantity'])
|
||
{
|
||
Shop_ProductsQuantityUpdate(array('products' => array(array('product_id' => $prod['id'], 'variant_id' => $prod['variant_id'], 'operation' => 'change', 'quantity' => -1*$prod['quantity']))));
|
||
}
|
||
}
|
||
|
||
if ($options['use_order_numbers'])
|
||
{
|
||
$this_order_id = DB_Result(DB_Query("SELECT number FROM `${dbp}st_order` WHERE id = '{0}' ORDER BY id DESC", $this_order_id));
|
||
}
|
||
|
||
return array('order_id' => $this_order_id);
|
||
}
|
||
|
||
/**
|
||
* Funkcja pobiera zamówienia złożone w sklepie internetowym
|
||
* Zwracane liczby (np ceny) powinny mieć format typu: 123456798.12 (kropka oddziela część całkowitą, 2 miejsca po przecinku)
|
||
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
|
||
* @param array $request tablica z żadaniem od systemu, zawiera informacje o zamówieniu w formacie:
|
||
* time_from => czas od którego mają zastać pobrane zamówienia - format UNIX TIME
|
||
* id_from => ID od którego mają zastać pobrane zamówienia
|
||
* only_paid => flaga określająca czy pobierane mają być tylko zamówienia opłacone (0/1)
|
||
* @return array $response tablica zawierająca dane zamówień:
|
||
* id zamówienia => array:
|
||
* delivery_fullname, delivery_company, delivery_address, delivery_city, delivery_postcode, delivery_country => dane dotyczące adresu wysyłki
|
||
* invoice_fullname, invoice_company, invoice_address, invoice_city, invoice_postcode, invoice_country, invoice_nip => dane dotyczące adresu płatnika faktury
|
||
* phone => nr telefonu, email => adres email,
|
||
* date_add => data złożenia zamówienia,
|
||
* payment_method => nazwa metody płatności,
|
||
* user_comments => komentarz klienta do zamówienia,
|
||
* status_id => numer ID statusu zamówienia,
|
||
* delivery_method_id => numer ID metody wysyłki, delivery_method => nazwa metody wysyłki,
|
||
* delivery_price => cena wysyłki
|
||
* products => array:
|
||
* [] =>
|
||
* id => id produktu, variant_id => id wariantu produktu (0 jeśli produkt główny),
|
||
name => nazwa produktu
|
||
* quantity => zakupiona ilość, price => cena sztuki brutto (uwzględniająca atrybuty)
|
||
* weight => waga produktu w kg, tax => wysokość podatku jako liczba z zakresu 0-100
|
||
* attributes => array: - tablica z wybieralnymi atrybutami produktów (jeśli istnieją)
|
||
* [] =>
|
||
* name => nazwa atrybutu (np 'kolor'),
|
||
* value => wartość atrubutu (np 'czerwony'),
|
||
* price => różnica w cenie w stosunku do ceny standardowe
|
||
*/
|
||
function Shop_OrdersGet($request)
|
||
{
|
||
global $options; // globalna tablica z ustawieniami
|
||
$dbp = $options['db_prefix']; // Data Base Prefix - prefix tabel bazy
|
||
|
||
$response = array();
|
||
|
||
// dostawa w weekend?
|
||
$has_weekend_delivery = DB_NumRows(DB_Query("SHOW FIELDS FROM `${dbp}st_order_delivery` LIKE 'weekend_delivery_cost_brutto'"));
|
||
|
||
//sprawdzamy czy sklep obsługuje punkty odbioru Poczty Polskiej
|
||
$poczta_polska_punkt_odbioru = DB_NumRows(DB_Query("SHOW TABLES LIKE '${dbp}st_poczta_polska_punkt_odbioru'"));
|
||
|
||
//plugin paczki w ruchu
|
||
$pwr_number = DB_NumRows(DB_Query("SHOW FIELDS FROM `${dbp}st_order_delivery` LIKE 'pwr_number'"))*DB_NumRows(DB_Query("SHOW TABLES LIKE '${dbp}aa_pwr_points'"));
|
||
$pickup_point = DB_NumRows(DB_Query("SHOW FIELDS FROM `${dbp}st_order_delivery` LIKE 'pickup_point'"));
|
||
|
||
//dodatkowe dane dostawy w oddzielnej tabeli?
|
||
$sheepla_orders = DB_NumRows(DB_Query("SHOW TABLES LIKE '${dbp}sheepla_orders'"));
|
||
$has_paczkomaty = DB_NumRows(DB_Query("SHOW FIELDS FROM `${dbp}st_order_delivery` LIKE 'paczkomaty_number'"));
|
||
$has_dhl = DB_NumRows(DB_Query("SHOW FIELDS FROM `${dbp}st_order_delivery` LIKE 'aa_dhl_service_point'"));
|
||
|
||
//formatowanie daty od której mają być pobrane zamówienia
|
||
$time_from = date("Y-m-d H:i:s", $request['time_from']);
|
||
$id_from = (int)$request['id_from'];
|
||
|
||
//zapytanie pobierające zamówienia od określonego czasu
|
||
$sql = "SELECT o.*, UNIX_TIMESTAMP(o.created_at) time_purchased, od.crypt od_crypt, ob.crypt ob_crypt,
|
||
od.full_name delivery_name, od.address delivery_street_address, od.address_more delivery_street_address2,
|
||
od.town delivery_city, od.code delivery_postcode, od.company delivery_company, od.phone delivery_phone,
|
||
ob.full_name customers_name, ob.address customers_street_address, ob.address_more customers_street_address2,
|
||
ob.town customers_city, ob.code customers_postcode, ob.company customers_company, ob.phone customers_phone,
|
||
ob.vat_number customers_nip, del.cost_brutto + if(del.payment_cost_brutto, del.payment_cost_brutto, 0) delivery_cost,
|
||
del.name delivery_method, oc.shortcut currency,
|
||
od.country delivery_country, ob.country customers_country, cod.name delivery_country_pl, cob.name customers_country_pl,
|
||
oc.exchange, obc.iso_a2 invoice_country_code, obd.iso_a2 delivery_country_code, del.delivery_id
|
||
" . ($pwr_number ? ', del.pwr_number' : '') . "
|
||
" . ($pickup_point ? ', del.pickup_point' : '') . "
|
||
" . ($has_paczkomaty ? ', del.paczkomaty_number' : '') . "
|
||
" . ($has_weekend_delivery ? ', del.weekend_delivery_cost_brutto, del.is_weekend_delivery' : '') . "
|
||
" . ($has_dhl ? ', del.aa_dhl_service_point' : '') . "
|
||
FROM `${dbp}st_order` o
|
||
LEFT JOIN `${dbp}st_order_user_data_billing` ob ON ob.id = o.order_user_data_billing_id
|
||
LEFT JOIN `${dbp}st_order_user_data_delivery` od ON od.id = o.order_user_data_delivery_id
|
||
LEFT JOIN `${dbp}st_order_delivery` del ON del.id = o.order_delivery_id
|
||
LEFT JOIN `${dbp}st_order_currency` oc ON oc.id = o.order_currency_id
|
||
LEFT JOIN `${dbp}st_countries_i18n` cod ON cod.id = od.countries_id AND cod.culture LIKE 'pl%'
|
||
LEFT JOIN `${dbp}st_countries_i18n` cob ON cob.id = ob.countries_id AND cob.culture LIKE 'pl%'
|
||
LEFT JOIN `${dbp}st_countries` obc ON obc.id = ob.countries_id
|
||
LEFT JOIN `${dbp}st_countries` obd ON obd.id = od.countries_id
|
||
WHERE o.created_at >= '{0}' AND o.id >= {1}";
|
||
$sql .= ($options['og_host'] ? " AND o.host = '{2}'" : '');
|
||
|
||
$res = DB_Query($sql, $time_from, $id_from, $options['og_host']);
|
||
|
||
while ($order = DB_Fetch($res))
|
||
{
|
||
$o = array('currency' => $order['currency']);
|
||
$o['delivery_fullname'] = $order['delivery_name'];
|
||
$o['delivery_company'] = html_entity_decode($order['delivery_company']);
|
||
$o['delivery_address'] = Sote_Decrypt($order['delivery_street_address'], $order['od_crypt'])." ".Sote_Decrypt($order['delivery_street_address2'], $order['od_crypt']);
|
||
$o['delivery_city'] = Sote_Decrypt($order['delivery_city'], $order['od_crypt']);
|
||
$o['delivery_postcode'] = Sote_Decrypt($order['delivery_postcode'], $order['od_crypt']);
|
||
$o['delivery_country'] = $order['delivery_country_pl'] ? $order['delivery_country_pl'] : $order['delivery_country'];
|
||
$o['delivery_country_code'] = $order['delivery_country_code'];
|
||
|
||
$o['invoice_fullname'] = $order['customers_name'];
|
||
$o['invoice_company'] = html_entity_decode($order['customers_company']);
|
||
$o['invoice_nip'] = $order['customers_nip'];
|
||
$o['invoice_address'] = Sote_Decrypt($order['customers_street_address'], $order['ob_crypt'])." ".Sote_Decrypt($order['customers_street_address2'], $order['ob_crypt']);
|
||
$o['invoice_city'] = Sote_Decrypt($order['customers_city'], $order['ob_crypt']);
|
||
$o['invoice_postcode'] = Sote_Decrypt($order['customers_postcode'], $order['ob_crypt']);
|
||
$o['invoice_country'] = $order['customers_country_pl'] ? $order['customers_country_pl'] : $order['customers_country'];
|
||
$o['invoice_country_code'] = $order['invoice_country_code'];
|
||
|
||
$billing_phone = Sote_Decrypt($order['customers_phone'], $order['ob_crypt']);
|
||
$delivery_phone = Sote_Decrypt($order['delivery_phone'], $order['ob_crypt']);
|
||
$o['phone'] = $delivery_phone ? $delivery_phone : $billing_phone;
|
||
$o['email'] = $order['opt_client_email'];
|
||
$o['date_add'] = $order['time_purchased'];
|
||
$o['payment_method'] = "";
|
||
$o['user_comments'] = $order['description'];
|
||
$o['delivery_method'] = $order['delivery_method'];
|
||
$o['delivery_method_id'] = $order['delivery_id'];
|
||
$o['status_id'] = $order['order_status_id'];
|
||
|
||
// most likely undecrypted order data
|
||
if (preg_match('/\w{40}/', $o['phone']))
|
||
{
|
||
return array('error' => true, 'error_code' => 'DECRYPT_ERROR', 'error_text' => 'Unable to decode order data: ' . $o['phone']);
|
||
}
|
||
|
||
if (preg_match('/\w{40}/', $o['delivery_address']))
|
||
{
|
||
return array('error' => true, 'error_code' => 'DECRYPT_ERROR', 'error_text' => 'Unable to decode order data: ' . $o['delivery_address']);
|
||
}
|
||
|
||
// dostawa do paczkomatu
|
||
if (preg_match('/^(Paczkomat)?(\s+|\s+-\s+)?((POP-)?([A-Z]{3}\d+[A-Z]*))\s*$/', $o['delivery_company'], $m))
|
||
{
|
||
$o['delivery_point_name'] = $m[3];
|
||
$o['delivery_point_id'] = $m[3];
|
||
|
||
foreach (array('address', 'city', 'country', 'postcode') as $fld)
|
||
{
|
||
$o["delivery_point_$fld"] = $o["delivery_$fld"];
|
||
$o["delivery_$fld"] = $o["invoice_$fld"];
|
||
}
|
||
|
||
foreach (array('company', 'fullname') as $fld)
|
||
{
|
||
$o["delivery_$fld"] = $o["invoice_$fld"];
|
||
}
|
||
}
|
||
elseif (isset($order['shipping_module']) and preg_match('/paczkomat/', $order['shipping_module']) and preg_match('/^([^,]+), (\d\d-\d{3}) (.+?), (.+?) \((\w+)\)/', $order['shipping_info'], $m))
|
||
{
|
||
$o['delivery_point_name'] = $m[5];
|
||
$o['delivery_point_address'] = "${m[4]}, ${m[1]}";
|
||
$o['delivery_point_city'] = $m[3];
|
||
$o['delivery_point_postcode'] = $m[2];
|
||
}
|
||
elseif (preg_match('/paczkomat/i', $order['delivery_method']) and isset($order['in_post_terminal']) and preg_match('/^([\w\-]+)\|.*?\|[\w\-]+ - (\d\d-\d{3}) ([\w\-]+) (.+)/u', $order['in_post_terminal'], $m))
|
||
{
|
||
$addr = explode(' ', $m[4]);
|
||
|
||
// dwu-członowa nazwa miejscowości?
|
||
if (count($addr) > 1 and strlen($add[0]) > 2 and preg_match('/^[A-ZĆŁÓŚŻŹ]/', $addr[0]))
|
||
{
|
||
$m[3] .= ' ' . array_splice($addr, 0, 1);
|
||
$m[4] = implode(' ', $addr);
|
||
}
|
||
|
||
$o['delivery_point_id'] = $m[1];
|
||
$o['delivery_point_name'] = $m[1];
|
||
$o['delivery_point_address'] = $m[4];
|
||
$o['delivery_point_city'] = $m[3];
|
||
$o['delivery_point_postcode'] = $m[2];
|
||
}
|
||
elseif ($sheepla_orders)
|
||
{
|
||
$sql = "SELECT adddata FROM `${dbp}sheepla_orders` WHERE order_id = {0}";
|
||
|
||
if ($so_data = DB_Result(DB_Query($sql, $order['id'])))
|
||
{
|
||
if ($so_data = @unserialize($so_data))
|
||
{
|
||
if ($so_data['sheepla-widget-plinpost-paczkomat'])
|
||
{
|
||
$o['delivery_point_name'] = $so_data['sheepla-widget-plinpost-paczkomat'];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//punkt odbioru PP
|
||
if (empty($o['delivery_point_name']) and $poczta_polska_punkt_odbioru)
|
||
{
|
||
if ($dp = DB_Fetch(DB_Query("SELECT * FROM `${dbp}st_poczta_polska_punkt_odbioru` WHERE order_id = '{0}'",
|
||
$order['id'])))
|
||
{
|
||
$o['delivery_point_id'] = $dp['pni'];
|
||
$o['delivery_point_name'] = $dp['name'];
|
||
$o['delivery_point_address'] = $dp['street'];
|
||
$o['delivery_point_city'] = $dp['city'];
|
||
$o['delivery_point_postcode'] = $dp['zip_code'];
|
||
$o['delivery_fullname'] = $o['delivery_fullname'] ? $o['delivery_fullname'] : $o['invoice_fullname'];
|
||
|
||
if ($dp['name'] == $o['delivery_company'])
|
||
{
|
||
$o['delivery_company'] = '';
|
||
}
|
||
}
|
||
}
|
||
|
||
// Paczka w RUCHu
|
||
if ($pwr_number and !$request['only_paid'] and !isset($o['delivery_point_name']) and !empty($order['pwr_number']))
|
||
{
|
||
$o['delivery_point_name'] = $order['pwr_number'];
|
||
|
||
if ($pwr = DB_Fetch(DB_Query("SELECT * FROM `${dbp}aa_pwr_points` WHERE destination_code = '{0}'", $order['pwr_number'])))
|
||
{
|
||
$o['delivery_point_city'] = $pwr['city'];
|
||
$o['delivery_point_address'] = $pwr['street_name'];
|
||
}
|
||
}
|
||
|
||
// Orlen Paczka
|
||
if (empty($o['delivery_point_id']) and preg_match('/orlen/i', $o['delivery_method']) and isset($o['delivery_company']) and preg_match('/Punkt nr: ([\S]+)\s*$/', $o['delivery_company'], $m))
|
||
{
|
||
$o['delivery_point_id'] = $o['delivery_point_name'] = $m[1];
|
||
$o['delivery_point_address'] = $o['delivery_address'];
|
||
$o['delivery_point_city'] = $o['delivery_city'];
|
||
$o['delivery_point_postcode'] = $o['delivery_postcode'];
|
||
$o['delivery_company'] = $o['invoice_company'];
|
||
$o['delivery_address'] = $o['invoice_address'];
|
||
}
|
||
|
||
// DHL
|
||
if (empty($o['delivery_point_id']) and preg_match('/dhl.+?pop/i', $o['delivery_method']) and $has_dhl and !empty($order['aa_dhl_service_point']))
|
||
{
|
||
$o['delivery_point_id'] = $o['delivery_point_name'] = $order['aa_dhl_service_point'];
|
||
}
|
||
|
||
// paczkomat z pola paczkomaty_number
|
||
if (empty($o['delivery_point_id']) and preg_match('/inpost|paczkom/i', $o['delivery_method']) and !empty($order['paczkomaty_number']))
|
||
{
|
||
$o['delivery_point_id'] = $o['delivery_point_name'] = $order['paczkomaty_number'];
|
||
}
|
||
|
||
// new versions of sote store delivery point ID here
|
||
if (empty($o['delivery_point_id']) and !empty($order['pickup_point']))
|
||
{
|
||
$o['delivery_point_id'] = $o['delivery_point_name'] = $order['pickup_point'];
|
||
|
||
foreach (array('address', 'city', 'country', 'postcode', 'fullname', 'company') as $fld)
|
||
{
|
||
$o["delivery_$fld"] = $o["invoice_$fld"];
|
||
}
|
||
}
|
||
|
||
// jeśli zamówienie jest w walucie innej niż PLN, trzeba przeliczyć koszt wysyłki
|
||
if ($order['currency'] != 'PLN' and $order['exchange'])
|
||
{
|
||
$order['delivery_cost'] /= $order['exchange'];
|
||
}
|
||
|
||
$o['delivery_price'] = number_format($order['delivery_cost'] + (($has_weekend_delivery and $order['is_weekend_delivery']) ? (float)$order['weekend_delivery_cost_brutto'] : 0), 2, ".", "");
|
||
|
||
if ($has_weekend_delivery and $order['is_weekend_delivery'])
|
||
{
|
||
$o['delivery_method'] .= ' dostawa w weekend';
|
||
}
|
||
|
||
// czy klient chce fakturę
|
||
if ($o['invoice_nip'])
|
||
{
|
||
$o['want_invoice'] = 1;
|
||
}
|
||
else
|
||
{
|
||
$sql = "SELECT count(*) FROM `${dbp}st_invoice` WHERE order_id = '{0}' AND is_request = 1";
|
||
$o['want_invoice'] = DB_Result(DB_Query($sql, $order['id']));
|
||
}
|
||
|
||
$deductions = array(); // bony, itp
|
||
$total_paid = 0; // zaksięgowana wpłata
|
||
|
||
// sposób platności
|
||
$sql = "SELECT pt.opt_name, p.payed_at, p.status, p.amount, gc.code
|
||
FROM `${dbp}st_order_has_payment` op
|
||
JOIN `${dbp}st_payment` p ON p.id = op.payment_id
|
||
LEFT JOIN `${dbp}st_payment_type` pt ON pt.id = p.payment_type_id
|
||
LEFT JOIN `${dbp}st_gift_card` gc ON gc.id = p.gift_card_id
|
||
WHERE op.order_id = '{0}'";
|
||
$result = DB_Query($sql, $order['id']);
|
||
|
||
while ($payment = DB_Fetch($result))
|
||
{
|
||
if ($payment['code']) // bon jako dodatkowa pozycja zamówienia
|
||
{
|
||
$deductions[] = array(
|
||
'id' => '-',
|
||
'name' => 'Bon zakupowy ' . $payment['code'],
|
||
'price' => -$payment['amount'],
|
||
'quantity' => 1,
|
||
);
|
||
}
|
||
else
|
||
{
|
||
$o['payment_method'] = $payment['opt_name'];
|
||
}
|
||
|
||
if ($payment['status'])
|
||
{
|
||
$total_paid += $payment['amount'];
|
||
}
|
||
}
|
||
|
||
$o['paid'] = ($total_paid >= $order['opt_total_amount']) ? 1 : ($order['opt_is_payed'] ? 1 : 0);
|
||
|
||
if (preg_match('/pobran|przy odb|obírk/i', $o['payment_method']) or preg_match('/dobírk/i', $o['delivery_method']))
|
||
{
|
||
$o['payment_method_cod'] = 1;
|
||
$o['paid'] = 0;
|
||
}
|
||
|
||
//produkty zamówienia
|
||
$o['products'] = array();
|
||
$total_products = 0;
|
||
$sql = "SELECT op.*, p.weight, p.code, ops.code scode, ops.name sname, ops.product_id sproduct_id,
|
||
p.opt_short_description, ops.price_brutto sprice_brutto"
|
||
. ($options['ean_fld'] ? ", p.${options['ean_fld']} ean" : '') . "
|
||
FROM `${dbp}st_order_product` op
|
||
LEFT JOIN `${dbp}st_order_product_has_set` ops ON ops.order_product_id = op.id
|
||
LEFT JOIN `${dbp}st_product` p ON p.id = if(op.is_set, ops.product_id, op.product_id)
|
||
WHERE op.order_id = '{0}' ";
|
||
|
||
if ($options['ean_fld'])
|
||
{
|
||
$sql = preg_replace('/^SELECT/is', '$0 p.'.$options['ean_fld'].' ean,', $sql);
|
||
}
|
||
|
||
$max_tax_rate = 0;
|
||
$result = DB_Query($sql, $order['id']);
|
||
|
||
while ($product = DB_Fetch($result))
|
||
{
|
||
$set_pref = $product['is_set'] ? 's' : '';
|
||
|
||
if ($set_pref)
|
||
{
|
||
$std_set_price = DB_Result(DB_Query("SELECT SUM(price_brutto) FROM `${dbp}st_order_product_has_set` WHERE order_product_id = '{0}'", $product['id']));
|
||
$product['sprice_brutto'] *= $product['price_brutto']/$std_set_price;
|
||
}
|
||
|
||
$op = array(
|
||
'id' => $product[$set_pref.'product_id'],
|
||
'name' => $product[$set_pref.'name'],
|
||
'quantity' => $product['quantity'],
|
||
'price' => $product[$set_pref.'price_brutto'],
|
||
'tax' => $product['vat'],
|
||
'weight' => $product['weight'],
|
||
'sku' => $product[$set_pref.'code'],
|
||
'ean' => $product['ean'],
|
||
);
|
||
|
||
if ($op['tax'] > $max_tax_rate)
|
||
{
|
||
$max_tax_rate = $op['tax'];
|
||
}
|
||
|
||
if ($product['is_set'])
|
||
{
|
||
if (isset($product['discount']) and $disc = @unserialize($product['discount']))
|
||
{
|
||
if (isset($disc[0]['type']) and $disc[0]['type'] == '%')
|
||
{
|
||
$op['price'] = number_format($op['price']*(100-$disc[0]['value'])/100, 2, '.', '');
|
||
}
|
||
}
|
||
|
||
// ten sam produkt pojawia się w zestawie wielokrotnie
|
||
if (!$request['only_paid'] and DB_Result(DB_Query("SELECT count(*) FROM `${dbp}st_order_product_has_set` WHERE order_product_id = '{0}'", $product['id'])) == 1)
|
||
{
|
||
$price_ratio = $product['price_brutto']/$product['sprice_brutto'];
|
||
|
||
if ($price_ratio == (int)$price_ratio)
|
||
{
|
||
$op['quantity'] *= $price_ratio;
|
||
}
|
||
}
|
||
|
||
$total_products += $op['price']*$op['quantity'];
|
||
$o['products'][] = $op;
|
||
continue;
|
||
}
|
||
|
||
if ($product['price_modifiers'] != '')
|
||
{
|
||
$opts = unserialize($product['price_modifiers']);
|
||
$depth = 0;
|
||
|
||
foreach ($opts as $opt)
|
||
{
|
||
// modyfikacja ceny
|
||
if (!empty($opt['value']))
|
||
{
|
||
if ($opt['prefix'] == '-')
|
||
{
|
||
if (isset($opt['value']['brutto']))
|
||
{
|
||
$opt['value']['brutto'] = -$opt['value']['brutto'];
|
||
}
|
||
else
|
||
{
|
||
$opt['value'] = -$opt['value'];
|
||
}
|
||
}
|
||
|
||
if ($opt['type'] == 'percent')
|
||
{
|
||
//$op['price'] = $opt['price'] + $opt['value']*$opt['price']/100;
|
||
//$op['price'] = $opt['value']*$op['price']/100;
|
||
}
|
||
else
|
||
{
|
||
if (is_array($opt['value']))
|
||
{
|
||
if ($opt['value']['brutto'])
|
||
{
|
||
// $op['price'] = $opt['value']['brutto'] / (($o['currency'] != 'PLN' AND $order['exchange']) ? $order['exchange'] : 1);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// $op['price'] += $opt['value'];
|
||
}
|
||
}
|
||
}
|
||
|
||
// id odstatniego poziomu zagłębienia identyfikuje wariant
|
||
if ($opt['level'] > $depth and !empty($opt['custom']) and $opt['custom']['type'] == 'product_options')
|
||
{
|
||
$op['variant_id'] = $opt['custom']['id'];
|
||
$depth = $opt['level'];
|
||
|
||
// jeszcze tylko SKU (+EAN) wariantu ...
|
||
$sql = "SELECT use_product sku"
|
||
. ($options['vean_fld'] ? ", ${options['vean_fld']} ean" : '') . "
|
||
FROM `${dbp}st_product_options_value` WHERE id = '{0}' LIMIT 1";
|
||
|
||
if ($v = DB_Fetch(DB_Query($sql, $op['variant_id'])))
|
||
{
|
||
$op['sku'] = $v['sku'] ? $v['sku'] : $op['sku'];
|
||
$op['ean'] = $v['ean'] ? $v['ean'] : $op['ean'];
|
||
}
|
||
}
|
||
|
||
$op['name'] .= ' ' . $opt['label'];
|
||
}
|
||
|
||
$op['price'] = number_format($op['price'],2,".","");
|
||
}
|
||
|
||
if($product['discount'] != "")
|
||
{
|
||
$discounts = unserialize($product['discount']);
|
||
foreach($discounts as $d)
|
||
{
|
||
if($d['type'] == "%")
|
||
{$op['price'] *= 1-($d['value']/100);}
|
||
else
|
||
{$op['price'] -= $d['value'];}
|
||
|
||
$op['price'] = number_format($op['price'],2,".","");
|
||
}
|
||
}
|
||
|
||
$total_products += $op['price']*$op['quantity'];
|
||
$o['products'][] = $op;
|
||
}
|
||
|
||
$order_total = $o['delivery_price'];
|
||
|
||
foreach ($o['products'] as $op)
|
||
{
|
||
$order_total += $op['quantity']*$op['price'];
|
||
}
|
||
|
||
// rabat od całości zamówienia
|
||
if ($order['discount_id'] and $order['order_discount'])
|
||
{
|
||
if ($discount = @unserialize($order['order_discount']))
|
||
{
|
||
if ($discount['value'])
|
||
{
|
||
$op = array('name' => 'Rabat', 'quantity' => 1, 'id' => '', 'tax' => $max_tax_rate);
|
||
|
||
// ustalenie nazwy rabatu
|
||
$sql = "SELECT name FROM `${dbp}st_discount` WHERE id = '{0}'";
|
||
|
||
if ($dname = DB_Result(DB_Query($sql, $order['discount_id'])))
|
||
{
|
||
$op['name'] = preg_match('/rabat/i', $dname) ? $dname : "Rabat $dname";
|
||
}
|
||
|
||
if ($discount['type'] == '%') // rabat procentowy
|
||
{
|
||
$op['price'] = number_format(-$discount['value']*$total_products/100, 2, '.', '');
|
||
}
|
||
else // rabat kwotowy
|
||
{
|
||
$op['price'] = -$discount['value'];
|
||
}
|
||
|
||
$o['products'][] = $op;
|
||
}
|
||
}
|
||
}
|
||
elseif (count($deductions))
|
||
{
|
||
$o['products'] = array_merge($o['products'], $deductions);
|
||
}
|
||
elseif ($order['opt_total_amount'] - $order_total <= -0.01)
|
||
{
|
||
$o['products'][] = array('name' => 'Rabat', 'quantity' => 1, 'id' => '', 'tax' => $max_tax_rate, 'price' => number_format($order['opt_total_amount']-$order_total, 2, '.', ''));
|
||
}
|
||
|
||
$response[$options['use_order_numbers'] ? $order['number'] : $order['id']] = $o;
|
||
}
|
||
|
||
|
||
return $response;
|
||
}
|
||
|
||
/**
|
||
* Funkcja aktualizuje zamówienia wcześniej dodane do bazy
|
||
* W przypadku zapisywania numeru nadawaczego, parametr orders_ids będzie przyjmował zawsze tablicę z jedną pozycją
|
||
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
|
||
* @param array $request tablica z żadaniem od systemu, zawiera informacje o aktualizacji zamówienia w formacie:
|
||
* orders_ids => ID zamówień
|
||
* update_type => typ zmiany - 'status', `delivery_number`, lub 'paid' (aktualizacja statusu zamówienia, dodanie numeru nadawczego i dodanie/usunięcie wpłaty)
|
||
* update_value => aktualizowana wartość - ID statusu, numer nadawczy lub informacja o opłaceniu zamówienia (bool true/false)
|
||
* @return array $response tablica zawierająca potwierdzenie zmiany:
|
||
* 'counter' => ilość zamówień w których dokonano zmiany (nawet jeśli zamówienie pozostało takie jak wcześniej)
|
||
*/
|
||
function Shop_OrderUpdate($request)
|
||
{
|
||
global $options; // globalna tablica z ustawieniami
|
||
$dbp = $options['db_prefix']; // Data Base Prefix - prefix tabel bazy
|
||
|
||
$counter = 0;
|
||
|
||
// dla wszystkich nadesłanych numerów zamówień
|
||
foreach ($request['orders_ids'] as $order_id)
|
||
{
|
||
if ($options['use_order_numbers'])
|
||
{
|
||
if (!($order_id = DB_Result(DB_Query("SELECT id FROM `${dbp}st_order` WHERE number = '{0}' ORDER BY id DESC", $order_id))))
|
||
{
|
||
continue; // nie udało się dopasować zamówienia po numerze
|
||
}
|
||
}
|
||
|
||
// zmiana statusu
|
||
if ($request['update_type'] == 'status')
|
||
{
|
||
DB_Query("UPDATE `${dbp}st_order` SET order_status_id = '{0}', updated_at = '{1}' WHERE id = '{2}'",
|
||
$request['update_value'], date('Y-m-d H:i:s'), $order_id);
|
||
}
|
||
|
||
// zapisanie numeru nadawczego
|
||
elseif ($request['update_type'] == 'delivery_number')
|
||
{
|
||
DB_Query("UPDATE `${dbp}st_order_delivery` SET number = '{0}'
|
||
WHERE id = (SELECT order_delivery_id FROM `${dbp}st_order` WHERE id = '{1}')
|
||
LIMIT 1", $request['update_value'], $order_id);
|
||
}
|
||
|
||
// zmiana statusu wpłaty
|
||
elseif ($request['update_type'] == 'paid')
|
||
{
|
||
DB_Query("UPDATE `${dbp}st_payment` SET updated_at = '{0}', status = '{2}',
|
||
payed_at = " . ($request['update_value'] ? '"{0}"' : 'NULL') .
|
||
" WHERE id = (SELECT payment_id FROM `${dbp}st_order_has_payment`
|
||
WHERE order_id = '{1}' ORDER BY created_at DESC LIMIT 1) LIMIT 1",
|
||
date('Y-m-d H:i:s'), $order_id, $request['update_value'] ? 1 : 0);
|
||
DB_Query("UPDATE `${dbp}st_order` SET opt_is_payed = '{0}' WHERE id = '{1}'",
|
||
$request['update_value'] ? 1 : 0, $order_id);
|
||
}
|
||
|
||
$counter++;
|
||
}
|
||
|
||
return array('counter' => $counter);
|
||
}
|
||
|
||
|
||
/**
|
||
* Funkcja zwraca listę dostępnych statusów zamówień
|
||
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
|
||
* @param array $request tablica z żadaniem od systemu, w przypadku tej funkcji nie używana
|
||
* @return array $response tablica zawierająca dostępne statusy zamówień:
|
||
* 'status_id' => nazwa statusu
|
||
*/
|
||
function Shop_StatusesList($request)
|
||
{
|
||
global $options; // globalna tablica z ustawieniami
|
||
$dbp = $options['db_prefix']; // Data Base Prefix - prefix tabel bazy
|
||
|
||
$response = array();
|
||
$sql = "SELECT id, opt_name FROM `${dbp}st_order_status`
|
||
ORDER BY is_default DESC";
|
||
$res = DB_Query($sql);
|
||
|
||
while ($status = DB_Fetch($res))
|
||
{
|
||
$response[$status['id']] = $status['opt_name'];
|
||
}
|
||
|
||
return $response;
|
||
}
|
||
|
||
|
||
/**
|
||
* Funkcja zwraca listę dostępnych sposobów wysyłki
|
||
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
|
||
* @param array $request tablica z żadaniem od systemu, w przypadku tej funkcji nie używana
|
||
* @return array $response tablica zawierająca dostępne sposoby_wysyłki:
|
||
* 'delivery_id' => nazwa wysyłki
|
||
*/
|
||
function Shop_DeliveryMethodsList($request)
|
||
{
|
||
global $options; //globalna tablica z ustawieniami
|
||
$dbp = $options['db_prefix']; //Data Base Prefix - prefix tabel bazy
|
||
|
||
$response = array();
|
||
|
||
$sql = "SELECT id, opt_name
|
||
FROM `${dbp}st_delivery`
|
||
WHERE active ORDER BY is_default DESC";
|
||
$res = DB_Query($sql);
|
||
|
||
while ($method = DB_Fetch($res))
|
||
{
|
||
$response[$method['id']] = $method['opt_name'];
|
||
}
|
||
|
||
return $response;
|
||
}
|
||
|
||
/**
|
||
* Funkcja zwraca listę dostępnych metod płatności
|
||
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
|
||
* @param array $request tablica z żadaniem od systemu, w przypadku tej funkcji nie używana
|
||
* @return array $response tablica zawierająca dostępne metody płatności
|
||
* 'payment_id' => nazwa płatności
|
||
*/
|
||
function Shop_PaymentMethodsList($request)
|
||
{
|
||
global $options; //globalna tablica z ustawieniami
|
||
$dbp = $options['db_prefix']; //Data Base Prefix - prefix tabel bazy
|
||
|
||
$response = array();
|
||
|
||
$sql = "SELECT id, opt_name
|
||
FROM `${dbp}st_payment_type`
|
||
WHERE active ORDER BY opt_name";
|
||
$res = DB_Query($sql);
|
||
|
||
while ($method = DB_Fetch($res))
|
||
{
|
||
$response[$method['id']] = $method['opt_name'];
|
||
}
|
||
|
||
return $response;
|
||
}
|
||
|
||
function Sote_Decrypt($text = '', $decrypt = true)
|
||
{
|
||
global $options;
|
||
static $key;
|
||
|
||
if ($decrypt == '2' and preg_match('/^def/', $text) and (isset($key) or file_exists($options['sote_dir'] . '/data/encrypt.key.php')))
|
||
{
|
||
$key = include $options['sote_dir'] . '/data/encrypt.key.php';
|
||
|
||
try {
|
||
return \Defuse\Crypto\Crypto::decrypt((string)$text, $key);
|
||
}
|
||
catch (Exception $ex)
|
||
{
|
||
return $text;
|
||
}
|
||
}
|
||
|
||
if($decrypt != "1"){return $text;}
|
||
|
||
$key = $options['sote_shophash'];
|
||
$string = $text;
|
||
$string = base64_decode($string);
|
||
$td = mcrypt_module_open('des', '','cfb', '');
|
||
$key = substr($key, 0, mcrypt_enc_get_key_size($td));
|
||
$iv_size = mcrypt_enc_get_iv_size($td);
|
||
$iv = substr($string,0,$iv_size);
|
||
$string = substr($string,$iv_size);
|
||
|
||
if (strlen($iv) == 0) { return $text; }
|
||
|
||
if (mcrypt_generic_init($td, $key, $iv) != -1) {
|
||
$c_t = @mdecrypt_generic($td, $string);
|
||
mcrypt_generic_deinit($td);
|
||
mcrypt_module_close($td);
|
||
return $c_t;
|
||
}
|
||
}
|
||
|
||
function Sote_Encrypt($text, $mode = 1)
|
||
{
|
||
global $options;
|
||
static $key;
|
||
|
||
if ($mode == 2)
|
||
{
|
||
if (file_exists($options['sote_dir'] . '/data/encrypt.key.php'))
|
||
{
|
||
$key = include $options['sote_dir'] . '/data/encrypt.key.php';
|
||
}
|
||
|
||
if (!isset($key))
|
||
{
|
||
Conn_Error('CRYPTO_FAILIURE', 'Nie można pobrać klucza szyfrowania');
|
||
}
|
||
|
||
try {
|
||
return \Defuse\Crypto\Crypto::encrypt((string)$text, $key);
|
||
}
|
||
catch (Exception $ex)
|
||
{
|
||
Conn_Error('CRYPTO_FAILIURE', 'Błąd szyfrowania');
|
||
}
|
||
}
|
||
|
||
|
||
if ($key = $options['sote_shophash'])
|
||
{
|
||
$td = mcrypt_module_open('des', '','cfb', '');
|
||
$key = substr($key, 0, mcrypt_enc_get_key_size($td));
|
||
$iv_size = mcrypt_enc_get_iv_size($td);
|
||
$iv = substr(base64_encode(md5(microtime(true))), 0, $iv_size);
|
||
|
||
if (@mcrypt_generic_init($td, $key, $iv) != -1)
|
||
{
|
||
$enc = @mcrypt_generic($td, $text);
|
||
mcrypt_generic_deinit($td);
|
||
mcrypt_module_close($td);
|
||
return base64_encode($iv.$enc);
|
||
}
|
||
}
|
||
|
||
return $text;
|
||
}
|
||
?>
|