* @version 4 * @package baselinker */ /** ----------------------------------------------------------------------------------------------------------- * Ustawienia wpisywane przez sprzedawcę * - Należy uzupełnić dane wprowadzając je między apostrofy */ $options['baselinker_pass'] = 'rcszksgwexd171b6x4mz5m77n2psqpo3'; //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['sote_shophash'] = 'f9862393534ee289a67584de0b0768a0'; // klucz rozkodowywania danych zamówienia (zawarty w pliku core/data/config/__stRegister.yml) 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 $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;} /** * 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(stripslashes($_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.8"; //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_attribute_field'; $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")); } } /** * 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 * FROM `${dbp}st_category` c WHERE is_active = 1 AND is_hidden = 0"; $res = DB_Query($sql); while ($category = DB_Fetch($res)) { $categories[$category['id']] = $category['opt_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 ($parents[$this_id] != 0) { $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'; $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 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 ($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); while ($prod = DB_Fetch($result)) { $response[$prod['id']] = array('name' => $prod['name'], 'quantity' => (int)$prod['stock'], 'price' => $prod['price'], 'sku' => $prod['code']); } 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(); // 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_vat tax, p.weight, p.opt_price_brutto price, pi.name, pi.description, pi.short_description description_extra1 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})"; $res = DB_Query($sql, implode(', ', $request['products_id']), $options['lang']); while ($p = DB_Fetch($res)) { $product_id = $p['id']; // 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, pov.price, pov.stock, depth, product_options_field_id field_id, pov.use_product sku FROM `${dbp}st_product_options_value` pov LEFT JOIN `${dbp}st_product_options_value_i18n` povi ON povi.id = pov.id AND culture = '${options['lang']}' 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('name' => '', 'price' => $p['price'])); $depth = 0; $field_id = 0; while ($opt = DB_Fetch($res2)) { 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'], ); 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, '.', ''); } $multiopt2[] = $v; $field_id = $opt['field_id']; } $p['variants'] = array(); foreach ($multiopt2 as $v) { if (!$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'], ); } // 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"; $res2 = DB_Query($sql, $product_id); $images = array(); 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($features[$f['name']]) ? ($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]); } //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 (!(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 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'] != "") { $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']); } // 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'; } // 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, 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'; // 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) VALUES ( '{0}', '{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}' , '{10}', '{11}')"; DB_Query($sql, date('Y-m-d H:i:s'), $request['invoice_country'], $request['invoice_fullname'], $request['invoice_company'], $request['invoice_address'], $request['invoice_postcode'], $request['invoice_city'], $invoice_street, $invoice_house, $request['phone'] , $request['invoice_nip'], $invoice_country_id); $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) VALUES ( '{0}', '{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}')"; DB_Query($sql, date('Y-m-d H:i:s'), $request['delivery_country'], $request['delivery_fullname'], $request['delivery_company'], $request['delivery_address'], $request['delivery_postcode'], $request['delivery_city'], $delivery_street, $delivery_house, $request['phone'], $delivery_country_id); $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) VALUES ('{0}', '{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}')"; 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']); $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) VALUES (0, '{0}', '{0}', {10}, 0, {1}, '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}')"; DB_Query($sql, date('Y-m-d H:i:s'), $user_id, $invoice_country_id, $invoice_street, $invoice_house, $request['invoice_postcode'], $request['invoice_city'], $request['phone'], $request['invoice_fullname'], $request['invoice_address'], 1); DB_Query($sql, date('Y-m-d H:i:s'), $user_id, $delivery_country_id, $delivery_street, $delivery_house, $request['delivery_postcode'], $request['delivery_city'], $request['phone'], $request['delivery_fullname'], $request['delivery_address'], 0); // 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']; // pobieranie numeru ostatniego zamowienia if ($request['previous_order_id'] != '') { $last_nr = $request['previous_order_id']; } else { $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(); // typ płatności $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); // 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(); $sql = "INSERT INTO `${dbp}st_order_has_payment` (created_at, updated_at, order_id, payment_id) VALUES ('{0}', '{0}', '{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); $price_netto = $prod['price'] / (1+$prod_data['opt_vat']/100); $price_modifiers = array(); // obsługa wariantu if ($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'])))); } } 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(); //dodatkowe dane dostawy w oddzielnej tabeli? $sheepla_orders = DB_NumRows(DB_Query("SHOW TABLES LIKE '${dbp}sheepla_orders'")); //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 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 = od.countries_id LEFT JOIN `${dbp}st_countries` obd ON obd.id = ob.countries_id WHERE o.created_at >= '{0}' AND o.id >= {1}"; $res = DB_Query($sql, $time_from, $id_from); while ($order = DB_Fetch($res)) { $o = array('currency' => $order['currency']); $o['delivery_fullname'] = $order['delivery_name']; $o['delivery_company'] = $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'] = $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']; $o['phone'] = ($order['customers_telephone']!="")?Sote_Decrypt($order['customers_phone'], $order['ob_crypt']):Sote_Decrypt($order['delivery_phone'], $order['ob_crypt']); $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']; // dostawa do paczkomatu if (preg_match('/^Paczkomat - (\w+)\s*$/', $o['delivery_company'], $m)) { $o['delivery_point_name'] = $m[1]; foreach (array('address', 'city', 'country', 'postcode') as $fld) { $o["delivery_point_$fld"] = $o["delivery_$fld"]; } } 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']; } } } } // 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'], 2, ".", ""); // czy klient chce fakturę if ($o['invoice_nip']) { $o['want_invoice'] = 1; } // sposób platności $sql = "SELECT pt.opt_name, p.payed_at FROM `${dbp}st_order_has_payment` op JOIN `${dbp}st_payment` p ON p.id = op.payment_id JOIN `${dbp}st_payment_type` pt ON pt.id = p.payment_type_id WHERE op.order_id = '{0}' LIMIT 1"; $result = DB_Query($sql, $order['id']); if ($payment = DB_Fetch($result)) { $o['payment_method'] = $payment['opt_name']; $o['paid'] = $payment['payed_at'] ? 1 : 0; if (preg_match('/pobran|przy odb/i', $o['payment_method'])) { $o['payment_method_cod'] = 1; } } //produkty zamówienia $o['products'] = array(); $total_products = 0; $sql = "SELECT op.*, p.weight, p.code FROM `${dbp}st_order_product` op LEFT JOIN `${dbp}st_product` p ON p.id = op.product_id WHERE op.order_id = '{0}' "; $result = DB_Query($sql, $order['id']); while ($product = DB_Fetch($result)) { $op = array( 'id' => $product['product_id'], 'name' => $product['name'], 'quantity' => $product['quantity'], 'price' => $product['price_brutto'], 'tax' => $product['vat'], 'weight' => $product['weight'], 'sku' => $product['code'], ); if ($product['price_modifiers'] != '') { $opts = unserialize($product['price_modifiers']); $depth = 0; foreach ($opts as $opt) { // modyfikacja ceny if (!empty($opt['value'])) { if ($opt['prefix'] == '-') { $opt['value'] = -$opt['value']; } if ($opt['type'] == 'percent') { $op['price'] = $opt['price'] + $opt['value']*$opt['price']/100; } else { if (is_array($opt['value'])) { if ($opt['value']['brutto']) { $op['price'] = $opt['value']['brutto']; } } 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']; } $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; } // 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' => 0); // 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; } } } $response[$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) { // 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; } function Sote_Decrypt($text, $decrypt = true) { global $options; 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 (mcrypt_generic_init($td, $key, $iv) != -1) { $c_t = @mdecrypt_generic($td, $string); mcrypt_generic_deinit($td); mcrypt_module_close($td); return $c_t; } } ?>