* Copyright (C) 2019 Cedric Ancelin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ use Luracast\Restler\RestException; use Sabre\Xml\Element; require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT . '/product/stock/class/productlot.class.php'; require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.product.class.php'; require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductAttribute.class.php'; require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductAttributeValue.class.php'; require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductCombination.class.php'; require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductCombination2ValuePair.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/sellproduct.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/apiuserhandler.class.php'; require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/jegy.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/bbloginlog.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/bbexchangerate.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/bbticket.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/bbdevices.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/bbdevicesservicelocation.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/bbdevicesservicelocationproduct.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/bbticketinvoiceprinting.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/utils/globalconst.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/utils/emailtemplatehandler.php'; include_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/bbticketnaplo.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/bbtickethandler.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/gpsposition.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/userloginnaplo.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/utils/countryhandler.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/utils/entityhandler.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/discountnaplo.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/settlements/class/groupusers.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/rollerstorage/class/packagehistory.class.php'; require_once DOL_DOCUMENT_ROOT . '/product/inventory/class/inventory.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/apiproductlisthelper.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/apiinvoicehelper.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/ticket_checker.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/api_bbus_helper.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/api_bbus_log.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/bbapilock.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/exchangerateupdater.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/bbticketvalidationcoords.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/api_curl.class.php'; require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/roller_handling.class.php'; /** * API class for products * * @access protected * @class DolibarrApiAccess {@requires user,external} */ class BBus extends DolibarrApi { use CurlApi; use RollerHandling; private $code; private $printingTime; private $status = 0; private $device_id; private $service_location_id; private $bbTicketRowId; private $facture_id; private $isValid = true; private User $user; const EMAIL_TEMPLATE = 'multiticketprinting'; const GLOBAL_CONF_SEND_TO_EMAIL = 'BBUS_INVOICE_PRINTING_ALERT_EMAIL'; const GLOBAL_CONF_EMAIL_FROM = 'BBUS_INVOICE_PRINTING_ALERT_EMAIL_FROM'; public function __construct() { global $db, $conf, $user; $this->db = $db; $this->user = $user; } /** * First ticket validation * * @param string $code * * @return array|mixed Data without useless information * * @url POST search */ public function search($code) { $this->checkUserReadPermission(); global $user; $this->code = $code; $this->facture_id = $this->getFactureRowIdByFactureId(); $sql = "SELECT bt.*, pr.ref as product_ref, pr.label as product_label, btp.printing_date, btp.printing_date_timestamp FROM llx_bbus_bbticketinvoiceprinting as btp INNER JOIN llx_bbus_bbticket AS bt ON bt.rowid = btp.ticket_id INNER JOIN llx_product AS pr ON pr.rowid = bt.ticket_id WHERE btp.fk_facture = {$this->facture_id} AND btp.printing_date = ( SELECT MIN(printing_date) FROM llx_bbus_bbticketinvoiceprinting AS btp2 WHERE btp2.fk_facture = {$this->facture_id} )"; $ticketsData = $this->db->query($sql); while ($row = pg_fetch_assoc($ticketsData)) { $now = date("Y-m-d H:i:s"); if ($row['usage'] == $row['usable_occasions'] && $row['usable_occasions'] != 0) { $this->isValid = false; } if ($row['available_at'] < $now || ((!is_null($row['expire_at']) && !empty($row['expire_at'])) && $row['expire_at'] < $now)) { $this->isValid = false; } $row['facture_ref'] = $code; $row['isValid'] = $this->isValid; $sub = []; foreach ($row as $key => $value) { $sub[$key] = $value; } $json[] = $sub; } return $json; } /** * Értékesítések * * @param date $date Date * * * @return array|mixed Data without useless information * * @url POST getsaleditems */ public function getsaleditems($date = null) { global $user; if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(403); } //$date = isset($date) ? $date : date("Y-m-d"); $date = date("Y-m-d"); $apiBbusHelper = new ApiBBusHelper(); $facturesArray = $apiBbusHelper->getSaledItems($date); return $apiBbusHelper->getSaledItemsArray($facturesArray); } /** LOG OK * Get properties of a product object by barcode * * Return an array with product information. * * @param string $code Facture ID and timestamp of printing * * @return array|mixed Data without useless information * * @url POST ticketinfos */ public function getinfos($code) { global $user; $ticketChecker = new TicketChecker(); ApiBbusLog::getinfosLog('=== NEW TICKETINFOS ==='); ApiBbusLog::getinfosLog("User: {$user->firstname} {$user->lastname} (ID: {$user->id})"); ApiBbusLog::getinfosLog("DOLAPIKEY: {$user->api_key}"); $ticketsFromBbticketinvoiceprinting = []; $code_and_timstamp = explode('_', $code); $this->code = $code_and_timstamp[0]; if (empty($this->code)) { ApiBbusLog::getinfosLog('Code or mac is empty!'); ApiBbusLog::getinfosLog('================='); throw new RestException(404, 'Code or mac is empty!'); } $this->printingTime = $code_and_timstamp[1]; if (empty($this->printingTime)) { ApiBbusLog::getinfosLog('Timestamp is empty!'); ApiBbusLog::getinfosLog('================='); throw new RestException(404, 'Timestamp is empty!'); } if (!DolibarrApiAccess::$user->rights->bbus->ticket->validation) { ApiBbusLog::getinfosLog('No access: Ticket Validation!'); ApiBbusLog::getinfosLog('================='); throw new RestException(403); } ApiBbusLog::getinfosLog("Code: {$this->code}"); ApiBbusLog::getinfosLog("Code: {$this->printingTime}"); //Kikeresem a facture_id-t $facture = new Facture($this->db); $sql = "SELECT * FROM " . $this->db->prefix() . $facture->table_element . " WHERE ref ILIKE '{$this->code}'"; $factureResult = $this->db->query($sql); if (pg_num_rows($factureResult) < 1) { ApiBbusLog::getinfosLog('Invoice not found!'); ApiBbusLog::getinfosLog('================='); throw new RestException(404, 'Invoice not found!'); } while ($row = pg_fetch_assoc($factureResult)) { $selectedFacture_id = $row['rowid']; } ApiBbusLog::getinfosLog('Facture ID: ' . (string) $selectedFacture_id); $sql = "SELECT rowid FROM " . $this->db->prefix() . $facture->table_element . " WHERE fk_facture_source = {$selectedFacture_id} AND type = 2"; $res = $this->db->query($sql); if (pg_num_rows($res) > 0) { ApiBbusLog::getinfosLog('Invoice has a Credit account!'); ApiBbusLog::getinfosLog('================='); throw new RestException(404, 'Invoice has a Credit account.'); } // Kikeresem az llx_bbus_bbticketinvoiceprinting táblából a timestamp-hez tartozo jegy Id(ka)t $bbticketinvoiceprinting = new BbTicketInvoicePrinting($this->db); $result = $bbticketinvoiceprinting->fetchAll('', '', 0, 0, ['customsql' => "printing_date_timestamp = '{$this->printingTime}' AND fk_facture = {$selectedFacture_id}"]); $this->checkResult($result, 'bbticketinvoiceprinting'); foreach ($result as $device) { $ticketsFromBbticketinvoiceprinting[] = $device->ticket_id; } $inString = implode(', ', $ticketsFromBbticketinvoiceprinting); //echo $inString;exit; // A ticket_id alapjan, hogy a jegyek kozott szerepel-e es ervenyes-e $bbticket = new BbTicket($this->db); $sql = "SELECT tic.rowid as ticketrowid, tic.*, bbd.*, fac.* FROM " . $this->db->prefix() . $bbticket->table_element . " AS tic INNER JOIN public.llx_product as bbd ON tic.ticket_id = bbd.rowid INNER JOIN public.llx_facture as fac ON tic.fk_facture = fac.rowid WHERE tic.rowid IN ({$inString})"; $statement = $this->db->query($sql); while ($row = pg_fetch_assoc($statement)) { $sub = []; foreach ($row as $key => $value) { $sub[$key] = $value; //print $key . ' - ' . $value . "\r\n"; } $sub['ticket_type'] = $ticketChecker->getTicketTypeByProductId($row['ticket_id']); $json[] = $sub; } ApiBbusLog::getinfosLog(json_encode($json)); ApiBbusLog::getinfosLog('Status: OK!'); ApiBbusLog::getinfosLog('====================='); return $json; } /** * Get properties of a product object by barcode * * Return an array with product information. * * * @return array|mixed Data without useless information * * @url GET product */ public function getProducts() { global $user; $productsArray = []; $products = new Product($this->db); $sql = "SELECT price, default_vat_code, rowid FROM " . $this->db->prefix() . $products->table_element . " WHERE fk_product_type = 1 ORDER BY rowid ASC"; $res = $this->db->query($sql); while ($row = pg_fetch_assoc($res)) { $productsArray[$row['rowid']] = $row; } return 'OK'; } /** LOG OK * Validate a product bbticket id. * * Return an array with product validation data. * * @param string $code Facture ID and timestamp of printing * @param string $ticketid Ticketid (bbticket rowid) * @param string $imei IMEI (Mobile IMEI number) * * @return array|mixed Data without useless information * * @url POST ticketvalidationbyphone */ public function validateTicket($code, $ticketid, $imei) { global $user; $logId = ApiBbusLog::getLogId(); ApiBbusLog::ticketvalidationByPhone("{$logId} === NEW TICKETVALIDATION BY PHONE ==="); ApiBbusLog::ticketvalidationByPhone("{$logId} User: {$user->firstname} {$user->lastname} (ID: {$user->id})"); ApiBbusLog::ticketvalidationByPhone("{$logId} DOLAPIKEY: {$user->api_key}"); ApiBbusLog::ticketvalidationByPhone("{$logId} code: {$code}"); $ticketChecker = new TicketChecker(); $ticketChecker->setCode($code); $ticketChecker->setTimestamp($code, 'ticketvalidationByPhone', $logId); $ticketChecker->SetTicketidFromPhone($ticketid, $logId); $ticketChecker->setImei($imei, $logId); $this->checkUserValidatePermission(); $ticketChecker->setFactureId('ticketvalidationByPhone', $logId); $ticketChecker->checkBbTicketInvoicePrinting(); $selectedTicket = $ticketChecker->getDataOfTheSelectedTicket(); $ticketChecker->setBbTicketRowId($selectedTicket->id); $ticketChecker->checkExceptionHandlers($selectedTicket, 'ticketvalidationByPhone', $logId); $ticketChecker->setMergedTickets($selectedTicket, 'ticketvalidationByPhone', $logId); $ticketChecker->saveData($selectedTicket); ApiBbusLog::ticketvalidationByPhone("{$logId} Status: OK!"); ApiBbusLog::ticketvalidationByPhone("{$logId} ================="); return 'OK'; } /** LOG OK * Get properties of a product object by barcode * * Return an array with product information. * * @param string $code Facture ID and timestamp of printing * @param string $mac MAC adress of the device * * @return array|mixed Data without useless information * * @url POST barcode * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function getByBarcode(string $code, string $mac, string $lat = null, string $lon = null) { global $user; $logId = ApiBbusLog::getLogId(); ApiBbusLog::getByBarcode("{$logId} === NEW OBU validation ==="); ApiBbusLog::getByBarcode("{$logId} User: {$user->firstname} {$user->lastname} (ID: {$user->id})"); ApiBbusLog::getByBarcode("{$logId} DOLAPIKEY: {$user->api_key}"); $bbticket = new BbTicket($this->db); $ticketChecker = new TicketChecker(); if (empty($code) || empty($mac)) { ApiBbusLog::getByBarcode("{$logId} Code or mac is empty!"); throw new RestException(404, 'Code or mac is empty!'); } ApiBbusLog::getByBarcode("{$logId} Code: " . $code); ApiBbusLog::getByBarcode("{$logId} MAC: " . $mac); ApiBbusLog::getByBarcode("{$logId} Latitude: " . $lat); ApiBbusLog::getByBarcode("{$logId} Longitude: " . $lon); $ticketChecker->setMac($mac); $ticketChecker->setCode($code); $ticketChecker->setLat($lat); $ticketChecker->setLon($lon); $ticketChecker->setTimestamp($code, 'getByBarcode', $logId); $this->checkUserReadPermission(); $ticketChecker->setFactureId('getByBarcode', $logId); $ticketChecker->setFilsArray(); $ticketChecker->setTicketId($logId); $selectedTicket = $ticketChecker->getDataOfTheSelectedTicket(); $ticketChecker->setBbTicketRowId($selectedTicket->id); $ticketChecker->check5Minutes($logId); $ticketChecker->checkExceptionHandlers($selectedTicket, 'getByBarcode', $logId); $ticketChecker->setMergedTickets($selectedTicket, 'getByBarcode', $logId); $ticketChecker->saveCoordinates($logId); $ticketChecker->saveData($selectedTicket); ApiBbusLog::getByBarcode("{$logId} Status: OK!"); ApiBbusLog::getByBarcode("{$logId} ================="); return 'OK'; } /** * curlGetFilsArray * * Return an array with success information. * * @param string $ref * * @return array|mixed Data without useless information * * @url POST curlGetFilsArray * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function curlGetFilsArray($ref) { $fils = []; $sqlFAC = "SELECT rowid FROM llx_facture WHERE ref = '{$ref}'"; $resultFAC = $this->db->query($sqlFAC); if ($this->db->num_rows($resultFAC)) { while ($facture = $this->db->fetch_object($resultFAC)) { $sql = "SELECT fdet.fk_product FROM llx_facture AS f INNER JOIN llx_facturedet as fdet ON fdet.fk_facture = f.rowid WHERE f.rowid = {$facture->rowid}"; $result = $this->db->query($sql); while ($sqlDataResult = pg_fetch_assoc($result)) { $fils[] = $sqlDataResult['fk_product']; } } } return $fils; } /** * Post invoice ref and creation date for data recording * * Return an array with success information. * * @param string $type_id Type id * @param string $ref Facture ref * @param string $datetime invoice creation date * * @return array|mixed Data without useless information * * @url POST printdate * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function dateHandler(string $type_id, string $ref, string $datetime) { global $user, $conf; ApiBbusLog::appLog("dateHandler"); if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(403); } if (empty($ref)) { throw new RestException(401, 'Empty ref!'); } if (empty($datetime)) { throw new RestException(401, 'Empty datetime!'); } ApiBbusLog::appLog("dateHandler: Access granted"); $printDate = DateTime::createFromFormat('Y-m-d H:i:s', $datetime); $now = new DateTime('now'); $now = (clone $now)->modify('+2 minutes'); $validDate = (clone $now)->modify('-5 minutes'); $datetime = $printDate->format('Y-m-d H:i:s'); $datetime_timestamp = strtotime($datetime); dol_syslog('printDate: ' . print_r($printDate, true), LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR); dol_syslog('now: ' . print_r($now, true), LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR); dol_syslog('validDate: ' . print_r($validDate, true), LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR); //print_r($validDate); //print_r($printDate); //print_r($now); if ($validDate <= $printDate && $printDate <= $now) { $server_host = $this->getServerHost($type_id); # Keresztvásárlás if ($server_host == $conf->global->LOCAL_SERVER_HOST) { ApiBbusLog::appLog("dateHandler: local"); ApiBbusLog::appLog("dateHandler: {$datetime_timestamp}"); $this->localDateHandler($ref, $datetime, $datetime_timestamp, $now, $type_id); } else { ApiBbusLog::appLog("dateHandler: curl"); $this->curlDateHandler($ref, $datetime, $type_id); } } else { ApiBbusLog::appLog("dateHandler: Invalid date"); throw new RestException(401, 'Invalid date'); } return 'OK'; } private function localDateHandler($ref, $datetime, $datetime_timestamp, $now) { global $user; $helper = new ApiBBusHelper(); $facture_id = $helper->getFactureIdForInvoicePrinting($ref); if (empty($facture_id)) { ApiBbusLog::appLog("localDateHandler: no facture_id because cross-shopping"); $printedCopies = $this->checkPrintedCopiesWithRef($ref); } else { $printedCopies = $this->checkPrintedCopies($facture_id); } // Leellenőrzöm, hogy a számla volt-e már nyomtatva ApiBbusLog::appLog("printedCopies: {$printedCopies}"); if ($printedCopies == 0) { ApiBbusLog::appLog("printedCopies: no copies"); if (empty($facture_id)) { ApiBbusLog::appLog("No facture_id"); $bbTicketsByFacture = $this->getTicketsByInvoiceNumber($ref); } else { ApiBbusLog::appLog("Facture_id: " . $facture_id); $bbTicketsByFacture = $this->getTicketsByFactureId($facture_id); } foreach ($bbTicketsByFacture as $ticket) { ApiBbusLog::appLog("Create BBticketInvoiceprinting record"); // Rogzitem a bbticketinvoiceprinting tablaba a rekordot $helper->setPrintingInvoiceObject($user, $facture_id, $datetime, $datetime_timestamp, $ticket, $ref); } } else { ApiBbusLog::appLog("printedCopies: MULTIPRINT"); if (empty($facture_id)) { $ticketIds = $helper->getTicketIdsForCrossShopping($ref); } else { $ticketIds = $helper->getTicketIdsByFactureId($facture_id, $ref); } $ticketObj = new stdClass(); foreach ($ticketIds as $key => $value) { // Rogzitem a bbticketinvoiceprinting tablaba a rekordot $ticketObj->id = $key; $ticketObj->ticket_id = $value; $helper->setPrintingInvoiceObject($user, $facture_id, $datetime, $datetime_timestamp, $ticketObj, $ref); } // e-mail küldése $helper->sendMail($facture_id, $datetime, $now->format('Y-m-d H:i:s')); return 'Multiprinting'; } } /* private function localDateHandler($ref, $datetime, $datetime_timestamp, $now) { global $user; $helper = new ApiBBusHelper(); $facture_id = $helper->getFactureIdForInvoicePrinting($ref); // Leellenőrzöm, hogy a számla volt-e már nyomtatva $printedCopies = $this->checkPrintedCopies($facture_id); if ($printedCopies == 0) { $bbTicketsByFacture = $this->getTicketsByFactureId($facture_id); foreach ($bbTicketsByFacture as $ticket) { // Rogzitem a bbticketinvoiceprinting tablaba a rekordot $helper->setPrintingInvoiceObject($user, $facture_id, $datetime, $datetime_timestamp, $ticket, $ref); } } else { $ticketIds = $helper->getTicketIdsByFactureId($facture_id); $ticketObj = new stdClass(); foreach ($ticketIds as $key => $value) { // Rogzitem a bbticketinvoiceprinting tablaba a rekordot $ticketObj->id = $key; $ticketObj->ticket_id = $value; $helper->setPrintingInvoiceObject($user, $facture_id, $datetime, $datetime_timestamp, $ticketObj, $ref); } // e-mail küldése $helper->sendMail($facture_id, $datetime, $now->format('Y-m-d H:i:s')); //return 'Multiprinting'; } } */ public function curlDateHandler($ref, $datetime, $type_id) { $params = compact('ref', 'datetime', 'type_id'); $datehandlerPostFields = json_encode($params); ApiBbusLog::appLog("dateHandler: {$datehandlerPostFields}"); $this->curlRunner('bbus/printdate', $datehandlerPostFields, 'POST', true); } /** * Save customer data (zip or countrycode) in facture table * * Return a result. * * @param string $facture_id Facture rowid * @param string $customerdatazip Customer data ZIP * @param string $customerdatacountrycode Customer data Countrycode * * @return array|mixed Data without useless information * * @url POST customerDataHandler * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function customerDataHandler(string $facture_id, string $customerdatazip = null, string $customerdatacountrycode = null) { if (is_null($customerdatazip) && is_null($customerdatacountrycode)) { dol_syslog("Nem sikerult a facture updateje. Ref: " . $this->facture_id, LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR); throw new RestException(404, 'Empty params'); } $sql = "UPDATE " . $this->db->prefix() . "facture_extrafields SET "; $sql .= !is_null($customerdatazip) ? "customer_data_zip = '{$customerdatazip}' " : "customer_data_countrycode = '{$customerdatacountrycode}' "; $sql .= "WHERE fk_object = '{$facture_id}'"; $this->factureUpdate($sql, $facture_id); return "OK"; } /** * Check user and eventdetail type permissions * * Return a result. * * @return array|mixed Data without useless information * * @url GET checkPermission */ public function checkPermission() { global $user, $db; ApiBbusLog::appLog("checkPermission_START"); $memcached = new Memcached(); $memcached->addServer("szollosil-excelia-urbanms-memcached", 11211); $key = '"' . $user->api_key . '"'; $cacheValue = $memcached->get($key); if ($cacheValue === false) { $permissionArray = []; $groupUsersObj = new GroupUsers($db); $result = $groupUsersObj->fetchAll('desc', 'rowid', 1, 0, ["customsql" => "fk_user = {$user->id}"]); if ($result == -1 || empty($result)) { return $permissionArray; } dol_include_once('/eventwizard/class/eventdetails.class.php'); $sqlBasicService = "SELECT pe.basic_service FROM llx_product as p INNER JOIN llx_product_extrafields as pe ON pe.fk_object = p.rowid GROUP BY pe.basic_service"; $resultBasicServices = $db->query($sqlBasicService); if ($db->num_rows($resultBasicServices) > 0) { while ($row = $db->fetch_object($resultBasicServices)) { $basicServices[] = $row->basic_service; } } $sqlBasicServicesTable = "SELECT basic_service_id, ref, is_event FROM llx_bbus_basicServices ORDER BY basic_service_id ASC"; $resultBasicServicesObj = $db->query($sqlBasicServicesTable); if ($db->num_rows($resultBasicServicesObj) > 0) { while ($bsrow = $db->fetch_object($resultBasicServicesObj)) { foreach ($basicServices as $item) { if ($bsrow->basic_service_id == $item && $item != 2) { if ($bsrow->is_event == '1' && $this->isAvailablePlaces($item)) { $permissionArray[$item] = $bsrow->ref; } elseif ($bsrow->is_event != '1') { $permissionArray[$item] = $bsrow->ref; } } } } } $cacheValue = json_encode($permissionArray); $memcached->set($key, $cacheValue, 600); // 5 percig tároljuk ApiBbusLog::appLog("Adat betöltve a adatbázis-ból: " . $cacheValue); } else { ApiBbusLog::appLog("Adat betöltve a cache-ből: " . $cacheValue); } //$curlPermissionArray = $this->curlRunner('rollerstorageapi/checkPermission', ''); //$permissionArray = $permissionArray + (array)json_decode($curlPermissionArray); //return $permissionArray; return json_decode($cacheValue, true); } private function isAvailablePlaces($item) { global $conf; $available = false; $server_host = $this->getServerHost($item); $sqlProducts = "SELECT fk_object, basic_service FROM llx_product_extrafields WHERE basic_service = '{$item}'"; $resultProducts = $this->db->query($sqlProducts); if ($this->db->num_rows($resultProducts) > 0) { while ($prodductsRow = $this->db->fetch_object($resultProducts)) { $productsArray[$prodductsRow->fk_object] = $prodductsRow->basic_service; } if (!empty($productsArray)) { foreach ($productsArray as $key => $value) { ApiBbusLog::appLog("SERVER_HOST: " . $server_host); ApiBbusLog::appLog("CONF_SERVER_HOST: " . $conf->global->LOCAL_SERVER_HOST); if ($server_host == $conf->global->LOCAL_SERVER_HOST) { ApiBbusLog::appLog($conf->global->LOCAL_SERVER_HOST); $availableResult = $this->localCheckAvailablePlacesForCheckPermission($key); } elseif ($server_host == $conf->global->CURL_SERVER_HOST) { ApiBbusLog::appLog($conf->global->CURL_SERVER_HOST); $postFields = '{"product_id":"' . $key . '"}'; $availableResult = $this->curlRunner('bbus/localCheckAvailablePlacesForCheckPermission', $postFields, 'POST', false); } if ($availableResult == 1) { $available = true; } } } }; return $available; } /** * localCheckAvailablePlacesForCheckPermission * * @param int $product_id Product rowid * * @return array|mixed Data without useless information * * @url POST localCheckAvailablePlacesForCheckPermission * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function localCheckAvailablePlacesForCheckPermission($product_id) { $date_from = $this->getCutOffTimeDate($product_id); $sql = "SELECT ac.id FROM llx_actioncomm as ac LEFT JOIN llx_actioncomm_extrafields as ace ON ace.fk_object = ac.id INNER JOIN llx_eventwizard_eventdetails as ed ON ac.fk_element = ed.rowid INNER JOIN llx_eventwizard_eventproduct as ep ON ep.fk_eventdetails = ac.fk_element WHERE ac.code = 'AC_EVENT' AND ep.fk_product = {$product_id} AND ac.datep > '{$date_from}' ORDER BY ac.datep ASC"; //ApiBbusLog::appLog($sql); $result = $this->db->query($sql); return $this->db->num_rows($result) > 0 ? 1 : 0; } private function getCutOffTimeDate($product_id) { $date = date("Y-m-d H:i:s"); $sql = "SELECT cut_off_time_app FROM llx_product_extrafields WHERE fk_object = {$product_id}"; if ($result = $this->db->query($sql)) { if ($this->db->num_rows($result) > 0) { while ($row = $this->db->fetch_object($result)) { $cutOffTime = $row->cut_off_time_app; } $dateTimestamp = strtotime($date); $date = date("Y-m-d H:i:s", $dateTimestamp + $cutOffTime * 60); } } return $date; } /** * Create naplo for userlogout * * Return a result. * * @return array|mixed Data without useless information * * @url POST logoutNaploCreator * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function logoutNaploCreator() { global $user, $db; $error = 0; $db->begin(); $group_user_id = $this->getGroupUserIdByUserId($user->id); if ($group_user_id == -1) { $error++; } $result = $this->isLastStatusLogout($user); if ($result !== '') { return date('Y-m-d H:i:s', $result); } $userLoginNaplo = new UserLoginNaplo($db); $userLoginNaplo->login_logout_status = 1; $userLoginNaplo->user_id = $user->id; $result = $userLoginNaplo->create($user); if ($result < 0) { $error++; } $userNaploObj = new UserNaplo($db); $userNaploObj->user_id = $user->id; $userNaploObj->group_user_id = $group_user_id; $userNaploObj->status = 0; $result = $userNaploObj->create($user); if ($result < 0) { $error++; } $groupUsersObj = new GroupUsers($db); $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "settlements_groupusers WHERE fk_user = {$user->id}"; $data = $db->query($sql); $dataArray = pg_fetch_assoc($data); $selectedGroupId = $dataArray['rowid']; if (isset($selectedGroupId)) { $resultKickOff = $groupUsersObj->deleteLine($user, $selectedGroupId); if (!$resultKickOff) { $error++; } } if ($error) { $db->rollback(); } $db->commit(); return 'OK'; } /** * Get the discount unit From Product * * Return a result. * * @param int $product_id Product rowid * * @return string discount unit * * @url POST getDiscountUnit * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function getDiscountUnit(int $product_id) { global $db, $user; $ProductObj = new Product($db); $ProductObj->fetch($product_id); return $ProductObj->array_options['discount_period']; } /** * Create naplo for Discount * * Return a result. * * @param int $facture_id Facture rowid * @param int $product_id Product rowid * @param int $discount Discount * @param string $discount_unit Discount unit * * @return array|mixed Data without useless information * * @url POST createDiscountNaplo * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function createDiscountNaplo(int $facture_id, int $product_id, int $discount, string $discount_unit) { global $db, $user; $discountNaploObj = new DiscountNaplo($db); $discountNaploObj->fk_facture = $facture_id; $discountNaploObj->fk_product = $product_id; $discountNaploObj->discount = $discount; $discountNaploObj->discount_unit = $discount_unit; $result = $discountNaploObj->create($user); if ($result < 0) { return false; } return $result; } /** * Get the products from Product * * Return a result. * * @param int $entity entity * * @return array|mixed Data without useless information * * @url POST getHotelSalesProducts * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function getHotelSalesProducts(int $entity) { global $db, $user; $sql = "SELECT p.* FROM public.llx_product AS p INNER JOIN public.llx_product_extrafields as pe ON pe.fk_object = p.rowid WHERE p.entity = {$entity} AND pe.hotelsales = 1"; $products = $this->db->query($sql); $row = pg_fetch_all($products); return $row; } private function getGroupUserIdByUserId($user_id) { global $db; $groupUsersObj = new GroupUsers($db); $result = $groupUsersObj->fetchAll('DESC', 'rowid', 1, 0, ["customsql" => "fk_user = {$user_id}"]); if (!empty($result)) { foreach ($result as $record) { return $record->fk_settlements_group; } } return -1; } private function isLastStatusLogout($user) { global $db; $userLoginNaplo = new UserLoginNaplo($db); $result = $userLoginNaplo->fetchAll('DESC', 'date_creation', 1, 0, array('user_id' => $user->id)); foreach ($result as $lastrecord) { return $lastrecord->login_logout_status == 1 ? $lastrecord->date_creation : ''; } } private function factureUpdate($sql, $facture_id) { $updated = $this->db->query($sql); if (!$updated) { dol_syslog("Nem sikerult a facture updateje. rowid: " . $facture_id, LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR); throw new RestException(404, 'Update failed'); } } private function checkUserReadPermission() { if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(403); } } private function checkUserValidatePermission() { if (!DolibarrApiAccess::$user->rights->bbus->ticket->validation) { throw new RestException(403); } } private function getFactureRowIdByFactureId() { $facture = new Facture($this->db); $sqlFacture = "SELECT rowid FROM public.llx_facture WHERE ref ILIKE '%{$this->code}%'"; $result = $this->db->query($sqlFacture); if (pg_num_rows($result) > 0) { while ($adatok = pg_fetch_assoc($result)) { $factureRowid = $adatok['rowid']; } } else { throw new RestException(404, 'Invoice not found.'); } $sql = "SELECT rowid FROM llx_facture WHERE fk_facture_source = {$factureRowid} AND type = 2"; $res = $this->db->query($sql); if (pg_num_rows($res) > 0) { throw new RestException(404, 'Invoice has a Credit account.'); } return $factureRowid; } private function checkResult($result, $tableName) { if (!is_array($result) || empty($result)) { dol_syslog("A megadott szuresi adatokhoz nem tartozik rekord ({$tableName}).", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR); throw new RestException(404, "A megadott szuresi adatokhoz nem tartozik rekord ({$tableName})."); } } private function saveBbTicketNaplo($user) { $bbTicketNaplo = new BbTicketNaplo($this->db); $bbTicketNaplo->ticket_row_id = $this->bbTicketRowId; $bbTicketNaplo->bbservicelocation_id = isset($this->service_location_id) ? $this->service_location_id : null; $bbTicketNaplo->device_id = isset($this->device_id) ? $this->device_id : null; $bbTicketNaplo->status = $this->status; if ($bbTicketNaplo->create($user) < 0) { dol_syslog('Nem sikerult menteni a bbticketNaplo tablaba a rekordot.', LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR); throw new RestException(500, 'Nem sikerult menteni a bbticketNaplo tablaba a rekordot.'); } } private function getTicketsByFactureId($facture_id) { $bbticket = new BbTicket($this->db); $bbTicketsByFacture = $bbticket->fetchAll('', '', 0, 0, ['customsql' => 'fk_facture = ' . intval($facture_id)]); if ($bbTicketsByFacture < 1) { throw new RestException(404, 'BBTicket not found'); } return $bbTicketsByFacture; } private function getTicketsByInvoiceNumber($ref) { $bbticket = new BbTicket($this->db); $bbTicketsByFacture = $bbticket->fetchAll('', '', 0, 0, ["customsql" => "invoice_number = '" . $ref . "'"]); if ($bbTicketsByFacture < 1) { ApiBbusLog::appLog("getTicketsByInvoiceNumber: BBTicket not found"); throw new RestException(404, 'BBTicket not found'); } ApiBbusLog::appLog("getTicketsByInvoiceNumber: I got it"); return $bbTicketsByFacture; } private function checkPrintedCopies($facture_id) { $bbticketinvoiceprinting = new BbTicketInvoicePrinting($this->db); $copies = $bbticketinvoiceprinting->fetchAll('ASC', 'rowid', 0, 0, ['customsql' => 'fk_facture = ' . intval($facture_id)]); return (is_array($copies)) ? count($copies) : 0; } private function checkPrintedCopiesWithRef($ref) { $bbticketinvoiceprinting = new BbTicketInvoicePrinting($this->db); $copies = $bbticketinvoiceprinting->fetchAll('ASC', 'rowid', 0, 0, ["customsql" => "invoice_number = '" . $ref . "'"]); return (is_array($copies)) ? count($copies) : 0; } /** * @param string $facture_id Facture ref * * @return array|mixed Data without useless information * * @url POST getRefFromFacture * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function getRefFromFacture(string $facture_id) { global $user; $facture = new Facture($this->db); $sql = "SELECT ref FROM " . $this->db->prefix() . $facture->table_element . " WHERE rowid = " . $facture_id; $res = $this->db->query($sql); while ($adatok = pg_fetch_assoc($res)) { print_r($adatok['ref']); exit; } return 'OK'; } /** * Get properties of a product object by barcode * * Return an array with product information. * * @param string $barcode Barcode of element * @param int $includestockdata Load also information about stock (slower) * @param bool $includesubproducts Load information about subproducts * @param bool $includeparentid Load also ID of parent product (if product is a variant of a parent product) * @param bool $includetrans Load also the translations of product label and description * * @return array|mixed Data without useless information * * @url GET profileimage/{id} * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function getUserImage(int $id) { $image = null; $dolApiKey = $_SERVER['HTTP_DOLAPIKEY'] ?? null; if (empty($dolApiKey)) { throw new RestException(401, 'Access not allowed'); } $user = (new ApiUserHandler)->getUser($id, $dolApiKey); if (empty($user->photo)) { throw new RestException(404, 'Photo not found'); } else { $originalFile = get_exdir(0, 0, 0, 0, $user, 'user') . 'photos/' . $user->photo; $originalFile = DOL_DOCUMENT_ROOT . '/documents/users/' . $originalFile; $filename = basename($originalFile); $originalFileOsEncoded = dol_osencode($originalFile); // New file name encoded in OS encoding charset $fileContent = file_get_contents($originalFileOsEncoded); $image = [ 'filename' => $filename, 'content-type' => dol_mimetype($filename), 'filesize' => filesize($originalFile), 'content' => base64_encode($fileContent), 'encoding' => 'base64' ]; } return $image; } /** * Create invoices from the order * * @param int $id_order (Row)Id of the order * @param int $id_soc Id of 3th party * @return array Response * @url POST invoicesFromOrder * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function invoicesFromOrder(int $id_order, int $id_soc = 0): array { // echo ini_get('memory_limit'); // exit; if (!DolibarrApiAccess::$user->rights->facture->creer) { throw new RestException(401, "Insuffisant rights"); } require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; // Standard or deposit invoice, not from a Predefined template invoice // Si facture standard $this->now = time(); $this->invoices = []; $element == 'order'; $element = $subelement = 'commande'; //etalon obj: $object = new Facture($this->db); // $extrafields = new ExtraFields($db); $defaultDevSocId = 1; $this->defaultSocId = (isset($_ENV['DEFAULT_SOCID']) && (int) $_ENV['DEFAULT_SOCID']) ? (int) $_ENV['DEFAULT_SOCID'] : $defaultDevSocId; $object->socid = (empty((int) $id_soc)) ? $this->defaultSocId : (int) $id_soc; $object->type = null; $object->ref = null; $object->date = $this->now; // $object->date_pointoftax = $date_pointoftax; // $object->note_public = trim(GETPOST('note_public', 'restricthtml')); // $object->note_private = trim(GETPOST('note_private', 'restricthtml')); // $object->ref_client = GETPOST('ref_client'); $object->model_pdf = null; // $object->fk_project = GETPOST('projectid', 'int'); // $object->cond_reglement_id = (GETPOST('type') == 3 ? 1 : GETPOST('cond_reglement_id')); // $object->mode_reglement_id = GETPOST('mode_reglement_id'); // $object->fk_account = GETPOST('fk_account', 'int'); // $object->amount = price2num(GETPOST('amount')); // $object->remise_absolue = price2num(GETPOST('remise_absolue'), 'MU'); // $object->remise_percent = price2num(GETPOST('remise_percent'), '', 2); // $object->fk_incoterms = GETPOST('incoterm_id', 'int'); // $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); // $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha'); // $object->multicurrency_tx = GETPOST('originmulticurrency_tx', 'int'); $object->fetch_thirdparty(); // If creation from another object of another module (Example: origin=propal, originid=1) $object->origin = $element; $object->origin_id = $id_order; // Possibility to add external linked objects with hooks $object->linked_objects[$object->origin] = $object->origin_id; // link with order if it is a shipping invoice if (is_array($_POST['other_linked_objects']) && !empty($_POST['other_linked_objects'])) { $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); } // dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); $classname = ucfirst($subelement); $srcobject = new $classname($this->db); $result = $srcobject->fetch($id_order); if ($result > 0) { $lines = $srcobject->lines; if (empty($lines) && method_exists($srcobject, 'fetch_lines')) { $srcobject->fetch_lines(); $lines = $srcobject->lines; } /* // If we create a standard invoice with a percent, we change amount by changing the qty if (is_array($lines)) { foreach ($lines as $line) { // We keep ->subprice and ->pa_ht, but we change the qty $line->qty = price2num($line->qty * $valuestandardinvoice / 100, 'MS'); } } */ $fk_parent_line = 0; $num = count($lines); $invNum = 0; for ($i = 0; $i < $num; $i++) { // if (!in_array($lines[$i]->id, $selectedLines)) { // continue; // Skip unselected lines // } //!!! create invoice by line: $quantity = $lines[$i]->qty; for ($j = 0; $j < $quantity; $j++) { $this->invoices[$invNum] = clone $object; if ($id = $this->invoices[$invNum]->create(DolibarrApiAccess::$user)) { $this->invoices[$invNum]->update_price(1, 'auto', 0, $mysoc); $label = (!empty($lines[$i]->label) ? $lines[$i]->label : ''); $desc = (!empty($lines[$i]->desc) ? $lines[$i]->desc : $lines[$i]->libelle); if ($this->invoices[$invNum]->situation_counter == 1) { $lines[$i]->situation_percent = 0; } if ($lines[$i]->subprice < 0 && empty($conf->global->INVOICE_KEEP_DISCOUNT_LINES_AS_IN_ORIGIN)) { // Negative line, we create a discount line require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php'; $discount = new DiscountAbsolute($db); $discount->fk_soc = $this->invoices[$invNum]->socid; $discount->amount_ht = abs($lines[$i]->total_ht); $discount->amount_tva = abs($lines[$i]->total_tva); $discount->amount_ttc = abs($lines[$i]->total_ttc); $discount->tva_tx = $lines[$i]->tva_tx; $discount->fk_user = DolibarrApiAccess::$user->id; $discount->description = $desc; $discount->multicurrency_subprice = abs($lines[$i]->multicurrency_subprice); $discount->multicurrency_amount_ht = abs($lines[$i]->multicurrency_total_ht); $discount->multicurrency_amount_tva = abs($lines[$i]->multicurrency_total_tva); $discount->multicurrency_amount_ttc = abs($lines[$i]->multicurrency_total_ttc); $discountid = $discount->create(DolibarrApiAccess::$user); if ($discountid > 0) { $result = $this->invoices[$invNum]->insert_discount($discountid); // This include link_to_invoice } else { setEventMessages($discount->error, $discount->errors, 'errors'); $error++; break; } } else { // Positive line $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0); // Date start $date_start = false; if ($lines[$i]->date_debut_prevue) { $date_start = $lines[$i]->date_debut_prevue; } if ($lines[$i]->date_debut_reel) { $date_start = $lines[$i]->date_debut_reel; } if ($lines[$i]->date_start) { $date_start = $lines[$i]->date_start; } // Date end $date_end = false; if ($lines[$i]->date_fin_prevue) { $date_end = $lines[$i]->date_fin_prevue; } if ($lines[$i]->date_fin_reel) { $date_end = $lines[$i]->date_fin_reel; } if ($lines[$i]->date_end) { $date_end = $lines[$i]->date_end; } // Reset fk_parent_line for no child products and special product if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) { $fk_parent_line = 0; } // Extrafields if (method_exists($lines[$i], 'fetch_optionals')) { $lines[$i]->fetch_optionals(); $array_options = $lines[$i]->array_options; } $tva_tx = $lines[$i]->tva_tx; if (!empty($lines[$i]->vat_src_code) && !preg_match('/\(/', $tva_tx)) { $tva_tx .= ' (' . $lines[$i]->vat_src_code . ')'; } // View third's localtaxes for NOW and do not use value from origin. // TODO Is this really what we want ? Yes if source is template invoice but what if proposal or order ? $localtax1_tx = get_localtax($tva_tx, 1, $this->invoices[$invNum]->thirdparty); $localtax2_tx = get_localtax($tva_tx, 2, $this->invoices[$invNum]->thirdparty); $result = $this->invoices[$invNum]->addline( $desc, $lines[$i]->subprice, // $lines[$i]->qty, 1, $tva_tx, $localtax1_tx, $localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, $date_start, $date_end, 0, $lines[$i]->info_bits, $lines[$i]->fk_remise_except, 'HT', 0, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $this->invoices[$invNum]->origin, $lines[$i]->rowid, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $array_options, $lines[$i]->situation_percent, $lines[$i]->fk_prev_id, $lines[$i]->fk_unit, 0, '', 1 ); if ($result > 0) { $lineid = $result; } else { $lineid = 0; $error++; break; } // Defined the new fk_parent_line if ($result > 0 && $lines[$i]->product_type == 9) { $fk_parent_line = $result; } } } $invNum++; } } } else { setEventMessages($srcobject->error, $srcobject->errors, 'errors'); $error++; } $num = count($this->invoices); $return = [ 'validated' => [] ]; // $used_mem = round(memory_get_usage(false) / 1024 / 1024); //mb // $used_mem = round(memory_get_usage(true) / 1024 / 1024); //mb // echo $used_mem. " / ".$allowed_mem; // echo ini_get('memory_limit'); // exit; for ($i = 0; $i < $num; $i++) { //!!! validation // $idwarehouse = 0; // $notrigger = 0; // $result = $this->invoices[$i]->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger); $id = $this->invoices[$i]->id; $result = $this->invoices[$i]->validate(DolibarrApiAccess::$user, '', null); if ($result >= 0) { // Define output language if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { global $langs; $outputlangs = $langs; $newlang = ''; if (!empty($conf->global->MAIN_MULTILANGS) && empty($newlang) && GETPOST('lang_id', 'aZ09')) { $newlang = GETPOST('lang_id', 'aZ09'); } if (!empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) { $newlang = $this->invoices[$i]->thirdparty->default_lang; } if (!empty($newlang)) { $outputlangs = new Translate("", $conf); $outputlangs->setDefaultLang($newlang); $outputlangs->load('products'); } $model = $this->invoices[$i]->model_pdf; $ret = $this->invoices[$i]->fetch($id); // Reload to get new records // PDF $hidedetails = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS)) ? 1 : 0; $hidedesc = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC)) ? 1 : 0; $hideref = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF)) ? 1 : 0; $result = $this->invoices[$i]->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); if ($result < 0) { //... // setEventMessages($this->invoices[$i]->error, $this->invoices[$i]->errors, 'errors'); } } } else { // if (count($this->invoices[$i]->errors)) { // setEventMessages(null, $this->invoices[$i]->errors, 'errors'); // } else { // setEventMessages($this->invoices[$i]->error, $this->invoices[$i]->errors, 'errors'); // } } // if ($result == 0) { // throw new RestException(304, 'Error nothing done. May be object is already validated'); // } // if ($result < 0) { // throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error); // } // $this->invoices[$i] = $this->invoicees[$i]->fetch($id); if (!$this->invoices[$i]) { throw new RestException(404, 'Invoice not found'); } $this->invoices[$i] = parent::_cleanObjectDatas($this->invoices[$i]); unset($this->invoices[$i]->note); unset($this->invoices[$i]->address); unset($this->invoices[$i]->barcode_type); unset($this->invoices[$i]->barcode_type_code); unset($this->invoices[$i]->barcode_type_label); unset($this->invoices[$i]->barcode_type_coder); unset($this->invoices[$i]->canvas); if (!DolibarrApi::_checkAccessToResource('facture', $id)) { throw new RestException(401, 'Access not allowed for login ' . DolibarrApiAccess::$user->login); } $return['validated'][] = $this->invoices[$i]->ref; } return $return; } /** * Jegy generálás -> (order?->) invoice -> payment -> jegy -> qr on the bill * * Return an array with prcess information. * * @param array $orderDetails Order details * * @return array|mixed Data without useless information * * @url POST order * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function jegy(array $orderDetails) { $return = [ "request" => $orderDetails ]; $Jegy = new Jegy(); $return['hash'] = [ $Jegy->generate_hash(), $Jegy->generate_hash(1), $Jegy->generate_hash(20), $Jegy->generate_hash(50), $Jegy->generate_hash(100), ]; return $return; } /** * Get app config * * Return an array with config params. * * @return array|mixed Data without useless information * * @url GET config * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function config(): array { global $user, $conf; $helper = new ApiBBusHelper(); // company $companyData = $helper->getCompany(); return [ 'exchange_rate' => ExchangeRateUpdater::getExchangeRate(ExchangeRateUpdater::EUR, $conf->entity), 'invoice' => [ 'header' => [ 'name' => $companyData['company_data']['NOM'], 'tax_number' => $companyData['company_data']['TVAINTRA'], 'address' => [ 'zip' => $companyData['company_data']['ZIP'], 'city' => $companyData['company_data']['TOWN'], 'address' => $companyData['company_data']['ADDRESS'] ] ], 'customer' => $helper->getAppCustomers(), 'vat_percent' => 27, 'entity' => $user->entity, 'account_id' => $helper->getAccountRowid($user->entity), 'currencies' => $helper->getCurrenciesRowid($user->entity), 'payments_mode' => $helper->getPaymentsMode($user->entity) ] ]; } /** * Get groupId for REACT * * Return an ID. * * @return integer Data without useless information * * @url GET getGroupId * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function getGroupId(): array { global $user, $db; $sql = "SELECT fk_settlements_group FROM public.llx_settlements_groupusers WHERE fk_user = {$user->id} ORDER BY rowid DESC LIMIT 1"; $result = $db->query($sql); while ($row = pg_fetch_assoc($result)) { return $row; } return []; } /** * Insert a row into login log table * * @param string $login Login name * * @return array|mixed Data without useless information * * @url POST savelogin * * @throws RestException 404 */ public function saveLogin(string $login) { $error = 0; $this->db->begin(); $user = new User($this->db); //$user->fetch(0, $login, 0, 0, 1); $user->fetch(0, $login, 0, 0); if (empty($user->id)) { throw new RestException(404, 'User not found'); } $log = new BbLoginLog($this->db); $log->entity = 1; $log->description = 'Login from App'; $id = $log->create($user); if ($id < 1) { $error++; throw new RestException(500, 'Log failure'); } $now = dol_now(); $userremoteip = getUserRemoteIP(); $sql = "UPDATE " . $this->db->prefix() . "user SET"; $sql .= " datepreviouslogin = datelastlogin,"; $sql .= " ippreviouslogin = iplastlogin,"; $sql .= " datelastlogin = '" . $this->db->idate($now) . "',"; $sql .= " iplastlogin = '" . $this->db->escape($userremoteip) . "',"; $sql .= " tms = tms"; // La date de derniere modif doit changer sauf pour la mise a jour de date de derniere connexion $sql .= " WHERE rowid = " . ((int) $user->id); $resql = $this->db->query($sql); if (!$resql) { $error++; $this->error = $this->db->lasterror() . ' sql=' . $sql; } if (!$error) { $this->db->commit(); return 'OK'; } else { $this->db->rollback(); } } /** * Receive GPS coordinates of the device * * @param string $licplate License plate of the vehicle * @param string $lat GPS latitude coordinate * @param string $lon GPS longitude coordinate * * @return string|mixed Data without useless information * * @url GET /gps_coords * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 * @throws RestException 500 */ public function gpsCoords(string $licplate, string $lat, string $lon): string { if (!(new GpsPosition)->save($licplate, $lat, $lon)) { throw new RestException(500, 'Save failure'); } return 'OK'; } /** * Receive GPS coordinates of the device * * @param string $licplate License plate of the vehicle * @param string $lat GPS latitude coordinate * @param string $lon GPS longitude coordinate * * @return string|mixed Data without useless information * * @url POST /gps_position * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 * @throws RestException 500 */ public function gpsPosition(string $licplate, string $lat, string $lon): string { if (!(new GpsPosition)->save($licplate, $lat, $lon)) { throw new RestException(500, 'Save failure'); } return 'OK'; } /** * List of countries * * Return an array with country name and code. * * @param string $lang * @param string $search * * @return array|mixed Data without useless information * * @url GET /countries * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function countries(string $lang = 'hu', string $search = ''): array { return (new CountryHandler)->getCountries($lang, $search); } /** * List of entities * * Return an array with companies data. * * @return array|mixed Data without useless information * * @url GET /entities * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function entities(): array { return (new EntityHandler)->getEntities(); } /** * List of assets received * * Return an array with assets received. * * @return array|mixed Data without useless information * * @url GET /assets_received * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function assetsReceived(): array { global $user, $db; $packageHistory = new PackageHistory($db); $inventoryObj = new Inventory($db); $sql = "SELECT pt.device_id, i.ref, i.title, ie.unique_identifier, (SELECT ph.date_creation FROM " . $this->db->prefix() . $packageHistory->table_element . " as ph WHERE user_id = {$user->id} AND DATE(ph.date_creation) = CURRENT_DATE ORDER BY ph.rowid DESC LIMIT 1) AS ph_date_creation FROM llx_settlements_packagetool pt INNER JOIN llx_inventory as i ON i.rowid = pt.device_id INNER JOIN llx_inventory_extrafields as ie ON ie.fk_object = i.rowid WHERE pt.package_id = (SELECT ph.package_id FROM public.llx_rollerstorage_packagehistory as ph WHERE user_id = {$user->id} AND DATE(ph.date_creation) = CURRENT_DATE ORDER BY ph.rowid DESC LIMIT 1) ORDER BY pt.rowid DESC"; //print $sql;exit; $result = $db->query($sql); $changeSql = "SELECT ref, title FROM " . $this->db->prefix() . $inventoryObj->table_element . " WHERE ref ILIKE '%Change%'"; $resultCh = $db->query($changeSql); if ($result > 0 && $resultCh > 0) { while ($row = $db->fetch_object($result)) { $row = (array) $row; $date = $row['ph_date_creation']; $device[] = [ "name" => isset($row['title']) ? $row['title'] : '', "sku" => isset($row['unique_identifier']) ? $row['unique_identifier'] : '' ]; } $change = []; while ($rowCh = $db->fetch_object($resultCh)) { $rowCh = (array) $rowCh; $ChangeArray = explode('_', $rowCh['ref']); $key = isset($ChangeArray[1]) ? strtolower($ChangeArray[1]) : ''; if (!empty($key)) { $change[$key] = isset($rowCh['title']) ? $rowCh['title'] : ''; } } } else { return []; } return [ 'date' => $date, 'devices' => $device, 'change' => $change ]; } /** * Save card payment log * * @param string $invoice_ref * @param string $data * * @return array|mixed Data without useless information * * @url POST /cardpaymentlog * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function cardPaymentLog(string $invoice_ref, string $data) { $result = 'OK'; $facture = new Facture($this->db); if ($facture->fetch(0, $invoice_ref) > 0) { $facture->array_options['options_payment_log'] = $data; $facture->updateExtraField('payment_log'); $json = json_decode($data, true); if (!empty($json['authorization_number'])) { $sql = " UPDATE " . MAIN_DB_PREFIX . "paiement SET num_paiement='" . $json['authorization_number'] . "' WHERE rowid=( SELECT fk_paiement FROM " . MAIN_DB_PREFIX . "paiement_facture WHERE fk_facture={$facture->id} ) "; $this->db->query($sql); } } else { $result = 'Missing invoice'; } return $result; } /** * Products list with children * * @param string $sortfield Sort field * @param string $sortorder Sort order * @param int $limit Limit for list * @param int $page Page number * @param int $mode Use this param to filter list (0 for all, 1 for only product, 2 for only service) * @param int $category Use this param to filter list by category * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.tobuy:=:0) and (t.tosell:=:1)" * @param bool $ids_only Return only IDs of product instead of all properties (faster, above all if list is long) * @param int $variant_filter Use this param to filter list (0 = all, 1=products without variants, 2=parent of variants, 3=variants only) * @param bool $pagination_data If this parameter is set to true the response will include pagination data. Default value is false. Page starts from 0 * @param int $includestockdata Load also information about stock (slower) * @return array Array of product objects * * @url GET /products * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function products($sortfield = 't.ref', $sortorder = 'ASC', $limit = 100, $page = 0, $mode = 0, $category = 0, $sqlfilters = '', $ids_only = false, $variant_filter = 0, $pagination_data = false, $includestockdata = 0): array { if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(403); } $productsArray = []; $productsArray = (new ApiProductListHelper)->list($sortfield, $sortorder, $limit, $page, $mode, $category, $sqlfilters, $ids_only, $variant_filter, $pagination_data, $includestockdata); return $productsArray; } /** * Products list with children * * @param string $sortfield Sort field * @param string $sortorder Sort order * @param int $limit Limit for list * @param int $page Page number * @param int $mode Use this param to filter list (0 for all, 1 for only product, 2 for only service) * @param int $category Use this param to filter list by category * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.tobuy:=:0) and (t.tosell:=:1)" * @param bool $ids_only Return only IDs of product instead of all properties (faster, above all if list is long) * @param int $variant_filter Use this param to filter list (0 = all, 1=products without variants, 2=parent of variants, 3=variants only) * @param bool $pagination_data If this parameter is set to true the response will include pagination data. Default value is false. Page starts from 0 * @param int $includestockdata Load also information about stock (slower) * @return array Array of product objects * * @url GET /productshotel * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function productshotel($sortfield = 't.ref', $sortorder = 'ASC', $limit = 100, $page = 0, $mode = 0, $category = 0, $sqlfilters = '', $ids_only = false, $variant_filter = 0, $pagination_data = false, $includestockdata = 0): array { if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(403); } return (new ApiProductListHelper)->listhotel($sortfield, $sortorder, $limit, $page, $mode, $category, $sqlfilters, $ids_only, $variant_filter, $pagination_data, $includestockdata); } /** * Create invoice * * @param array $invoice Invoice data * @param array $lines Invoice lines * @param array $payment Invoice payment * @param string $cardPaymentLog Card payment log data * * @return array|mixed Data without useless information * * @url POST /invoice */ public function invoice(array $invoice, array $lines, array $payment, string $cardPaymentLog = '', string $sendId = '', $server_host_curl = false, $company_invoice = '') { global $user, $conf; $lockLabel = 'CREATE_INVOICE'; if (empty($sendId)) { $sendId = substr(md5(rand()), 0, 8); } /** * LOG SECTION */ ApiBbusLog::appLog("{$sendId} === NEW INVOICE ==="); dol_syslog("{$sendId} === NEW INVOICE ===", LOG_INFO, 0); ApiBbusLog::appLog("{$sendId} REQUEST: {$sendId}"); dol_syslog("{$sendId} REQUEST: {$sendId}", LOG_INFO, 0); ApiBbusLog::appLog("{$sendId} User: {$user->firstname} {$user->lastname} (ID: {$user->id})"); dol_syslog("{$sendId} User: {$user->firstname} {$user->lastname} (ID: {$user->id})", LOG_INFO, 0); ApiBbusLog::appLog("{$sendId} " . json_encode([ 'invoice' => $invoice, 'lines' => $lines, 'payment' => $payment, 'cardPaymentLog' => $cardPaymentLog ])); /** * CHECK RIGHTS */ if (!DolibarrApiAccess::$user->rights->facture->creer) { ApiBbusLog::appLog("{$sendId} Insufficient rights"); throw new RestException(401, 'Insufficient rights'); } $apiInvoiceHelper = new ApiInvoiceHelper; $BookingApi = new BookingApi; /** * handle invoice basic data */ $invoiceObj = $apiInvoiceHelper->createInvoice($invoice, $sendId, $company_invoice); ApiBbusLog::appLog("{$sendId} Invoice created"); /** * handle invoice line(s) */ $products = []; foreach ($lines as $line) { $invoiceObj = $apiInvoiceHelper->addLineToInvoice($invoiceObj, $line, $sendId); $product = $apiInvoiceHelper->loadProductToResult($line); if (!empty($product)) { $products[] = $product; } } $invoiceObj->fetch_lines(); foreach ($products as &$row) { foreach ($invoiceObj->lines as $line) { if ($line->product_ref == $row['ref']) { //$row['price'] = $line->total_ttc; $row['price'] = $line->multicurrency_total_ttc; $row['total_tva'] = $line->total_tva; //$row['total_tva'] = $line->multicurrency_total_tva; } } } /** * validate */ $invoiceObj = $apiInvoiceHelper->validateInvoice($invoiceObj, $sendId); /** * set payment */ $apiInvoiceHelper->setPayment($invoiceObj, $payment, $sendId); /** * save card payment data */ if (!empty($cardPaymentLog)) { $invoiceObj = $apiInvoiceHelper->saveCardPaymentLog($invoiceObj, $cardPaymentLog, $sendId); } ApiBbusLog::appLog("{$sendId} Invoice created. ID: {$invoiceObj->id} REF: {$invoiceObj->ref} REQ: {$sendId}"); dol_syslog("{$sendId} Invoice created. ID: {$invoiceObj->id} REF: {$invoiceObj->ref} REQ: {$sendId}", LOG_INFO, 0); //$bbApiLock->delete($user); ApiBbusLog::appLog("{$sendId}####################################################################"); dol_syslog("{$sendId}####################################################################", LOG_INFO, 0); #-------------- UPDATE BTICKET -------------- foreach ($products as $product) { $server_host = ''; $proSQL = "SELECT bbs.server_host FROM llx_product as pr INNER JOIN llx_product_extrafields as pre ON pre.fk_object = pr.rowid INNER JOIN llx_bbus_basicservices as bbs ON bbs.rowid = CAST(pre.basic_service AS integer) WHERE pr.rowid = {$product['id']}"; $proResult = $this->db->query($proSQL); if ($this->db->num_rows($proResult) > 0) { while ($proRow = $this->db->fetch_object($proResult)) { $server_host = $proRow->server_host; } } if ($server_host == $conf->global->LOCAL_SERVER_HOST) { $BookingApi->updateBbticket(get_object_vars($invoiceObj), null); } else { ApiBbusLog::appLog("{$sendId}: Update bbticket with curl"); $invoiceForCurl['id'] = $invoiceObj->id; $invoiceForCurl['ref'] = $invoiceObj->ref; $array['invoice'] = $invoiceForCurl; $updateBBticketPostFields = json_encode($array); ApiBbusLog::appLog("{$updateBBticketPostFields}"); $this->curlRunner('bookingapi/curlUpdateBbticket', $updateBBticketPostFields, 'POST', true); } } return [ 'sendId' => $sendId, 'invoice' => [ 'id' => $invoiceObj->id, 'ref' => $invoiceObj->ref, 'total' => $invoiceObj->multicurrency_total_ttc ], 'products' => $products, ]; } /** * Get the saled factures data by user * * @param string $date Date * * @return array|mixed Data without useless information * * @url POST /saledfacturesbyuser */ function saledfacturesbyuser(string $date) { global $user, $db; $date = date("Y-m-d", dol_now()); $fulldate = date("Y-m-d H:i:s", dol_now()); $apiBbusHelper = new ApiBBusHelper(); $from = $apiBbusHelper->getGroupLoginDate($date); $to = $apiBbusHelper->getGroupLogout($date, $from); $array = []; if (strtotime($fulldate) > strtotime($to)) { return $array; } $sql = "SELECT f.rowid as facture_rowid, f.ref AS facture_ref, f.datec, f.multicurrency_code, pa.libelle, pai.note AS transaction_id, fdet.fk_product AS product_id, pr.label AS product_label, pr.ref AS product_ref, pr.description, pass.fk_product_pere AS bundle_id, pr2.label AS bundle_label, pr2.ref AS bundle_ref, fdet.multicurrency_total_tva AS base_tva, fdet.multicurrency_total_ttc AS base_ttc, fdete.discount_percent, fdete.discount_hours, pr.default_vat_code, f.multicurrency_total_ttc AS bundle_ttc, (SELECT rate FROM llx_multicurrency_rate AS mc WHERE mc.fk_multicurrency = f.fk_multicurrency AND mc.entity = {$user->entity} ORDER BY mc.rowid DESC LIMIT 1) AS rate, (SELECT date_start FROM llx_booking_bookinghistory AS bh WHERE bh.fk_facture = f.rowid) AS date_start FROM llx_facture AS f INNER JOIN llx_facture_extrafields AS fe ON fe.fk_object = f.rowid INNER JOIN llx_c_paiement AS pa ON pa.id = f.fk_mode_reglement INNER JOIN llx_paiement_facture AS pafa ON pafa.fk_facture = f.rowid INNER JOIN llx_paiement AS pai ON pai.rowid = pafa.fk_paiement INNER JOIN llx_facturedet AS fdet ON fdet.fk_facture = f.rowid INNER JOIN llx_product AS pr ON pr.rowid = fdet.fk_product left JOIN llx_product_association AS pass ON pass.fk_product_fils = pr.rowid LEFT JOIN llx_product AS pr2 ON pr2.rowid = pass.fk_product_pere LEFT JOIN llx_facturedet_extrafields AS fdete ON fdet.rowid = fdete.fk_object WHERE f.datec BETWEEN '{$from}' AND '{$to}' AND f.fk_user_closing = $user->id ORDER BY f.rowid DESC"; //print $sql;exit; $data = $db->query($sql); if ($db->num_rows($data > 0)) { while ($row = $db->fetch_object($data)) { $tmpArray = (array) $row; if ($tmpArray['transaction_id'] != '') { $jsonArray = json_decode($tmpArray['transaction_id']); $row->transaction_id = $jsonArray->card_transaction_id; } $row->bundle_id = $row->bundle_id == '' ? $row->product_id : $row->bundle_id; $row->bundle_label = $row->bundle_label == '' ? $row->product_label : $row->bundle_label; $row->bundle_ref = $row->bundle_ref == '' ? $row->product_ref : $row->bundle_ref; $array[$row->facture_rowid]['ref'] = $row->facture_ref; $array[$row->facture_rowid]['bundle_name'] = $row->bundle_label; $array[$row->facture_rowid]['currency'] = $row->multicurrency_code; $array[$row->facture_rowid]['total_price'] = $row->bundle_ttc; $array[$row->facture_rowid]['type'] = $row->libelle; $array[$row->facture_rowid]['transaction_id'] = $row->transaction_id; $array[$row->facture_rowid]['rate'] = $row->rate; $array[$row->facture_rowid]['date'] = $row->datec; $array[$row->facture_rowid]['lines'][$row->product_id] = (array) $row; } return $array; } else { return $array; } } /** * List of assets received * * Return an array with assets received. * * @return array|mixed Data without useless information * * @url GET /getAllUsersOfTheGroup * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function getAllUsersOfTheGroup(): array { global $user, $db; $array = []; $sql = "SELECT u.rowid, u.firstname, u.lastname, u.login, ue.nickname, u.email, u.office_phone, u.user_mobile, u.personal_mobile FROM llx_settlements_groupusers AS gu INNER JOIN llx_user_extrafields as ue ON ue.fk_object = gu.fk_user INNER JOIN llx_user as u ON u.rowid = gu.fk_user WHERE gu.fk_settlements_group = (SELECT gu2.fk_settlements_group FROM llx_settlements_groupusers as gu2 WHERE gu2.fk_user = {$user->id})"; $data = $db->query($sql); while ($row = $db->fetch_object($data)) { $array[] = [ 'id' => $row->rowid, 'name' => $row->firstname . ' ' . $row->lastname, 'login' => $row->login, 'email' => $row->email, 'nickname' => $row->nickname ? $row->nickname : '', 'office_phone' => $row->office_phone, 'user_mobile' => $row->user_mobile, 'personal_mobile' => $row->personal_mobile ]; } return $array; } /** * Generate events * * @return array|mixed Data without useless information * * @url GET /genEvents * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function genEvents() { $period = new DatePeriod( new DateTime('2024-05-09'), new DateInterval('P1D'), new DateTime('2024-09-01') ); $size = 30; $buffer = 5; $dates = []; foreach ($period as $date) { if (rand(0, 1)) { $eventDate = $date->format('Y-m-d'); $eventTimes = array_rand( array_flip([ '16:00', '18:00', '20:00', '22:00' ]), rand(1, 4) ); /* print $eventDate; print "\r\n"; print_r($eventTimes); */ if (is_array($eventTimes)) { foreach ($eventTimes as $eventTime) { $dates[$eventDate][] = [ 'start' => $eventTime, 'duration' => '02:00:00', ]; } } } } $dates = ['dates' => $dates]; dol_include_once('/eventwizard/class/eventdetails.class.php'); $object = new EventDetails($this->db); $object->fetch(1); $object->genEvents($dates); return []; } /** * Generate events * * @return array|mixed Data without useless information * * @url GET /updateeventextrafields * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function updateEventsExtrafields() { $sql = "SELECT ac.id FROM llx_actioncomm as ac LEFT JOIN llx_actioncomm_extrafields as ace ON ace.fk_object = ac.id WHERE ac.code = 'AC_EVENT' AND ace.fk_object IS NULL"; $result1 = $this->db->query($sql); while ($row1 = $this->db->fetch_object($result1)) { $sql2 = "INSERT INTO llx_actioncomm_extrafields (fk_object, max_num, buffer) VALUES ({$row1->id}, 30, 5)"; $result = $this->db->query($sql2); } } /** * Generate factures * * @return array|mixed Data without useless information * * @url POST /generateFactures * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function generateFactures() { $numberOfFactures = 1; for ($i = 0; $i < $numberOfFactures; $i++) { $currencyRand = rand(0, 1); $currencyText = [0 => 'HUF', 1 => 'EUR']; $currencyNumber = [0 => 3, 1 => 5]; $reglementRand = rand(14, 15); //$reglementRand = rand(106, 107); ## STAGING $mode_reglement_id = $reglementRand; $paymentid = $reglementRand; $accountid = [0 => 4, 1 => 5]; $deduction = rand(1, 5) == 3 ? 1 : null; $storno = rand(1, 5) == 1 ? 1 : null; $invoice = ["mode_reglement_id" => $mode_reglement_id, "array_options_app_facture" => 1, "array_options_commission_deduction" => $deduction, "array_options_marked_for_storno" => $storno, "multicurrency_code" => $currencyText[$currencyRand], "fk_multicurrency" => $currencyNumber[$currencyRand], "array_options_customer_data_zip" => null]; $linesHUFBundle = [ ["desc" => "", "subprice" => "787.4015", "qty" => 1, "tva_tx" => "27.0", "localtax1_tx" => "0.000", "localtax2_tx" => "0.000", "fk_product" => "102", "remise_percent" => "0", "date_start" => "", "date_end" => "", "fk_code_ventilation" => 0, "info_bits" => "0", "fk_remise_except" => null, "product_type" => "1", "rang" => "-1", "special_code" => "0", "fk_parent_line" => null, "fk_fournprice" => null, "pa_ht" => "0.00000000", "label" => "", "array_options" => [], "situation_percent" => "100", "fk_prev_id" => null, "fk_unit" => null, "price_base_type" => "HT"], ["desc" => "", "subprice" => "13333.3333", "qty" => 1, "tva_tx" => "5.0", "localtax1_tx" => "0.000", "localtax2_tx" => "0.000", "fk_product" => "108", "remise_percent" => "0", "date_start" => "", "date_end" => "", "fk_code_ventilation" => 0, "info_bits" => "0", "fk_remise_except" => null, "product_type" => "1", "rang" => "-1", "special_code" => "0", "fk_parent_line" => null, "fk_fournprice" => null, "pa_ht" => "0.00000000", "label" => "", "array_options" => [], "situation_percent" => "100", "fk_prev_id" => null, "fk_unit" => null, "price_base_type" => "HT"] ]; $linesEURBundle = [ ["desc" => "", "subprice" => "2.3622", "qty" => 1, "tva_tx" => "27.0", "localtax1_tx" => "0.000", "localtax2_tx" => "0.000", "fk_product" => "101", "remise_percent" => "0", "date_start" => "", "date_end" => "", "fk_code_ventilation" => 0, "info_bits" => "0", "fk_remise_except" => null, "product_type" => "1", "rang" => "-1", "special_code" => "0", "fk_parent_line" => null, "fk_fournprice" => null, "pa_ht" => "0.00000000", "label" => "", "array_options" => [], "situation_percent" => "100", "fk_prev_id" => null, "fk_unit" => null, "price_base_type" => "HT"], ["desc" => "", "subprice" => "33.3333", "qty" => 1, "tva_tx" => "5.0", "localtax1_tx" => "0.000", "localtax2_tx" => "0.000", "fk_product" => "107", "remise_percent" => "0", "date_start" => "", "date_end" => "", "fk_code_ventilation" => 0, "info_bits" => "0", "fk_remise_except" => null, "product_type" => "1", "rang" => "-1", "special_code" => "0", "fk_parent_line" => null, "fk_fournprice" => null, "pa_ht" => "0.00000000", "label" => "", "array_options" => [], "situation_percent" => "100", "fk_prev_id" => null, "fk_unit" => null, "price_base_type" => "HT"] ]; $linesEURSimple = [ ["desc" => "", "subprice" => "12.5984", "qty" => 1, "tva_tx" => "27.0", "localtax1_tx" => "0.000", "localtax2_tx" => "0.000", "fk_product" => "132", "remise_percent" => "0", "date_start" => "", "date_end" => "", "fk_code_ventilation" => 0, "info_bits" => "0", "fk_remise_except" => null, "product_type" => "1", "rang" => "-1", "special_code" => "0", "fk_parent_line" => null, "fk_fournprice" => null, "pa_ht" => "0.00000000", "label" => "", "array_options" => [], "situation_percent" => "100", "fk_prev_id" => null, "fk_unit" => null, "price_base_type" => "HT"], ]; $linesArray = [ 0 => $linesEURBundle, 1 => $linesEURSimple, 2 => $linesHUFBundle ]; if ($currencyRand == 1) { $lineRand = rand(0, 1); $lines = $linesArray[$lineRand]; } else { $lines = $linesArray[2]; } $payment = ["datepaye" => time(), "paymentid" => $paymentid, "closepaidinvoices" => "yes", "accountid" => $accountid[$currencyRand]]; $comment = "{\"timestamp\":\"1704241200\",\"merchant_id\":\"000000000014202\",\"acquirer_id\":\"88105000003\",\"operation_number\":\"000037\",\"termid\":\"36002058\",\"pan\":\"428312******1789\",\"exp\":\"****\",\"stan\":\"000007\",\"authorization_number\":\"282597\",\"trans_type\":\"CLI\",\"amount\":\"2.0\",\"cvm\":\"2\",\"billnumber\":\"AcTbHmcWsMGcF6Nf\",\"card_transaction_id\":\"AcTbHmcWsMGcF6Nf\"}"; $payment['comment'] = $reglementRand == 15 ? '' : $comment; //$payment['comment'] = $reglementRand == 107 ? '' : $comment; ## STAGING $cardPaymentLog = ""; /* print_r($invoice); print_r($lines); print_r($payment); exit; */ $invoiceNumber = $this->invoice($invoice, $lines, $payment, $cardPaymentLog, $sendId = ''); $ref = $invoiceNumber['invoice']['ref']; $datetime = date("Y-m-d H:i:s", $payment['datepaye']); $multiprint = rand(1, 5); $this->dateHandler($ref, $datetime); if ($multiprint == 2 || $multiprint == 3) { $prints = rand(1, 5); $dateofprint = $payment['datepaye']; for ($i = 0; $i < $prints; $i++) { $dateofprint = strtotime('+5 seconds', $dateofprint); $datetime = date("Y-m-d H:i:s", $dateofprint); $this->dateHandler($ref, $datetime); } } } return 'OK'; } /** * Generate events * * @return array|mixed Data without useless information * * @url GET /getDatetime * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function getDatetime() { $dateArray = []; $now = dol_now(); $dateArray = ["timestamp" => $now, "date" => date("Y-m-d", $now), "datetime" => date("Y-m-d H:i:s", $now)]; return $dateArray; } /** * Get the saled factures data by user * * @param string $ref Date * * @return array|mixed Data without useless information * * @url POST /curlgetdatecfromfacture */ public function curlgetdatecfromfacture(string $ref) { $sql = "SELECT datec FROM llx_facture WHERE ref = '{$ref}'"; $result = $this->db->query($sql); if ($this->db->num_rows($result) < 1) { return []; } else { while ($row = $this->db->fetch_object($result)) { return $row->datec; } } } /** * Get the saled factures data by user * * @param string $ref Date * * @return array|mixed Data without useless information * * @url POST /curlgetproductidfromfacturedet */ public function curlgetproductidfromfacturedet(string $ref) { ApiBbusLog::appLog("curlgetproductidfromfacturedet"); $helper = new ApiBBusHelper(); $facture_id = $helper->getFactureIdForInvoicePrinting($ref); global $db; $array = []; $sql = "SELECT fk_product FROM public.llx_facturedet WHERE fk_facture = " . $facture_id; $result = $db->query($sql); while ($facturedetrecord = pg_fetch_assoc($result)) { $array[] = $facturedetrecord['fk_product']; } return $array; } /** * Create SQL queries for products clone * * @return array|mixed Data without useless information * * @url POST /giveMeAllProducts * * @throws RestException 401 * @throws RestException 403 * @throws RestException 404 */ public function giveMeAllProducts() { $productsArray = []; $sql = "SELECT * FROM llx_product"; $result = $this->db->query($sql); while ($row = $this->db->fetch_object($result)) { $productsArray[$row->rowid]['product'] = $row; $sqlef = "SELECT * FROM llx_product_extrafields WHERE fk_object = {$row->rowid}"; $resultef = $this->db->query($sqlef); while ($rowef = $this->db->fetch_object($resultef)) { $contentef = "-- new Extrafields row {$rowef->rowid} DELETE FROM llx_product_extrafields WHERE fk_object = {$rowef->rowid}; INSERT INTO llx_product_extrafields ("; $valueContentef = ""; $keyNumberef = count((array)$rowef); $keyNumberef - 2; $counteref = 1; foreach ($rowef as $efkey => $efvalue) { if ($efkey == 'oneoccasion' || $efkey == 'online') { $counteref++; } else { $contentef .= "{$efkey}"; if ($efkey == 'fk_user_author') { $valueContentef .= intval(1); } elseif ($efkey == 'fk_user_modif') { $valueContentef .= intval(1); } else { $valueContentef .= "{$this->getvvalue($efvalue)}"; } if ($counteref <= $keyNumberef - 1) { $contentef .= ", "; $valueContentef .= ", "; } else { $contentef .= ") VALUES ("; $valueContentef .= ") ON CONFLICT (rowid) DO NOTHING;"; } $counteref++; } } $asdef = $contentef . $valueContentef; $productsArray[$row->rowid]['extrafields'] = $asdef; } $sqlprice = "SELECT * FROM llx_product_price WHERE fk_product = {$row->rowid}"; $resultprice = $this->db->query($sqlprice); while ($rowprice = $this->db->fetch_object($resultprice)) { $contentprice = "-- product price rowid: {$rowprice->rowid} DELETE FROM llx_product_price WHERE rowid = {$rowprice->rowid}; INSERT INTO llx_product_price ("; $valueContentprice = ""; $keyNumber = count((array)$rowprice); $counter = 1; foreach ($rowprice as $pricekey => $pricevalue) { //print $pricekey . "\r\n"; $contentprice .= "{$pricekey}"; if ($pricekey == 'fk_user_author') { $valueContentprice .= intval(1); } elseif ($pricekey == 'fk_user_modif') { $valueContentprice .= intval(1); } else { $valueContentprice .= "{$this->getvvalue($pricevalue)}"; } if ($counter <= $keyNumber - 1) { $contentprice .= ", "; $valueContentprice .= ", "; } else { $contentprice .= ") VALUES ("; $valueContentprice .= ") ON CONFLICT (rowid) DO NOTHING;"; } $counter++; } $asdprice = $contentprice . $valueContentprice; $productsArray[$row->rowid]['prices'] = $asdprice; } //exit; } foreach ($productsArray as $key => $value) { $content = "-- product rowid: {$key} INSERT INTO llx_product ("; $valueContent = ""; $keyNumber = count((array)$value['product']); $counter = 1; foreach ($value['product'] as $vkey => $vvalue) { $content .= "{$vkey}"; if ($vkey == 'fk_user_author') { $valueContent .= intval(1); } elseif ($vkey == 'fk_user_modif') { $valueContent .= intval(1); } else { $valueContent .= "{$this->getvvalue($vvalue)}"; } if ($counter <= $keyNumber - 1) { $content .= ", "; $valueContent .= ", "; } else { $content .= ") VALUES ("; $valueContent .= ") ON CONFLICT (rowid) DO NOTHING;"; } $counter++; } $asd = $content . $valueContent; print $asd . "\r\n"; print $value['extrafields'] . "\r\n"; print $value['prices'] . "\r\n"; } exit; } function getvvalue($value) { //$value = str_replace("'", '"', $value); if (is_numeric($value)) { $value = intval($value); } else { if (is_null($value)) { $value = 'NULL'; } else { $value = "'" . $value . "'"; } } return $value; } /** * Get events ids * * @return array|mixed Data without useless information * * @url POST /getAllEventids */ public function getAllEventids() { global $db; $array = []; $sql = "SELECT rowid FROM llx_bbus_basicservices WHERE is_event = '1'"; $result = $db->query($sql); if($db->num_rows($result) > 0){ while($row = $db->fetch_object($result)){ $array[] = $row->rowid; } } return $array; } }