Browse Source

bbus excelia code sync

BL 1 year ago
parent
commit
5dac9d9f10
27 changed files with 8667 additions and 228 deletions
  1. 2 3
      custom/bbus/class/api_bbus.class.php
  2. 56 33
      custom/bbus/class/api_bbus.class.php.bak
  3. 2523 0
      custom/bbus/class/api_bbus.class.php.bak.bak
  4. 0 1
      custom/bbus/class/api_curl.class.php
  5. 2 3
      custom/bbus/class/api_curl.class.php.bak
  6. 1 0
      custom/bbus/class/apiinvoicehelper.class.php
  7. 10 6
      custom/bbus/class/apiinvoicehelper.class.php.bak
  8. 1 2
      custom/bbus/class/commissionhandler.class.php
  9. 203 18
      custom/bbus/class/commissionhandler.class.php.bak
  10. 2 1
      custom/bbus/class/roller_handling_helper.class.php
  11. 18 2
      custom/bbus/class/ticket_checker.class.php
  12. 501 0
      custom/bbus/class/ticket_checker.class.php.bak
  13. 2 2
      custom/booking/class/api_booking.class.php
  14. 0 1
      custom/financialreport/class/helper.class.php
  15. 1993 0
      custom/financialreport/class/helper.class.php.bak
  16. 4 4
      custom/rollerstorage/class/api_rollerstorage.class.php
  17. 41 47
      custom/rollerstorage/langs/hu_HU/rollerstorage.lang
  18. 113 0
      custom/rollerstorage/langs/hu_HU/rollerstorage.lang.bak
  19. 1 2
      custom/settlements/class/daily_closing.class.php
  20. 91 19
      custom/settlements/class/daily_closing.class.php.bak
  21. 0 1
      custom/settlements/class/helper.class.php
  22. 2540 0
      custom/settlements/class/helper.class.php.bak
  23. 40 0
      custom/settlements/core/tpl/printPDF_szisz.php
  24. 0 2
      custom/settlements/core/triggers/interface_99_modSettlements_SettlementsTriggers.class.php
  25. 476 0
      custom/settlements/core/triggers/interface_99_modSettlements_SettlementsTriggers.class.php.bak
  26. 39 22
      custom/voucher/core/actions_addupdatedelete.inc.php
  27. 8 59
      custom/voucher/voucherhistory_card.php

+ 2 - 3
custom/bbus/class/api_bbus.class.php

@@ -256,7 +256,6 @@ class BBus extends DolibarrApi
 			$sub = [];
 			$sub = [];
 			foreach ($row as $key => $value) {
 			foreach ($row as $key => $value) {
 				$sub[$key] = $value;
 				$sub[$key] = $value;
-				//print $key . ' - ' . $value . "\r\n";
 			}
 			}
 			$sub['ticket_type'] = $ticketChecker->getTicketTypeByProductId($row['ticket_id']);
 			$sub['ticket_type'] = $ticketChecker->getTicketTypeByProductId($row['ticket_id']);
 			$json[] = $sub;
 			$json[] = $sub;
@@ -639,10 +638,10 @@ class BBus extends DolibarrApi
 	 */
 	 */
 	public function checkPermission()
 	public function checkPermission()
 	{
 	{
-		global $user, $db;
+		global $user, $db, $conf;
 		ApiBbusLog::appLog("checkPermission_START");
 		ApiBbusLog::appLog("checkPermission_START");
 		$memcached = new Memcached();
 		$memcached = new Memcached();
-		$memcached->addServer("szollosil-excelia-urbanms-memcached", 11211);
+		$memcached->addServer($conf->global->CONF_MEMCACHED, 11211);
 		$key = '"' . $user->api_key . '"';
 		$key = '"' . $user->api_key . '"';
 
 
 		$cacheValue = $memcached->get($key);
 		$cacheValue = $memcached->get($key);

+ 56 - 33
custom/bbus/class/api_bbus.class.php.bak

@@ -256,7 +256,6 @@ class BBus extends DolibarrApi
 			$sub = [];
 			$sub = [];
 			foreach ($row as $key => $value) {
 			foreach ($row as $key => $value) {
 				$sub[$key] = $value;
 				$sub[$key] = $value;
-				//print $key . ' - ' . $value . "\r\n";
 			}
 			}
 			$sub['ticket_type'] = $ticketChecker->getTicketTypeByProductId($row['ticket_id']);
 			$sub['ticket_type'] = $ticketChecker->getTicketTypeByProductId($row['ticket_id']);
 			$json[] = $sub;
 			$json[] = $sub;
@@ -439,7 +438,6 @@ class BBus extends DolibarrApi
 	 *
 	 *
 	 * Return an array with success information.
 	 * Return an array with success information.
 	 *
 	 *
-	 * @param  string $type_id	Type id
 	 * @param  string $ref	Facture ref
 	 * @param  string $ref	Facture ref
 	 * @param  string $datetime	invoice creation date
 	 * @param  string $datetime	invoice creation date
 	 *
 	 *
@@ -451,7 +449,7 @@ class BBus extends DolibarrApi
 	 * @throws RestException 403
 	 * @throws RestException 403
 	 * @throws RestException 404
 	 * @throws RestException 404
 	 */
 	 */
-	public function dateHandler(string $type_id, string $ref, string $datetime)
+	public function dateHandler(string $ref, string $datetime)
 	{
 	{
 		global $user, $conf;
 		global $user, $conf;
 		ApiBbusLog::appLog("dateHandler");
 		ApiBbusLog::appLog("dateHandler");
@@ -482,16 +480,28 @@ class BBus extends DolibarrApi
 		//print_r($printDate);
 		//print_r($printDate);
 		//print_r($now);
 		//print_r($now);
 
 
+		$server_host = $conf->global->LOCAL_SERVER_HOST;
+		$sqlServerHost = "SELECT bbbs.server_host FROM llx_facture as f 
+		INNER JOIN llx_facturedet as fdet ON fdet.fk_facture = f.rowid
+		INNER JOIN llx_product_extrafields as pe ON pe.fk_object = fdet.fk_product
+		INNER JOIN llx_bbus_basicservices as bbbs ON bbbs.rowid = CAST(pe.basic_service AS integer)
+		WHERE f.ref = '{$ref}'";
+		$resultSH = $this->db->query($sqlServerHost);
+		if($this->db->num_rows($resultSH) > 0){
+			while($row = $this->db->fetch_object($resultSH)){
+				$server_host = $row->server_host;
+			}
+		}
+
 		if ($validDate <= $printDate && $printDate <= $now) {
 		if ($validDate <= $printDate && $printDate <= $now) {
-			$server_host = $this->getServerHost($type_id);
 			# Keresztvásárlás
 			# Keresztvásárlás
 			if ($server_host == $conf->global->LOCAL_SERVER_HOST) {
 			if ($server_host == $conf->global->LOCAL_SERVER_HOST) {
 				ApiBbusLog::appLog("dateHandler: local");
 				ApiBbusLog::appLog("dateHandler: local");
 				ApiBbusLog::appLog("dateHandler: {$datetime_timestamp}");
 				ApiBbusLog::appLog("dateHandler: {$datetime_timestamp}");
-				$this->localDateHandler($ref, $datetime, $datetime_timestamp, $now, $type_id);
+				$this->localDateHandler($ref, $datetime, $datetime_timestamp, $now);
 			} else {
 			} else {
 				ApiBbusLog::appLog("dateHandler: curl");
 				ApiBbusLog::appLog("dateHandler: curl");
-				$this->curlDateHandler($ref, $datetime, $type_id);
+				$this->curlDateHandler($ref, $datetime);
 			}
 			}
 		} else {
 		} else {
 			ApiBbusLog::appLog("dateHandler: Invalid date");
 			ApiBbusLog::appLog("dateHandler: Invalid date");
@@ -579,9 +589,9 @@ class BBus extends DolibarrApi
 		}
 		}
 	} */
 	} */
 
 
-	public function curlDateHandler($ref, $datetime, $type_id)
+	public function curlDateHandler($ref, $datetime)
 	{
 	{
-		$params = compact('ref', 'datetime', 'type_id');
+		$params = compact('ref', 'datetime');
 		$datehandlerPostFields = json_encode($params);
 		$datehandlerPostFields = json_encode($params);
 		ApiBbusLog::appLog("dateHandler: {$datehandlerPostFields}");
 		ApiBbusLog::appLog("dateHandler: {$datehandlerPostFields}");
 		$this->curlRunner('bbus/printdate', $datehandlerPostFields, 'POST', true);
 		$this->curlRunner('bbus/printdate', $datehandlerPostFields, 'POST', true);
@@ -628,10 +638,10 @@ class BBus extends DolibarrApi
 	 */
 	 */
 	public function checkPermission()
 	public function checkPermission()
 	{
 	{
-		global $user, $db;
+		global $user, $db, $conf;
 		ApiBbusLog::appLog("checkPermission_START");
 		ApiBbusLog::appLog("checkPermission_START");
 		$memcached = new Memcached();
 		$memcached = new Memcached();
-		$memcached->addServer("szollosil-excelia-urbanms-memcached", 11211);
+		$memcached->addServer($conf->global->CONF_MEMCACHED, 11211);
 		$key = '"' . $user->api_key . '"';
 		$key = '"' . $user->api_key . '"';
 
 
 		$cacheValue = $memcached->get($key);
 		$cacheValue = $memcached->get($key);
@@ -2353,6 +2363,17 @@ class BBus extends DolibarrApi
 		return $array;
 		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()
 	public function giveMeAllProducts()
 	{
 	{
 		$productsArray = [];
 		$productsArray = [];
@@ -2430,33 +2451,35 @@ class BBus extends DolibarrApi
 			//exit;
 			//exit;
 		}
 		}
 		foreach ($productsArray as $key => $value) {
 		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;";
+			if($key > 4999){
+				$content = "-- product rowid: {$key}
+				INSERT INTO llx_product_temp (";
+				$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++;
 				}
 				}
-				$counter++;
 			}
 			}
 			$asd = $content . $valueContent;
 			$asd = $content . $valueContent;
 			print $asd . "\r\n";
 			print $asd . "\r\n";
-			print $value['extrafields'] . "\r\n";
-			print $value['prices'] . "\r\n";
+			//print $value['extrafields'] . "\r\n";
+			//print $value['prices'] . "\r\n";
 		}
 		}
 		exit;
 		exit;
 	}
 	}

+ 2523 - 0
custom/bbus/class/api_bbus.class.php.bak.bak

@@ -0,0 +1,2523 @@
+<?php
+/* Copyright (C) 2015   Jean-François Ferry     <jfefe@aternatik.fr>
+* Copyright (C) 2019   Cedric Ancelin          <icedo.anc@gmail.com>
+*
+* 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 <https://www.gnu.org/licenses/>.
+*/
+
+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 $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 $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);
+
+		$server_host = $conf->global->LOCAL_SERVER_HOST;
+		$sqlServerHost = "SELECT bbbs.server_host FROM llx_facture as f 
+		INNER JOIN llx_facturedet as fdet ON fdet.fk_facture = f.rowid
+		INNER JOIN llx_product_extrafields as pe ON pe.fk_object = fdet.fk_product
+		INNER JOIN llx_bbus_basicservices as bbbs ON bbbs.rowid = CAST(pe.basic_service AS integer)
+		WHERE f.ref = '{$ref}'";
+		$resultSH = $this->db->query($sqlServerHost);
+		if($this->db->num_rows($resultSH) > 0){
+			while($row = $this->db->fetch_object($resultSH)){
+				$server_host = $row->server_host;
+			}
+		}
+
+		if ($validDate <= $printDate && $printDate <= $now) {
+			# 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);
+			} else {
+				ApiBbusLog::appLog("dateHandler: curl");
+				$this->curlDateHandler($ref, $datetime);
+			}
+		} 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)
+	{
+		$params = compact('ref', 'datetime');
+		$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, $conf;
+		ApiBbusLog::appLog("checkPermission_START");
+		$memcached = new Memcached();
+		$memcached->addServer($conf->global->CONF_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) {
+			if($key > 4999){
+				$content = "-- product rowid: {$key}
+				INSERT INTO llx_product_temp (";
+				$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;
+	}
+}

+ 0 - 1
custom/bbus/class/api_curl.class.php

@@ -12,7 +12,6 @@ trait CurlApi
 		$curl = curl_init();
 		$curl = curl_init();
 
 
 		curl_setopt_array($curl, array(
 		curl_setopt_array($curl, array(
-			//CURLOPT_URL => 'http://dolibarr-bbusdev-imap-cron-soap/api/index.php/' . $route,
 			CURLOPT_URL => $conf->global->CURL_ROUTE . $route,
 			CURLOPT_URL => $conf->global->CURL_ROUTE . $route,
 			CURLOPT_RETURNTRANSFER => true,
 			CURLOPT_RETURNTRANSFER => true,
 			CURLOPT_VERBOSE => true,
 			CURLOPT_VERBOSE => true,

+ 2 - 3
custom/bbus/class/api_curl.class.php.bak

@@ -2,15 +2,13 @@
 
 
 use Luracast\Restler\RestException;
 use Luracast\Restler\RestException;
 require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/basicservices.class.php';
 require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/basicservices.class.php';
-
-//require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/api_bbus_log.class.php';
-
 trait CurlApi
 trait CurlApi
 {
 {
 
 
 	private function curlInit($route, $postFields = '', $request = 'POST')
 	private function curlInit($route, $postFields = '', $request = 'POST')
 	{
 	{
 		global $conf;
 		global $conf;
+		ApiBbusLog::appLog("{$conf->global->CURL_ROUTE}{$route} => {$postFields}");
 		$curl = curl_init();
 		$curl = curl_init();
 
 
 		curl_setopt_array($curl, array(
 		curl_setopt_array($curl, array(
@@ -94,6 +92,7 @@ trait CurlApi
 	{
 	{
 		$basicServices = new BasicServices($this->db);
 		$basicServices = new BasicServices($this->db);
 		$resultBS = $basicServices->fetch($type_id);
 		$resultBS = $basicServices->fetch($type_id);
+		ApiBbusLog::appLog("{$type_id} => {$basicServices->server_host}");
 		return $basicServices->server_host;
 		return $basicServices->server_host;
 	}
 	}
 }
 }

+ 1 - 0
custom/bbus/class/apiinvoicehelper.class.php

@@ -466,6 +466,7 @@ class ApiInvoice implements ApiInvoiceData
 		$paymentobj->note_private = (is_array($data['comment'])) ? json_encode($data['comment']) : $data['comment'];
 		$paymentobj->note_private = (is_array($data['comment'])) ? json_encode($data['comment']) : $data['comment'];
 
 
 		$paymentId = $paymentobj->create(DolibarrApiAccess::$user, ($data['closepaidinvoices'] == 'yes' ? 1 : 0)); // This include closing invoices
 		$paymentId = $paymentobj->create(DolibarrApiAccess::$user, ($data['closepaidinvoices'] == 'yes' ? 1 : 0)); // This include closing invoices
+		ApiBbusLog::appLog("paymentId created");
 
 
 
 
 		if ($paymentId < 0) {
 		if ($paymentId < 0) {

+ 10 - 6
custom/bbus/class/apiinvoicehelper.class.php.bak

@@ -25,7 +25,7 @@ class ApiInvoiceHelper
 	/**
 	/**
 	 * Generate invoice with basic data
 	 * Generate invoice with basic data
 	 */
 	 */
-	public function createInvoice(array $invoice, $sendId): Facture
+	public function createInvoice(array $invoice, $sendId, $company_invoice = []): Facture
 	{
 	{
 		global $user;
 		global $user;
 		ApiBbusLog::appLog("{$sendId} - createInvoice_________START - " . microtime(true));
 		ApiBbusLog::appLog("{$sendId} - createInvoice_________START - " . microtime(true));
@@ -36,7 +36,7 @@ class ApiInvoiceHelper
 		$this->apiInvoice->prepareData();
 		$this->apiInvoice->prepareData();
 		$this->apiInvoice->validate();
 		$this->apiInvoice->validate();
 		ApiBbusLog::appLog("{$sendId} - createInvoice_________END - " . microtime(true));
 		ApiBbusLog::appLog("{$sendId} - createInvoice_________END - " . microtime(true));
-		return $this->apiInvoice->create();
+		return $this->apiInvoice->create($company_invoice);
 	}
 	}
 
 
 	function getGroupId()
 	function getGroupId()
@@ -84,6 +84,7 @@ class ApiInvoiceHelper
 	 */
 	 */
 	public function addLineToInvoice(Facture $invoice, array $line, $sendId): Facture
 	public function addLineToInvoice(Facture $invoice, array $line, $sendId): Facture
 	{
 	{
+		ApiBbusLog::appLog("{$sendId} addLineToInvoice: START");
 		$tva_tx_array = explode('.', $line['tva_tx']);
 		$tva_tx_array = explode('.', $line['tva_tx']);
 		$line['tva_tx'] = $line['tva_tx'] . '000 (' . $tva_tx_array[0] . ')';
 		$line['tva_tx'] = $line['tva_tx'] . '000 (' . $tva_tx_array[0] . ')';
 		//ApiBbusLog::appLog("{$sendId} - createInvoiceLINE_________START - " . microtime(true));
 		//ApiBbusLog::appLog("{$sendId} - createInvoiceLINE_________START - " . microtime(true));
@@ -114,7 +115,8 @@ class ApiInvoiceHelper
 		$productObj = new Product($this->db);
 		$productObj = new Product($this->db);
 		$result = $productObj->fetch($product_id);
 		$result = $productObj->fetch($product_id);
 		$productObj->fk_product = $product_id;
 		$productObj->fk_product = $product_id;
-		$productObj->subprice = $productObj->price_ttc;
+		//$productObj->subprice = $productObj->price_ttc;
+		$productObj->subprice = $productObj->price;
 		$productObj->qty = 1;
 		$productObj->qty = 1;
 		$productObj->array_options['options_discount_hours'] = null;
 		$productObj->array_options['options_discount_hours'] = null;
 		$productObj->array_options['options_discount_percent'] = null;
 		$productObj->array_options['options_discount_percent'] = null;
@@ -361,7 +363,7 @@ class ApiInvoice implements ApiInvoiceData
 	/**
 	/**
 	 * 
 	 * 
 	 */
 	 */
-	public function create(): Facture
+	public function create($company_invoice = []): Facture
 	{
 	{
 		global $db;
 		global $db;
 
 
@@ -380,7 +382,9 @@ class ApiInvoice implements ApiInvoiceData
 			$this->invoice->date = dol_now();
 			$this->invoice->date = dol_now();
 		}
 		}
 
 
-		$this->invoice->type = 7;
+		if(empty($company_invoice)){
+			$this->invoice->type = 7;
+		}
 
 
 		if ($this->invoice->create(DolibarrApiAccess::$user, 0, (empty($this->data['date_lim_reglement']) ? 0 : $this->data['date_lim_reglement'])) < 0) {
 		if ($this->invoice->create(DolibarrApiAccess::$user, 0, (empty($this->data['date_lim_reglement']) ? 0 : $this->data['date_lim_reglement'])) < 0) {
 			throw new RestException(500, 'Error creating invoice', array_merge([$this->invoice->error], $this->invoice->errors));
 			throw new RestException(500, 'Error creating invoice', array_merge([$this->invoice->error], $this->invoice->errors));
@@ -462,7 +466,6 @@ class ApiInvoice implements ApiInvoiceData
 		$paymentobj->note_private = (is_array($data['comment'])) ? json_encode($data['comment']) : $data['comment'];
 		$paymentobj->note_private = (is_array($data['comment'])) ? json_encode($data['comment']) : $data['comment'];
 
 
 		$paymentId = $paymentobj->create(DolibarrApiAccess::$user, ($data['closepaidinvoices'] == 'yes' ? 1 : 0)); // This include closing invoices
 		$paymentId = $paymentobj->create(DolibarrApiAccess::$user, ($data['closepaidinvoices'] == 'yes' ? 1 : 0)); // This include closing invoices
-		ApiBbusLog::appLog("paymentId created");
 
 
 
 
 		if ($paymentId < 0) {
 		if ($paymentId < 0) {
@@ -470,6 +473,7 @@ class ApiInvoice implements ApiInvoiceData
 			ApiBbusLog::appLog("{$sendId} Payment error : " . $paymentobj->error);
 			ApiBbusLog::appLog("{$sendId} Payment error : " . $paymentobj->error);
 			throw new RestException(400, 'Payment error : ' . $paymentobj->error);
 			throw new RestException(400, 'Payment error : ' . $paymentobj->error);
 		}
 		}
+		ApiBbusLog::appLog("paymentId created");
 
 
 		if (isModEnabled('banque')) {
 		if (isModEnabled('banque')) {
 			$label = '(CustomerInvoicePayment)';
 			$label = '(CustomerInvoicePayment)';

+ 1 - 2
custom/bbus/class/commissionhandler.class.php

@@ -300,7 +300,6 @@ class CommissionHandler
         AND fk_mode_reglement = (SELECT id FROM public.llx_c_paiement WHERE entity = {$entity} AND code = '{$code}')
         AND fk_mode_reglement = (SELECT id FROM public.llx_c_paiement WHERE entity = {$entity} AND code = '{$code}')
         AND multicurrency_code = '{$currency}' 
         AND multicurrency_code = '{$currency}' 
         AND date_closing BETWEEN '{$from}' AND '{$to}'";
         AND date_closing BETWEEN '{$from}' AND '{$to}'";
-        //print $sqlForCrossShoppingFactures . '<br>';
         $resultForCrossShoppingFactures = $this->db->query($sqlForCrossShoppingFactures);
         $resultForCrossShoppingFactures = $this->db->query($sqlForCrossShoppingFactures);
         if ($this->db->num_rows($resultForCrossShoppingFactures) > 0) {
         if ($this->db->num_rows($resultForCrossShoppingFactures) > 0) {
             while ($factureCSRow = pg_fetch_assoc($resultForCrossShoppingFactures)) {
             while ($factureCSRow = pg_fetch_assoc($resultForCrossShoppingFactures)) {
@@ -315,7 +314,7 @@ class CommissionHandler
         $params = ["from" => $from, "to" => $to, "factures" => $crossShoppingFacturesString];
         $params = ["from" => $from, "to" => $to, "factures" => $crossShoppingFacturesString];
         $postFields = json_encode($params);
         $postFields = json_encode($params);
         $crossShoppingFactures = $this->curlRunner('bookingapi/getPrintedFacturesRefs', $postFields, 'POST', true);
         $crossShoppingFactures = $this->curlRunner('bookingapi/getPrintedFacturesRefs', $postFields, 'POST', true);
-        //print $crossShoppingFactures;
+
         $sql = $this->createSQL($from, $to, $currency, $code, $entity, $user_id, $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $crossShoppingFactures);
         $sql = $this->createSQL($from, $to, $currency, $code, $entity, $user_id, $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $crossShoppingFactures);
         $commissions = $this->getMulticurrencyTotalTTC($sql);
         $commissions = $this->getMulticurrencyTotalTTC($sql);
         $commissionsCroSho = 0;
         $commissionsCroSho = 0;

+ 203 - 18
custom/bbus/class/commissionhandler.class.php.bak

@@ -1,9 +1,13 @@
 <?php
 <?php
 
 
 require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
 require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/api_curl.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/api_bbus_log.class.php';
 
 
 class CommissionHandler
 class CommissionHandler
 {
 {
+    use CurlApi;
+
     public function __construct()
     public function __construct()
     {
     {
         global $db, $user;
         global $db, $user;
@@ -99,7 +103,83 @@ class CommissionHandler
 
 
     function getAllCommission($allUsersString, $currency, $from, $to, $allComissionInvoicesOfUserInTheGroupFromUserInvoice)
     function getAllCommission($allUsersString, $currency, $from, $to, $allComissionInvoicesOfUserInTheGroupFromUserInvoice)
     {
     {
+        //print $allComissionInvoicesOfUserInTheGroupFromUserInvoice;
+        if($to == null){
+            $to = date('Y-m-d H:i:s', dol_now());
+        }
+        $crossShoppingFacturesString = '';
+
+        $sqlForCrossShoppingFactures = "SELECT f.ref
+        FROM llx_facture as f 
+        INNER JOIN llx_facture_extrafields as fe ON fe.fk_object = f.rowid 
+        LEFT JOIN llx_bbus_bbticket as bbt ON bbt.fk_facture = f.rowid WHERE";
+        if (!empty($allComissionInvoicesOfUserInTheGroupFromUserInvoice)) {
+            $sqlForCrossShoppingFactures .= " f.rowid NOT IN({$allComissionInvoicesOfUserInTheGroupFromUserInvoice}) AND";
+        }
+        $sqlForCrossShoppingFactures .= " (SELECT a.rowid FROM llx_facture as a WHERE a.fk_facture_source = f.rowid AND fk_user_closing IN ({$allUsersString})) Is NULL AND
+        fk_user_closing IN ({$allUsersString}) 
+        AND multicurrency_code = '{$currency}' 
+        AND date_closing BETWEEN '{$from}' AND '{$to}'";
+        $resultForCrossShoppingFactures = $this->db->query($sqlForCrossShoppingFactures);
+        if ($this->db->num_rows($resultForCrossShoppingFactures) > 0) {
+            while ($factureCSRow = pg_fetch_assoc($resultForCrossShoppingFactures)) {
+                if ($crossShoppingFacturesString == "") {
+                    $crossShoppingFacturesString .= "'" . $factureCSRow['ref'] . "'";
+                } else {
+                    $crossShoppingFacturesString .= ",'" . $factureCSRow['ref'] . "'";
+                }
+            }
+        }
+        $params = ["from" => $from, "to" => $to, "factures" => $crossShoppingFacturesString];
+        $postFields = json_encode($params);
+        $crossShoppingFactures = $this->curlRunner('bookingapi/getPrintedFacturesRefs', $postFields, 'POST', true);
+        global $db;
         $commissions = 0;
         $commissions = 0;
+        $sql = "SELECT f.rowid, f.total_ttc, fe.commission, f.ref, f.date_closing 
+        FROM llx_facture as f 
+        INNER JOIN llx_facture_extrafields as fe ON fe.fk_object = f.rowid 
+        INNER JOIN llx_bbus_bbticketinvoiceprinting as bbtip ON bbtip.invoice_number = f.ref WHERE ";
+        if ($crossShoppingFactures != '') {
+            $sql .= " f.ref not in ({$crossShoppingFactures}) AND";
+        }
+        if (!empty($allComissionInvoicesOfUserInTheGroupFromUserInvoice)) {
+            $sql .= " f.rowid NOT IN({$allComissionInvoicesOfUserInTheGroupFromUserInvoice}) AND";
+        }
+        $sql .= "
+        fk_user_closing IN ({$allUsersString}) 
+        AND multicurrency_code = '{$currency}' 
+        AND fe.commission_deduction is NULL
+        AND date_closing BETWEEN '{$from}' AND '{$to}'
+        GROUP BY f.rowid, f.total_ttc, fe.commission, f.ref";
+        //print $sql;
+        $result = $db->query($sql);
+        if ($db->num_rows($result) != 0) {
+            while ($row = pg_fetch_assoc($result)) {
+                    $commissions += $this->getAmountOfCommission($row);
+            }
+        }
+        if ($crossShoppingFactures != '') {
+            $sqlCS = "SELECT f.rowid, f.total_ttc, fe.commission, f.ref
+        FROM llx_facture as f 
+        INNER JOIN llx_facture_extrafields as fe ON fe.fk_object = f.rowid WHERE f.ref in ({$crossShoppingFactures}) AND";
+            if (!empty($allComissionInvoicesOfUserInTheGroupFromUserInvoice)) {
+                $sqlCS .= " f.rowid NOT IN({$allComissionInvoicesOfUserInTheGroupFromUserInvoice}) AND";
+            }
+            $sqlCS .= "
+        fk_user_closing IN ({$allUsersString}) 
+        AND multicurrency_code = '{$currency}' 
+        AND fe.commission_deduction is NULL
+        AND date_closing BETWEEN '{$from}' AND '{$to}'";
+            //print $sqlCS;
+            $resultCS = $db->query($sqlCS);
+            if ($db->num_rows($resultCS) != 0) {
+                while ($rowCS = pg_fetch_assoc($resultCS)) {
+                    $commissions += $this->getAmountOfCommission($rowCS);
+                }
+            }
+        }
+        return $commissions;
+        /* $commissions = 0;
         $sql = "SELECT f.rowid, f.total_ttc, fe.commission FROM llx_facture as f
         $sql = "SELECT f.rowid, f.total_ttc, fe.commission FROM llx_facture as f
         INNER JOIN llx_facture_extrafields as fe ON fe.fk_object = f.rowid
         INNER JOIN llx_facture_extrafields as fe ON fe.fk_object = f.rowid
         WHERE f.fk_user_closing IN ({$allUsersString})
         WHERE f.fk_user_closing IN ({$allUsersString})
@@ -117,31 +197,85 @@ class CommissionHandler
         while ($row = pg_fetch_assoc($result)) {
         while ($row = pg_fetch_assoc($result)) {
             $commissions += $this->getAmountOfCommission($row);
             $commissions += $this->getAmountOfCommission($row);
         }
         }
-        return $commissions;
+        return $commissions; */
     }
     }
 
 
     function getCommisonByUserId($user_id, $currency, $from, $to, $allComissionInvoicesOfUserInTheGroupFromUserInvoice)
     function getCommisonByUserId($user_id, $currency, $from, $to, $allComissionInvoicesOfUserInTheGroupFromUserInvoice)
     {
     {
+        //print $allComissionInvoicesOfUserInTheGroupFromUserInvoice;
+        if($to == null){
+            $to = date('Y-m-d H:i:s', dol_now());
+        }
+        $crossShoppingFacturesString = '';
+
+        $sqlForCrossShoppingFactures = "SELECT f.ref
+        FROM llx_facture as f 
+        INNER JOIN llx_facture_extrafields as fe ON fe.fk_object = f.rowid 
+        LEFT JOIN llx_bbus_bbticket as bbt ON bbt.fk_facture = f.rowid WHERE";
+        if (!empty($allComissionInvoicesOfUserInTheGroupFromUserInvoice)) {
+            $sqlForCrossShoppingFactures .= " f.rowid NOT IN({$allComissionInvoicesOfUserInTheGroupFromUserInvoice}) AND";
+        }
+        $sqlForCrossShoppingFactures .= " (SELECT a.rowid FROM llx_facture as a WHERE a.fk_facture_source = f.rowid AND fk_user_closing = {$user_id}) Is NULL AND
+        fk_user_closing = {$user_id} 
+        AND multicurrency_code = '{$currency}' 
+        AND date_closing BETWEEN '{$from}' AND '{$to}'";
+        //print $sqlForCrossShoppingFactures . '<br>';
+        $resultForCrossShoppingFactures = $this->db->query($sqlForCrossShoppingFactures);
+        if ($this->db->num_rows($resultForCrossShoppingFactures) > 0) {
+            while ($factureCSRow = pg_fetch_assoc($resultForCrossShoppingFactures)) {
+                if ($crossShoppingFacturesString == "") {
+                    $crossShoppingFacturesString .= "'" . $factureCSRow['ref'] . "'";
+                } else {
+                    $crossShoppingFacturesString .= ",'" . $factureCSRow['ref'] . "'";
+                }
+            }
+        }
+        $params = ["from" => $from, "to" => $to, "factures" => $crossShoppingFacturesString];
+        $postFields = json_encode($params);
+        $crossShoppingFactures = $this->curlRunner('bookingapi/getPrintedFacturesRefs', $postFields, 'POST', true);
         global $db;
         global $db;
         $commissions = 0;
         $commissions = 0;
-        $sql = "SELECT f.rowid, f.total_ttc, fe.commission
+        $sql = "SELECT f.rowid, f.total_ttc, fe.commission, f.ref, f.date_closing 
         FROM llx_facture as f 
         FROM llx_facture as f 
         INNER JOIN llx_facture_extrafields as fe ON fe.fk_object = f.rowid 
         INNER JOIN llx_facture_extrafields as fe ON fe.fk_object = f.rowid 
-        WHERE EXISTS (SELECT * FROM llx_bbus_bbticketinvoiceprinting as bbip WHERE bbip.fk_facture = f.rowid ORDER BY bbip.rowid DESC LIMIT 1) AND";
+        INNER JOIN llx_bbus_bbticketinvoiceprinting as bbtip ON bbtip.invoice_number = f.ref WHERE ";
+        if ($crossShoppingFactures != '') {
+            $sql .= " f.ref not in ({$crossShoppingFactures}) AND";
+        }
         if (!empty($allComissionInvoicesOfUserInTheGroupFromUserInvoice)) {
         if (!empty($allComissionInvoicesOfUserInTheGroupFromUserInvoice)) {
             $sql .= " f.rowid NOT IN({$allComissionInvoicesOfUserInTheGroupFromUserInvoice}) AND";
             $sql .= " f.rowid NOT IN({$allComissionInvoicesOfUserInTheGroupFromUserInvoice}) AND";
         }
         }
         $sql .= "
         $sql .= "
         fk_user_closing = {$user_id} 
         fk_user_closing = {$user_id} 
         AND multicurrency_code = '{$currency}' 
         AND multicurrency_code = '{$currency}' 
-        --AND fe.marked_for_storno IS NULL 
         AND fe.commission_deduction is NULL
         AND fe.commission_deduction is NULL
-        AND date_closing BETWEEN '{$from}' AND '{$to}'";
+        AND date_closing BETWEEN '{$from}' AND '{$to}'
+        GROUP BY f.rowid, f.total_ttc, fe.commission, f.ref";
         //print $sql;
         //print $sql;
         $result = $db->query($sql);
         $result = $db->query($sql);
         if ($db->num_rows($result) != 0) {
         if ($db->num_rows($result) != 0) {
             while ($row = pg_fetch_assoc($result)) {
             while ($row = pg_fetch_assoc($result)) {
-                $commissions += $this->getAmountOfCommission($row);
+                    $commissions += $this->getAmountOfCommission($row);
+            }
+        }
+        if ($crossShoppingFactures != '') {
+            $sqlCS = "SELECT f.rowid, f.total_ttc, fe.commission, f.ref
+        FROM llx_facture as f 
+        INNER JOIN llx_facture_extrafields as fe ON fe.fk_object = f.rowid WHERE f.ref in ({$crossShoppingFactures}) AND";
+            if (!empty($allComissionInvoicesOfUserInTheGroupFromUserInvoice)) {
+                $sqlCS .= " f.rowid NOT IN({$allComissionInvoicesOfUserInTheGroupFromUserInvoice}) AND";
+            }
+            $sqlCS .= "
+        fk_user_closing = {$user_id} 
+        AND multicurrency_code = '{$currency}' 
+        AND fe.commission_deduction is NULL
+        AND date_closing BETWEEN '{$from}' AND '{$to}'";
+            //print $sqlCS;
+            $resultCS = $db->query($sqlCS);
+            if ($db->num_rows($resultCS) != 0) {
+                while ($rowCS = pg_fetch_assoc($resultCS)) {
+                    $commissions += $this->getAmountOfCommission($rowCS);
+                }
             }
             }
         }
         }
         return $commissions;
         return $commissions;
@@ -149,32 +283,83 @@ class CommissionHandler
 
 
     function getCashCommisonByUserId($user_id, $currency, $from, $to, $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $entity, $code)
     function getCashCommisonByUserId($user_id, $currency, $from, $to, $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $entity, $code)
     {
     {
-        $commissions = 0;
-        //$from = date('Y-m-d H:i:s', strtotime("-1 day", strtotime($from)));
-        //print $from;exit;
+
         $to = date('Y-m-d H:i:s', dol_now());
         $to = date('Y-m-d H:i:s', dol_now());
-        $sql = "SELECT f.rowid, f.multicurrency_total_ttc, fe.commission
+        $crossShoppingFacturesString = "";
+        $sqlForCrossShoppingFactures = "SELECT f.ref
         FROM llx_facture as f 
         FROM llx_facture as f 
         INNER JOIN llx_facture_extrafields as fe ON fe.fk_object = f.rowid 
         INNER JOIN llx_facture_extrafields as fe ON fe.fk_object = f.rowid 
-        WHERE EXISTS (SELECT * FROM llx_bbus_bbticketinvoiceprinting as bbip WHERE bbip.fk_facture = f.rowid ORDER BY bbip.rowid DESC LIMIT 1) AND";
+        LEFT JOIN llx_bbus_bbticket as bbt ON bbt.fk_facture = f.rowid
+        LEFT JOIN llx_bbus_bbticketinvoiceprinting as bbtip ON bbtip.invoice_number = f.ref WHERE";
         if (!empty($allComissionInvoicesOfUserInTheGroupFromUserInvoice)) {
         if (!empty($allComissionInvoicesOfUserInTheGroupFromUserInvoice)) {
-            $sql .= " f.rowid NOT IN({$allComissionInvoicesOfUserInTheGroupFromUserInvoice}) AND";
+            $sqlForCrossShoppingFactures .= " f.rowid NOT IN({$allComissionInvoicesOfUserInTheGroupFromUserInvoice}) AND";
         }
         }
-        $sql .= " (SELECT a.rowid FROM llx_facture as a WHERE a.fk_facture_source = f.rowid AND fk_user_closing = {$user_id}) Is NULL AND
+        $sqlForCrossShoppingFactures .= " (SELECT a.rowid FROM llx_facture as a WHERE a.fk_facture_source = f.rowid AND fk_user_closing = {$user_id}) Is NULL AND
         fk_user_closing = {$user_id} 
         fk_user_closing = {$user_id} 
+        
         AND fk_mode_reglement = (SELECT id FROM public.llx_c_paiement WHERE entity = {$entity} AND code = '{$code}')
         AND fk_mode_reglement = (SELECT id FROM public.llx_c_paiement WHERE entity = {$entity} AND code = '{$code}')
         AND multicurrency_code = '{$currency}' 
         AND multicurrency_code = '{$currency}' 
-        --AND fe.marked_for_storno is NuLL 
-        AND fe.commission_deduction is NULL
         AND date_closing BETWEEN '{$from}' AND '{$to}'";
         AND date_closing BETWEEN '{$from}' AND '{$to}'";
-        //print $sql . '<br>';
+        //print $sqlForCrossShoppingFactures . '<br>';
+        $resultForCrossShoppingFactures = $this->db->query($sqlForCrossShoppingFactures);
+        if ($this->db->num_rows($resultForCrossShoppingFactures) > 0) {
+            while ($factureCSRow = pg_fetch_assoc($resultForCrossShoppingFactures)) {
+                if ($crossShoppingFacturesString == "") {
+                    $crossShoppingFacturesString .= "'" . $factureCSRow['ref'] . "'";
+                } else {
+                    $crossShoppingFacturesString .= ",'" . $factureCSRow['ref'] . "'";
+                }
+            }
+        }
+
+        $params = ["from" => $from, "to" => $to, "factures" => $crossShoppingFacturesString];
+        $postFields = json_encode($params);
+        $crossShoppingFactures = $this->curlRunner('bookingapi/getPrintedFacturesRefs', $postFields, 'POST', true);
+        //print $crossShoppingFactures;
+        $sql = $this->createSQL($from, $to, $currency, $code, $entity, $user_id, $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $crossShoppingFactures);
+        $commissions = $this->getMulticurrencyTotalTTC($sql);
+        $commissionsCroSho = 0;
+        if($crossShoppingFactures !== ""){
+            $sqlCroSho = $this->createSQL($from, $to, $currency, $code, $entity, $user_id, $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $crossShoppingFactures, true);
+            $commissionsCroSho = $this->getMulticurrencyTotalTTC($sqlCroSho);
+        }
+        return $commissions + $commissionsCroSho;
+    }
+
+    function getMulticurrencyTotalTTC($sql)
+    {
+        $commissions = 0;
         $result = $this->db->query($sql);
         $result = $this->db->query($sql);
-        while ($row = pg_fetch_assoc($result)) {
-            $commissions += $row['multicurrency_total_ttc'];
+        while ($factureRow = pg_fetch_assoc($result)) {
+            $commissions += $factureRow['multicurrency_total_ttc'];
         }
         }
         return $commissions;
         return $commissions;
     }
     }
 
 
+    function createSQL($from, $to, $currency, $code, $entity, $user_id, $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $crossShoppingFactures, $crossShopping = false)
+    {
+        $sql = "SELECT f.rowid, f.multicurrency_total_ttc, fe.commission, f.ref
+        FROM llx_facture as f 
+        INNER JOIN llx_facture_extrafields as fe ON fe.fk_object = f.rowid WHERE ";
+        if ($crossShopping && $crossShoppingFactures != "") {
+            $sql .= " f.ref in ({$crossShoppingFactures}) AND";
+        } else {
+            $sql .= " EXISTS (SELECT * FROM llx_bbus_bbticketinvoiceprinting as bbip WHERE bbip.fk_facture = f.rowid ORDER BY bbip.rowid DESC LIMIT 1) AND";
+            if ($crossShoppingFactures != "") {
+                $sql .= " f.ref not in ({$crossShoppingFactures}) AND";
+            }
+        }
+        if (!empty($allComissionInvoicesOfUserInTheGroupFromUserInvoice)) {
+            $sql .= " f.rowid NOT IN({$allComissionInvoicesOfUserInTheGroupFromUserInvoice}) AND";
+        }
+        $sql .= " (SELECT a.rowid FROM llx_facture as a WHERE a.fk_facture_source = f.rowid AND fk_user_closing = {$user_id}) Is NULL AND
+        fk_user_closing = {$user_id} 
+        AND fk_mode_reglement = (SELECT id FROM public.llx_c_paiement WHERE entity = {$entity} AND code = '{$code}')
+        AND multicurrency_code = '{$currency}' 
+        AND date_closing BETWEEN '{$from}' AND '{$to}'";
+        return $sql;
+    }
+
     function getCashCommisonByUserIdHistory($user_id, $currency, $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $id, $entity, $code)
     function getCashCommisonByUserIdHistory($user_id, $currency, $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $id, $entity, $code)
     {
     {
         global $db;
         global $db;

+ 2 - 1
custom/bbus/class/roller_handling_helper.class.php

@@ -155,6 +155,7 @@ trait RollerHandligHelper
 
 
     public function getBbticketDataByInvoiceNumber_and_Timestamp($invoice_number, $timestamp)
     public function getBbticketDataByInvoiceNumber_and_Timestamp($invoice_number, $timestamp)
     {
     {
+        global $conf;
         $bbTicketData = [];
         $bbTicketData = [];
         $sql = "SELECT bbt.* FROM llx_bbus_bbticketinvoiceprinting as bbtip 
         $sql = "SELECT bbt.* FROM llx_bbus_bbticketinvoiceprinting as bbtip 
             INNER JOIN llx_product_extrafields as pre ON pre.fk_object = bbtip.product_id
             INNER JOIN llx_product_extrafields as pre ON pre.fk_object = bbtip.product_id
@@ -162,7 +163,7 @@ trait RollerHandligHelper
             INNER JOIN llx_bbus_basicservices as bbs ON bbs.rowid = CAST(pre.basic_service AS integer)
             INNER JOIN llx_bbus_basicservices as bbs ON bbs.rowid = CAST(pre.basic_service AS integer)
             WHERE bbtip.invoice_number = '{$invoice_number}'
             WHERE bbtip.invoice_number = '{$invoice_number}'
             AND bbtip.printing_date_timestamp = '{$timestamp}'
             AND bbtip.printing_date_timestamp = '{$timestamp}'
-			AND bbs.server_host = 'excelia'
+			AND bbs.server_host = '{$conf->global->LOCAL_SERVER_HOST}'
             ORDER BY bbtip.rowid DESC limit 1";
             ORDER BY bbtip.rowid DESC limit 1";
         $result = $this->db->query($sql);
         $result = $this->db->query($sql);
         if ($this->db->num_rows($result) > 0) {
         if ($this->db->num_rows($result) > 0) {

+ 18 - 2
custom/bbus/class/ticket_checker.class.php

@@ -1,4 +1,5 @@
 <?php
 <?php
+require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/api_curl.class.php';
 
 
 use Luracast\Restler\RestException;
 use Luracast\Restler\RestException;
 
 
@@ -7,6 +8,8 @@ require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/basicservices.class.php';
 
 
 class TicketChecker
 class TicketChecker
 {
 {
+    use CurlApi;
+
     private $db;
     private $db;
     private $mac;
     private $mac;
     private $code;
     private $code;
@@ -172,6 +175,7 @@ class TicketChecker
 
 
     public function check5Minutes($logId)
     public function check5Minutes($logId)
     {
     {
+        ApiBbusLog::getByBarcode("check5Minutes!!!!");
         $result = $this->bbticketNaploObj->fetchAll('DESC', 'rowid', 1, 0, ["customsql" => "ticket_row_id = {$this->bbTicketRowId}"]);
         $result = $this->bbticketNaploObj->fetchAll('DESC', 'rowid', 1, 0, ["customsql" => "ticket_row_id = {$this->bbTicketRowId}"]);
         if ($result > 0) {
         if ($result > 0) {
             foreach ($result as $ticket) {
             foreach ($result as $ticket) {
@@ -185,6 +189,9 @@ class TicketChecker
 
 
     public function setFilsArray()
     public function setFilsArray()
     {
     {
+        if (is_null($this->facture_id)) {
+			$this->curlSetFilsArray($this->code);
+		}else{
         $sql = "SELECT fdet.fk_product FROM " . $this->db->prefix() . $this->factureObj->table_element . " AS f
         $sql = "SELECT fdet.fk_product FROM " . $this->db->prefix() . $this->factureObj->table_element . " AS f
 		INNER JOIN " . $this->db->prefix() . $this->factureObj->table_element_line . " as fdet ON fdet.fk_facture = f.rowid
 		INNER JOIN " . $this->db->prefix() . $this->factureObj->table_element_line . " as fdet ON fdet.fk_facture = f.rowid
 		INNER JOIN " . $this->db->prefix() . $this->productObj->table_element . " AS p ON p.rowid = fdet.fk_product
 		INNER JOIN " . $this->db->prefix() . $this->productObj->table_element . " AS p ON p.rowid = fdet.fk_product
@@ -193,7 +200,13 @@ class TicketChecker
         while ($sqlDataResult = pg_fetch_assoc($result)) {
         while ($sqlDataResult = pg_fetch_assoc($result)) {
             $this->fils[] = $sqlDataResult['fk_product'];
             $this->fils[] = $sqlDataResult['fk_product'];
         }
         }
+        }
+    }
 
 
+    public function curlSetFilsArray($ref)
+    {
+        $postFields = '{"ref":"' . $ref . '"}';
+        $this->fils = $this->curlRunner('bbus/curlGetFilsArray', $postFields, 'POST', true);
     }
     }
 
 
     public function setFactureId($log, $logId)
     public function setFactureId($log, $logId)
@@ -205,9 +218,11 @@ class TicketChecker
                 $factureRowid = $adatok['rowid'];
                 $factureRowid = $adatok['rowid'];
             }
             }
         } else {
         } else {
-            ApiBbusLog::$log("{$logId} Invoice not found.");
-            throw new RestException(404, 'Invoice not found.');
+            ApiBbusLog::$log("{$logId} Invoice not found. Maybe cross-shopping: {$this->code}");
+            $this->facture_id = null;
+            //throw new RestException(404, 'Invoice not found.');
         }
         }
+        if(!is_null($factureRowid)){
         $sql = "SELECT rowid FROM " . $this->db->prefix() . $this->factureObj->table_element . " WHERE fk_facture_source = {$factureRowid} AND type = 2";
         $sql = "SELECT rowid FROM " . $this->db->prefix() . $this->factureObj->table_element . " WHERE fk_facture_source = {$factureRowid} AND type = 2";
         $res = $this->db->query($sql);
         $res = $this->db->query($sql);
         if (pg_num_rows($res) > 0) {
         if (pg_num_rows($res) > 0) {
@@ -217,6 +232,7 @@ class TicketChecker
 
 
         $this->facture_id = $factureRowid;
         $this->facture_id = $factureRowid;
     }
     }
+    }
 
 
     public function setBbTicketRowId($id)
     public function setBbTicketRowId($id)
     {
     {

+ 501 - 0
custom/bbus/class/ticket_checker.class.php.bak

@@ -0,0 +1,501 @@
+<?php
+
+use Luracast\Restler\RestException;
+
+require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/basicservices.class.php';
+
+class TicketChecker
+{
+    private $db;
+    private $mac;
+    private $code;
+    private $lat;
+    private $lon;
+    private $printingTime;
+    private $status = 0;
+    private $device_id;
+    private $service_location_id;
+    private $product_id;
+    private $fils = array();
+    private $ticketIdForCheck;
+    private $basic_service_id;
+    private $ticket_id;
+    private $bbTicketRowId;
+    private $usage;
+    private $facture_id;
+    private $bundle_id;
+    private $merged_tickets;
+    private $imei;
+    private $validated_at;
+    private $expire_at;
+    private $duration;
+    private $productObj;
+    private $factureObj;
+    private $bbticketNaploObj;
+    private $bbDevicesObj;
+    private $BbDevicesServiceLocationObj;
+    private $BbDevicesServiceLocationProductObj;
+    private $bbticketObj;
+    private $bbticketInvoicePrintingObj;
+
+
+
+    public function __construct()
+    {
+        global $db, $conf, $user;
+
+        $this->db = $db;
+        $this->user = $user;
+        $this->productObj = new Product($this->db);
+        $this->factureObj = new Facture($this->db);
+        $this->bbticketNaploObj = new BbTicketNaplo($this->db);
+        $this->bbDevicesObj = new BbDevices($this->db);
+        $this->BbDevicesServiceLocationObj = new BbDevicesServiceLocation($this->db);
+        $this->BbDevicesServiceLocationProductObj = new BbDevicesServiceLocationProduct($this->db);
+        $this->bbticketObj = new BbTicket($this->db);
+        $this->bbticketInvoicePrintingObj = new BbTicketInvoicePrinting($this->db);
+    }
+
+    public function setMac($mac)
+    {
+        $this->mac = $mac;
+    }
+
+    public function setCode($code)
+    {
+        $code_and_timstamp = explode('_', $code);
+        $this->code = $code_and_timstamp[0];
+    }
+
+    public function setLat($lat)
+    {
+        $this->lat = $lat;
+    }
+
+    public function setLon($lon)
+    {
+        $this->lon = $lon;
+    }
+
+    public function setTimestamp($code, $log, $logId)
+    {
+        global $user;
+        $code_and_timstamp = explode('_', $code);
+        $this->printingTime = $code_and_timstamp[1];
+        if (empty($this->printingTime)) {
+            ApiBbusLog::$log("{$logId} Timestamp is empty!");
+            throw new RestException(404, 'Timestamp is empty!');
+        }
+    }
+
+    public function setImei($imei, $logId)
+    {
+        global $user;
+        $this->imei = $imei;
+        if (empty($this->imei)) {
+            ApiBbusLog::ticketvalidationByPhone("{$logId} IMEI is empty!");
+            throw new RestException(404, 'IMEI is empty!');
+        }
+    }
+
+    public function SetTicketidFromPhone($ticketid, $logId)
+    {
+        $this->ticket_id = $ticketid;
+        ApiBbusLog::ticketvalidationByPhone("{$logId} Ticketid: {$this->ticket_id}");
+        if (empty($this->ticket_id)) {
+            ApiBbusLog::ticketvalidationByPhone("{$logId} Ticketid is empty!");
+            throw new RestException(404, 'Ticketid is empty!');
+        }
+    }
+
+    public function set_device_id()
+    {
+        $result = $this->bbDevicesObj->fetchAll('ASC', 'date_creation', 1, 0, ["customsql" => "device_id = '" . $this->mac . "'"]);
+        $this->setId($result, 'BbDevices', 'device_id', 'id');
+    }
+
+    public function set_service_location_id()
+    {
+        $result = $this->BbDevicesServiceLocationObj->fetchAll('ASC', 'date_creation', 1, 0, ['customsql' => "device_id = " . $this->device_id]);
+        $this->setId($result, 'device_servicelocation', 'service_location_id', 'id');
+    }
+
+    public function set_basic_service_id()
+    {
+        $result = $this->BbDevicesServiceLocationProductObj->fetchAll('ASC', 'date_creation', 1, 0, ['customsql' => "devicesservicelocation_id = " . $this->service_location_id]);
+        $this->setId($result, 'device_service_location_product', 'basic_service_id', 'basic_service');
+    }
+
+    public function get_Basic_service_array()
+    {
+        $productRowIdsArray = [];
+        $sql = "SELECT fk_object FROM " . $this->db->prefix() . $this->productObj->table_element . "_extrafields WHERE basic_service = '{$this->basic_service_id}'";
+        $productsRowIDs = $this->db->query($sql);
+        while ($row = pg_fetch_assoc($productsRowIDs)) {
+            $productRowIdsArray[] = $row['fk_object'];
+        }
+        return $productRowIdsArray;
+    }
+
+    public function setTicketId($logId)
+    {
+        $this->set_device_id();
+        $this->set_service_location_id();
+        $this->set_basic_service_id();
+        $this->set_ticketIDForCheck();
+
+        if (!isset($this->ticketIdForCheck)) {
+            ApiBbusLog::getByBarcode("{$logId} Invalid ticket");
+            throw new RestException(404, 'Invalid ticket');
+        }
+        $sqlBbticketInvoicePrinting = "SELECT * FROM " . $this->db->prefix() . $this->bbticketInvoicePrintingObj->table_element . " WHERE printing_date_timestamp ILIKE '%{$this->printingTime}%' AND product_id = {$this->ticketIdForCheck}";
+        //print $sqlBbticketInvoicePrinting;exit;
+        $resultBBT = $this->db->query($sqlBbticketInvoicePrinting);
+        while ($row = pg_fetch_assoc($resultBBT)) {
+            $result2[$row['rowid']] = (object) $row;
+        }
+        //print_r($result2);exit;
+        $this->setId($result2, 'bbticketinvoiceprinting', 'ticket_id', 'ticket_id');
+
+    }
+
+    public function set_ticketIDForCheck()
+    {
+        $basic_service_array = $this->get_Basic_service_array();
+        foreach ($this->fils as $elem) {
+            if (in_array($elem, $basic_service_array)) {
+                $this->ticketIdForCheck = $elem;
+            }
+        }
+    }
+
+    public function check5Minutes($logId)
+    {
+        $result = $this->bbticketNaploObj->fetchAll('DESC', 'rowid', 1, 0, ["customsql" => "ticket_row_id = {$this->bbTicketRowId}"]);
+        if ($result > 0) {
+            foreach ($result as $ticket) {
+                if (strtotime("+5 minutes", $ticket->date_creation) > dol_now()) {
+                    ApiBbusLog::getByBarcode("{$logId} Too fast!");
+                    throw new RestException(401, 'Too fast');
+                }
+            }
+        }
+    }
+
+    public function setFilsArray()
+    {
+        $sql = "SELECT fdet.fk_product FROM " . $this->db->prefix() . $this->factureObj->table_element . " AS f
+		INNER JOIN " . $this->db->prefix() . $this->factureObj->table_element_line . " as fdet ON fdet.fk_facture = f.rowid
+		INNER JOIN " . $this->db->prefix() . $this->productObj->table_element . " AS p ON p.rowid = fdet.fk_product
+		WHERE f.rowid = {$this->facture_id}";
+        $result = $this->db->query($sql);
+        while ($sqlDataResult = pg_fetch_assoc($result)) {
+            $this->fils[] = $sqlDataResult['fk_product'];
+        }
+
+    }
+
+    public function setFactureId($log, $logId)
+    {
+        $sqlFacture = "SELECT rowid FROM " . $this->db->prefix() . $this->factureObj->table_element . " 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 {
+            ApiBbusLog::$log("{$logId} Invoice not found.");
+            throw new RestException(404, 'Invoice not found.');
+        }
+        $sql = "SELECT rowid FROM " . $this->db->prefix() . $this->factureObj->table_element . " WHERE fk_facture_source = {$factureRowid} AND type = 2";
+        $res = $this->db->query($sql);
+        if (pg_num_rows($res) > 0) {
+            ApiBbusLog::$log("{$logId} Invoice has a Credit account.");
+            throw new RestException(404, 'Invoice has a Credit account.');
+        }
+
+        $this->facture_id = $factureRowid;
+    }
+
+    public function setBbTicketRowId($id)
+    {
+        $this->bbTicketRowId = $id;
+    }
+
+    public function saveData($selectedTicket)
+    {
+        global $user;
+        if ($this->newTicket($selectedTicket)) {
+            $this->validated_at = date('Y-m-d H:i:s');
+            $this->setDurationByProductId($selectedTicket->ticket_id);
+            $this->setExpireAt($selectedTicket);
+            $this->setUsage($selectedTicket);
+            if ($this->merged_tickets) {
+                $tickets = $this->getAllTicketsByfactureIdAndTimestamp();
+                foreach ($tickets as $key => $value) {
+                    $sql = "UPDATE " . $this->db->prefix() . $this->bbticketObj->table_element . " SET validated_at = '" . $this->validated_at . "', expire_at = '" . $this->expire_at . "'";
+                    if ($key == $this->bbTicketRowId && $this->usage != 0) {
+                        $sql .= ", usage = '" . $this->usage . "'";
+                    }
+                    $sql .= " WHERE rowid = " . $key;
+                    $this->bbTicketRowId = $key;
+                    $this->saveAndCreateNaplo($sql);
+                }
+            } else {
+                $sql = "UPDATE " . $this->db->prefix() . $this->bbticketObj->table_element . " SET usage = '" . $this->usage . "', validated_at = '" . $this->validated_at . "', expire_at = '" . $this->expire_at . "' WHERE rowid = " . $this->bbTicketRowId;
+                $this->saveAndCreateNaplo($sql);
+            }
+        } else {
+            $this->setUsage($selectedTicket);
+            $sql = "UPDATE " . $this->db->prefix() . $this->bbticketObj->table_element . " SET usage = '" . $this->usage . "' WHERE rowid = " . $this->bbTicketRowId;
+            $this->saveAndCreateNaplo($sql);
+        }
+    }
+
+    public function saveCoordinates($logId)
+    {
+        global $db, $user;
+        $bbTicketValidationCoordsObj = new BbTicketValidationCoords($db);
+        $bbTicketValidationCoordsObj->fk_ticket = $this->bbTicketRowId;
+        $bbTicketValidationCoordsObj->device_id = $this->device_id;
+        $bbTicketValidationCoordsObj->location_id = $this->service_location_id;
+        $bbTicketValidationCoordsObj->lat = $this->lat;
+        $bbTicketValidationCoordsObj->lon = $this->lon;
+        if ($bbTicketValidationCoordsObj->create($user) < 0) {
+            ApiBbusLog::getByBarcode("{$logId} ##ERROR## Nem sikerult menteni a jegy koordinatait.");
+            dol_syslog("{$logId} ##ERROR## Nem sikerult menteni a jegy koordinatait.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+        }
+        ApiBbusLog::getByBarcode("{$logId} Koordinatak mentve");
+    }
+
+    private function newTicket($selectedTicket)
+    {
+        return is_null($selectedTicket->validated_at) && is_null($selectedTicket->expire_at) || empty($selectedTicket->validated_at) && empty($selectedTicket->expire_at);
+    }
+
+    private function setExpireAt($selectedTicket)
+    {
+        $discountArray = $this->getDiscountFromfacturedet($selectedTicket->ticket_id);
+        if (!empty($discountArray)) {
+            $this->expire_at = date('Y-m-d H:i:s', strtotime($this->validated_at . ' +' . substr($this->duration, 0, -1) . ' ' . $this->getIntervalTimeByDuration() . ' +' . $discountArray['value'] . ' hours'));
+        } else {
+            $this->expire_at = date('Y-m-d H:i:s', strtotime($this->validated_at . ' +' . substr($this->duration, 0, -1) . ' ' . $this->getIntervalTimeByDuration()));
+        }
+    }
+
+    private function getDiscountFromFActuredet($ticket_id)
+    {
+        $sql = "SELECT fdete.discount_hours AS value FROM " . $this->db->prefix() . $this->factureObj->table_element . " AS f
+            INNER JOIN " . $this->db->prefix() . $this->factureObj->table_element_line . " AS fdet ON f.rowid = fdet.fk_facture
+            INNER JOIN " . $this->db->prefix() . "facturedet_extrafields AS fdete ON fdete.fk_object = fdet.rowid
+            WHERE f.rowid = {$this->facture_id} AND fdet.fk_product = {$ticket_id}";
+        $res = $this->db->query($sql);
+        if (pg_num_rows($res) > 0) {
+            while ($adatok = pg_fetch_assoc($res)) {
+                return $adatok;
+            }
+        } else {
+            return [];
+        }
+    }
+
+    private function setDurationByProductId($ticket_id)
+    {
+        $sql = "SELECT p.duration as duration  FROM " . $this->db->prefix() . $this->productObj->table_element . " AS p WHERE rowid = " . $ticket_id;
+        $result = $this->getDataFromDatabase($sql, "Product");
+        $this->duration = $this->getIdFromResult($result, 'duration');
+    }
+
+    private function getIdFromResult($res, $fieldName)
+    {
+        while ($adatok = pg_fetch_assoc($res)) {
+            return $adatok[$fieldName];
+        }
+    }
+
+    private function getIntervalTimeByDiscountPeriod($period)
+    {
+        switch ($period) {
+            case 'hour':
+                return 'hours';
+            case 'day':
+                return 'days';
+            default:
+                return 'hours';
+        }
+    }
+
+    private function getIntervalTimeByDuration()
+    {
+        $duration = $this->duration[-1];
+        switch ($duration) {
+            case 'h':
+                return 'hours';
+            case 'd':
+                return 'days';
+            case 'w':
+                return 'weeks';
+            case 'm':
+                return 'months';
+            case 'y':
+                return 'years';
+            default:
+                return 'hours';
+        }
+    }
+
+    private function setUsage($selectedTicket)
+    {
+        $this->usage = $selectedTicket->usage;
+        if ($selectedTicket->usable_occasions !== 0) {
+            $this->usage++;
+        }
+    }
+
+    private function getAllTicketsByfactureIdAndTimestamp()
+    {
+        $tickets = [];
+        $sql = "SELECT ip.ticket_id, t.usable_occasions FROM " . $this->db->prefix() . $this->bbticketInvoicePrintingObj->table_element . " as ip
+		INNER JOIN " . $this->db->prefix() . $this->bbticketObj->table_element . " as t ON t.rowid = ip.ticket_id
+		WHERE ip.printing_date_timestamp = '{$this->printingTime}' AND ip.fk_facture = {$this->facture_id}";
+        $res = $this->db->query($sql);
+        while ($result = pg_fetch_assoc($res)) {
+            $tickets[$result['ticket_id']] = $result['usable_occasions'];
+        }
+        return $tickets;
+    }
+
+    public function checkExceptionHandlers($selectedTicket, $log, $logId)
+	{
+		$now = strtotime(date("Y-m-d H:i:s"));
+		if ($selectedTicket->usage == $selectedTicket->usable_occasions && $selectedTicket->usable_occasions != 0) {
+            ApiBbusLog::$log("{$logId} Out of usage!");
+			$this->ExceptionHandler(2, 'Out of usage!');
+		}
+
+		if ($selectedTicket->available_at < $now || ((!is_null($selectedTicket->expire_at) && !empty($selectedTicket->expire_at)) && $selectedTicket->expire_at < $now)) {
+            ApiBbusLog::$log("{$logId} Expired!");
+			$this->ExceptionHandler(1, 'Expired');
+		}
+
+	}
+
+    private function ExceptionHandler($status, $message)
+	{
+		$this->status = $status;
+		$this->saveBbTicketNaplo();
+		throw new RestException(401, $message);
+	}
+
+
+    private function saveAndCreateNaplo($sql)
+    {
+        $this->bbticketUpdate($sql);
+        $this->saveBbTicketNaplo();
+    }
+
+    private function bbticketUpdate($sql)
+    {
+        $updated = $this->db->query($sql);
+        if (!$updated) {
+            dol_syslog("Nem sikerult a ticketek updateje. facture_id: " . $this->facture_id, LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            throw new RestException(404, 'Update failed');
+        }
+    }
+
+    private function saveBbTicketNaplo()
+    {
+        global $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) {
+            print_r($bbTicketNaplo->error);exit;
+            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.');
+        }
+    }
+
+    public function setMergedTickets($selectedTicket, $log, $logId)
+    {
+        $this->bundle_id = $selectedTicket->bundle_id;
+        $sql = "SELECT merged_tickets FROM " . $this->db->prefix() . "product_extrafields WHERE fk_object = " . $this->bundle_id;
+        $result = $this->getDataFromDatabase($sql, "Product_extrafields");
+
+        while ($adatok = pg_fetch_assoc($result)) {
+            $this->merged_tickets = $adatok['merged_tickets'] == 1 ? true : false;
+            if($this->merged_tickets){
+                ApiBbusLog::$log("{$logId} Merged ticket");
+            }
+        }
+    }
+
+    public function checkBbTicketInvoicePrinting()
+    {
+        $result = $this->bbticketInvoicePrintingObj->fetchAll('', '', 0, 0, ['customsql' => "printing_date_timestamp = '{$this->printingTime}' AND fk_facture = {$this->facture_id} AND ticket_id = {$this->ticket_id}"]);
+        $this->checkResult($result, 'bbticketinvoiceprinting');
+    }
+
+    public function getDataOfTheSelectedTicket()
+    {
+        $result = $this->bbticketObj->fetchAll('ASC', 'rowid', 0, 0, ['customsql' => "rowid = {$this->ticket_id} AND fk_ticket IS NULL"]);
+        $this->checkResult($result, 'bbticket');
+
+        foreach ($result as $device) {
+            $selectedTicket = $device;
+        }
+        return $selectedTicket;
+    }
+
+    #_______________________________________________________________
+
+
+    private function getDataFromDatabase($sql, $name)
+    {
+        $res = $this->db->query($sql);
+        $this->checkValidation($res, $name);
+        return $res;
+    }
+
+    private function checkValidation($res, $name)
+    {
+        if (pg_num_rows($res) == 0) {
+            throw new RestException(404, $name . ' not found');
+        }
+    }
+
+    private function setId($result, $tableName, $variableName, $fieldName)
+    {
+        $this->checkResult($result, $tableName);
+        foreach ($result as $device) {
+            $this->$variableName = $device->$fieldName;
+        }
+    }
+
+    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}).");
+        }
+    }
+
+    public function getTicketTypeByProductId($product_id){
+        $productObj = new Product($this->db);
+        $result = $productObj->fetch($product_id);
+        if($result > 0){
+            $basicServicesObj = new BasicServices($this->db);
+            $resultBS = $basicServicesObj->fetch($productObj->array_options['options_basic_service']);
+            if($resultBS > 0){
+                return $basicServicesObj->server_host;
+            }
+        }else{
+            return false;
+        }
+    }
+}

+ 2 - 2
custom/booking/class/api_booking.class.php

@@ -874,7 +874,7 @@ class BookingApi extends DolibarrApi
 	{
 	{
 		ApiBbusLog::appLog("updateBbticket_________START");
 		ApiBbusLog::appLog("updateBbticket_________START");
 
 
-		global $user;
+		global $user, $conf;
 		$sql = "SELECT rowid FROM llx_bbus_bbticket WHERE fk_facture = {$invoice['id']}";
 		$sql = "SELECT rowid FROM llx_bbus_bbticket WHERE fk_facture = {$invoice['id']}";
 		ApiBbusLog::appLog("{$sql}");
 		ApiBbusLog::appLog("{$sql}");
 		$data = $this->db->query($sql);
 		$data = $this->db->query($sql);
@@ -893,7 +893,7 @@ class BookingApi extends DolibarrApi
 			}
 			}
 		} else {
 		} else {
 			ApiBbusLog::appLog("{$this->db->error()}");
 			ApiBbusLog::appLog("{$this->db->error()}");
-			ApiBbusLog::appLog("api_booking (Excelia): updateBbticket error");
+			ApiBbusLog::appLog("api_booking ({$conf->global->LOCAL_SERVER_HOST}): updateBbticket error");
 		}
 		}
 	}
 	}
 
 

+ 0 - 1
custom/financialreport/class/helper.class.php

@@ -1479,7 +1479,6 @@ class HelperUserInvoice
             }
             }
         }
         }
         $invocesRowidString = implode(',', $arraytmp);
         $invocesRowidString = implode(',', $arraytmp);
-        //print $invocesRowidString;
         return $invocesRowidString;
         return $invocesRowidString;
     }
     }
 
 

+ 1993 - 0
custom/financialreport/class/helper.class.php.bak

@@ -0,0 +1,1993 @@
+<?php
+
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
+use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
+use PhpOffice\PhpSpreadsheet\Style\Alignment;
+
+require_once DOL_DOCUMENT_ROOT . '/includes/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Spreadsheet.php';
+require_once DOL_DOCUMENT_ROOT . '/includes/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/settlements/class/usernaplo.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/settlements/class/hotel.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/settlements/class/group.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/commissionhandler.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/api_curl.class.php';
+
+
+
+class HelperUserInvoice
+{
+    use CurlApi;
+
+    public $db;
+
+    public function __construct(DoliDB $db)
+    {
+        $this->db = $db;
+        $this->userCategoryArray = [1 => "sales / kereskedő", 2 => "office / irodai dolgozó", 3 => "management / vezetőség", 4 => "maintenance / szerelő", 5 => "host(ess) / buszkísérő", 6 => "accounts / elszámolók", 7 => "hotelsales"];
+    }
+    /**
+     * Output the buttons to submit a creation/edit form
+     *
+     * @param   string  $save_label     	Alternative label for save button
+     * @param   string  $cancel_label   	Alternative label for cancel button
+     * @param   array   $morebuttons    	Add additional buttons between save and cancel
+     * @param   bool    $withoutdiv     	Option to remove enclosing centered div
+     * @param	string	$morecss			More CSS
+     * @param	string	$dol_openinpopup	If the button are shown in a context of a page shown inside a popup, we put here the string name of popup.
+     * @return 	string						Html code with the buttons
+     */
+    public function buttonsSaveCancel($save_label = 'Save', $cancel_label = 'Cancel', $cancelURL = '', $morebuttons = array(), $withoutdiv = 0, $morecss = '', $dol_openinpopup = '')
+    {
+        global $langs;
+
+        $buttons = array();
+
+        $save = array(
+            'name' => 'save',
+            'label_key' => $save_label,
+        );
+
+        if ($save_label == 'Create' || $save_label == 'Add') {
+            $save['name'] = 'add';
+        } elseif ($save_label == 'Modify') {
+            $save['name'] = 'edit';
+        }
+
+        $cancel = array(
+            'name' => 'cancel',
+            'label_key' => 'Cancel',
+        );
+
+        !empty($save_label) ? $buttons[] = $save : '';
+
+        if (!empty($morebuttons)) {
+            $buttons[] = $morebuttons;
+        }
+
+        //!empty($cancel_label) ? $buttons[] = $cancel : '';
+
+        $retstring = $withoutdiv ? '' : '<div class="center">';
+
+        foreach ($buttons as $button) {
+            $addclass = empty($button['addclass']) ? '' : $button['addclass'];
+            $retstring .= '<input type="submit" class="button button-' . $button['name'] . ($morecss ? ' ' . $morecss : '') . ' ' . $addclass . '" name="' . $button['name'] . '" value="' . dol_escape_htmltag($langs->trans($button['label_key'])) . '">';
+        }
+
+        if ($cancel_label == "Cancel") {
+            $retstring .= '<a class="button button-' . $cancel['name'] . '" href="' . dol_buildpath($cancelURL, 1) . /*'?restore_lastsearch_values=1' .*/ (!empty($socid) ? '&socid=' . $socid : '') . '">' . $langs->trans($cancel['label_key']) . '</a>';
+        }
+
+        $retstring .= $withoutdiv ? '' : '</div>';
+
+        if ($dol_openinpopup) {
+            $retstring .= '<!-- buttons are shown into a $dol_openinpopup=' . $dol_openinpopup . ' context, so we enable the close of dialog on cancel -->' . "\n";
+            $retstring .= '<script>';
+            $retstring .= 'jQuery(".button-cancel").click(function(e) {
+				e.preventDefault(); console.log(\'We click on cancel in iframe popup ' . $dol_openinpopup . '\');
+				window.parent.jQuery(\'#idfordialog' . $dol_openinpopup . '\').dialog(\'close\');
+				 });';
+            $retstring .= '</script>';
+        }
+
+        return $retstring;
+    }
+
+    function getAllSales($userObj)
+    {
+        $salesUsers = [];
+        $sql = "SELECT u.rowid, u.lastname, u.firstname, u.login, ue.nickname FROM " . MAIN_DB_PREFIX . "user AS u LEFT JOIN " . MAIN_DB_PREFIX . "user_extrafields AS ue ON u.rowid = ue.fk_object WHERE ue.user_category = '1' ORDER BY u.lastname";
+        $result = $this->db->query($sql);
+        while ($row = pg_fetch_assoc($result)) {
+            $salesUsers[] = $row;
+        }
+        return $salesUsers;
+    }
+
+    function getAllSalesWithSQL($sql)
+    {
+        $salesUsers = [];
+        $result = $this->db->query($sql);
+        if ($this->db->num_rows($result) > 0) {
+            while ($row = pg_fetch_assoc($result)) {
+                $salesUsers[] = $row;
+            }
+        }
+        return $salesUsers;
+    }
+
+    private function getAllPaymenttype($user_id, $db, $payment_type)
+    {
+        $sql = "SELECT 'HUF' AS type,
+        SUM(amount) AS amount
+        FROM " . MAIN_DB_PREFIX . "financialreport_userinvoice
+        WHERE payment_type = {$payment_type} AND user_id = {$user_id} AND currency = 0";
+        if ($payment_type != 1) {
+            $sql .= " AND payed = 1";
+        }
+        /* $sql .= "UNION ALL
+        SELECT 'EUR' AS type,
+        SUM(amount) AS amount
+        FROM " . MAIN_DB_PREFIX . "financialreport_userinvoice
+        WHERE payment_type = {$payment_type} AND user_id = {$user_id} AND currency = 1"; */
+        if ($payment_type != 1) {
+            $sql .= " AND payed = 1";
+        }
+        $resultUserdata = $db->query($sql);
+        return pg_fetch_all($resultUserdata);
+    }
+
+    function getAllCommissions($user_id, $db)
+    {
+        $sql = "SELECT 'HUF' AS type,
+        SUM(amount) AS amount
+        FROM " . MAIN_DB_PREFIX . "financialreport_userinvoice
+        WHERE payment_type = 2 AND user_id = {$user_id} AND currency = 0
+        UNION ALL
+        SELECT 'EUR' AS type,
+        SUM(amount) AS amount
+        FROM " . MAIN_DB_PREFIX . "financialreport_userinvoice
+        WHERE payment_type = 2 AND user_id = {$user_id} AND currency = 1";
+        $resultUserdata = $db->query($sql);
+        return pg_fetch_all($resultUserdata);
+    }
+
+    function getAllUnpaidCommissions($user_id, $db)
+    {
+        $sql = "SELECT 'HUF' AS type,
+        SUM(amount) AS amount
+        FROM " . MAIN_DB_PREFIX . "financialreport_userinvoice
+        WHERE payment_type = 2 AND user_id = {$user_id} AND currency = 0 AND payed=0
+        UNION ALL
+        SELECT 'EUR' AS type,
+        SUM(amount) AS amount
+        FROM " . MAIN_DB_PREFIX . "financialreport_userinvoice
+        WHERE payment_type = 2 AND user_id = {$user_id} AND currency = 1 AND payed=0";
+        $resultUserdata = $db->query($sql);
+        return pg_fetch_all($resultUserdata);
+    }
+
+    function getAllMinusInvoice($user_id, $db)
+    {
+        $sql = "SELECT 'HUF' AS type,
+        SUM(amount) AS amount
+        FROM " . MAIN_DB_PREFIX . "financialreport_userinvoice
+        WHERE user_id = {$user_id} AND currency = 0 AND payed=0
+        UNION ALL
+        SELECT 'EUR' AS type,
+        SUM(amount) AS amount
+        FROM " . MAIN_DB_PREFIX . "financialreport_userinvoice
+        WHERE user_id = {$user_id} AND currency = 1 AND payed=0";
+        $resultUserdata = $db->query($sql);
+        return pg_fetch_all($resultUserdata);
+    }
+
+    function createArray($daterange)
+    {
+        $dates = explode(" - ", $daterange);
+        $startDate = new DateTime($dates[0]);
+        $endDate = new DateTime($dates[1]);
+
+        $dateArray = array();
+
+        $currentDate = clone $startDate;
+        while ($currentDate <= $endDate) {
+            $dateArray[] = $currentDate->format('Y-m-d');
+            $currentDate->modify('+1 day');
+        }
+
+        return $dateArray;
+    }
+
+    function getMonths()
+    {
+        global $langs;
+        if ($langs->shortlang == 'hu') {
+            return array(
+                "01" => "Január",
+                "02" => "Február",
+                "03" => "Március",
+                "04" => "Április",
+                "05" => "Május",
+                "06" => "Június",
+                "07" => "Július",
+                "08" => "Augusztus",
+                "09" => "Szeptember",
+                "10" => "Október",
+                "11" => "November",
+                "12" => "December"
+            );
+        } else {
+            return array(
+                "01" => "January",
+                "02" => "February",
+                "03" => "March",
+                "04" => "April",
+                "05" => "May",
+                "06" => "June",
+                "07" => "July",
+                "08" => "August",
+                "09" => "September",
+                "10" => "Octóber",
+                "11" => "November",
+                "12" => "December"
+            );
+        }
+    }
+
+    function selectedMonths($year, $months, $honapok)
+    {
+        $selectedmonths = $year . ' - ';
+        $count = count($months);
+        $i = 1;
+        foreach ($months as $month) {
+            $selectedmonths .= $honapok[$month];
+            if ($i < $count)
+                $selectedmonths .= ', ';
+            $i++;
+        }
+        return $selectedmonths;
+    }
+
+    private function getDateIntervalForExcel($year, $months)
+    {
+        $intervalArray = [];
+        $from = $year . '-' . $months[0];
+        $to = $year . '-' . end($months);
+    }
+
+    private function createStartDateForQuery($year, $month)
+    {
+        return $year . '-' . $month . '-' . '01 00:00:00';
+    }
+
+    private function createEndDateForQuery($year, $month)
+    {
+        $lastDayOfTheMonth = $this->getLastDayOfTheMonth($year, $month);
+        return $year . '-' . $month . '-' . $lastDayOfTheMonth . ' 23:59:59';
+    }
+
+    private function getLastDayOfTheMonth($year, $month)
+    {
+        $lastDay = date("t", strtotime("$year-$month-01"));
+        return $lastDay;
+    }
+
+
+    function createExcel($year, $months, $honapok)
+    {
+        $spreadsheet = new Spreadsheet();
+
+        $felirat = $this->selectedMonths($year, $months, $honapok);
+        $start_date = $this->createStartDateForQuery($year, min($months));
+        $end_date = $this->createEndDateForQuery($year, max($months));
+        //$dateInterval = $this->getDateIntervalForExcel($year, $months);
+        $sql = "SELECT CONCAT(u.lastname, ' ', u.firstname) AS name, u.login, ue.tax_identification_number,
+            COALESCE(login_count.record_count, 0) AS ledolgozott_napok_szama,
+            COALESCE(payment_count_huf.total_amount_huf, 0) AS kifizetett_osszeg_huf
+            /*COALESCE(payment_count_eur.total_amount_eur, 0) AS kifizetett_osszeg_eur*/
+                FROM " . MAIN_DB_PREFIX . "user AS u
+            INNER JOIN " . MAIN_DB_PREFIX . "user_extrafields as ue ON ue.fk_object = u.rowid
+            LEFT JOIN (
+                SELECT user_id, COUNT(DISTINCT DATE(date_creation)) AS record_count
+                FROM " . MAIN_DB_PREFIX . "bbus_userloginnaplo
+                WHERE date_creation BETWEEN '{$start_date}' AND '{$end_date}'
+                GROUP By user_id
+            ) AS login_count ON u.rowid = login_count.user_id
+            LEFT JOIN (
+                SELECT user_id, SUM(amount) AS total_amount_huf
+                FROM " . MAIN_DB_PREFIX . "financialreport_userinvoice
+                WHERE payment_type = 2 AND payed = 1 AND currency = 0 AND paymentdate BETWEEN '{$start_date}' AND '{$end_date}'
+                GROUP BY user_id
+            ) AS payment_count_huf ON u.rowid = payment_count_huf.user_id
+            /*LEFT JOIN (
+                SELECT user_id, SUM(amount) AS total_amount_eur
+                FROM " . MAIN_DB_PREFIX . "financialreport_userinvoice
+                WHERE payment_type = 2 AND payed = 1 AND currency = 1 AND paymentdate BETWEEN '{$start_date}' AND '{$end_date}'
+                GROUP BY user_id
+            ) AS payment_count_eur ON u.rowid = payment_count_eur.user_id*/
+            WHERE ue.user_category = '1'
+            ORDER BY name ASC;
+            ";
+        $resultUserdata = $this->db->query($sql);
+        $allUsers = pg_fetch_all($resultUserdata);
+
+        $sheet = $spreadsheet->getActiveSheet();
+        $sheet->setTitle("{$felirat}");
+        $sheet->setCellValue("A1", "Felhasználó");
+        $sheet->setCellValue("B1", "Login");
+        $sheet->setCellValue("C1", "Adóazonosító jel");
+        $sheet->setCellValue("D1", "Ledolgozott napok száma");
+        $sheet->setCellValue("E1", "Kifizetett jutalék HUF");
+        /*$sheet->setCellValue("F1", "Kifizetett jutalék EUR");*/
+
+        $i = 2;
+        foreach ($allUsers as $user) {
+            $sheet->setCellValue("A" . $i, $user['name']);
+            $sheet->setCellValue("B" . $i, $user['login']);
+            $sheet->setCellValue("C" . $i, $user['tax_identification_number']);
+            $sheet->setCellValue("D" . $i, $user['ledolgozott_napok_szama']);
+            $sheet->setCellValue("E" . $i, $user['kifizetett_osszeg_huf'] . ' HUF');
+            /*$sheet->setCellValue("F" . $i, $user['kifizetett_osszeg_eur'] . ' EUR');*/
+            $i++;
+        }
+        //$sheet->setCellValue("A1", "Hello World!");
+        //$sheet->setCellValue("A1", "Hello World!");
+        //$sheet->setCellValue("A2", "Goodbye World!");
+
+        // (D) ADD NEW WORKSHEET + YOU CAN ALSO USE FORMULAS!
+        /* $spreadsheet->createSheet();
+        $sheet = $spreadsheet->getSheet(1);
+        $sheet->setTitle("Formula");
+        $sheet->setCellValue("A1", "5");
+        $sheet->setCellValue("A2", "6");
+        $sheet->setCellValue("A3", "=SUM(A1:A2)"); */
+
+        $date = date('d-m-y-' . substr((string) microtime(), 1, 8));
+        $date = str_replace(".", "", $date);
+        $filename = "export_" . $date . ".xlsx";
+
+        try {
+            $writer = new Xlsx($spreadsheet);
+            $writer->save($filename);
+            $content = file_get_contents($filename);
+        } catch (Exception $e) {
+            exit($e->getMessage());
+        }
+
+        header("Content-Disposition: attachment; filename=" . $filename);
+        unlink($filename);
+        exit($content);
+    }
+
+    function createExcelInterval($daterange)
+    {
+        $spreadsheet = new Spreadsheet();
+
+        $felirat = $daterange;
+        $rangeArray = explode(' - ', $daterange);
+        $start_date = $rangeArray[0] . ' 00:00:00';
+        $end_date = $rangeArray[1] . ' 23:59:59';
+        //$dateInterval = $this->getDateIntervalForExcel($year, $months);
+        $sql = "SELECT CONCAT(u.lastname, ' ', u.firstname) AS name, u.login, ue.tax_identification_number,
+            COALESCE(login_count.record_count, 0) AS ledolgozott_napok_szama,
+            COALESCE(payment_count_huf.total_amount_huf, 0) AS kifizetett_osszeg_huf
+            /*COALESCE(payment_count_eur.total_amount_eur, 0) AS kifizetett_osszeg_eur*/
+                FROM " . MAIN_DB_PREFIX . "user AS u
+            INNER JOIN " . MAIN_DB_PREFIX . "user_extrafields as ue ON ue.fk_object = u.rowid
+            LEFT JOIN (
+                SELECT user_id, COUNT(DISTINCT DATE(date_creation)) AS record_count
+                FROM " . MAIN_DB_PREFIX . "bbus_userloginnaplo
+                WHERE date_creation BETWEEN '{$start_date}' AND '{$end_date}'
+                GROUP By user_id
+            ) AS login_count ON u.rowid = login_count.user_id
+            LEFT JOIN (
+                SELECT user_id, SUM(amount) AS total_amount_huf
+                FROM " . MAIN_DB_PREFIX . "financialreport_userinvoice
+                WHERE payment_type = 2 AND payed = 1 AND currency = 0 AND paymentdate BETWEEN '{$start_date}' AND '{$end_date}'
+                GROUP BY user_id
+            ) AS payment_count_huf ON u.rowid = payment_count_huf.user_id
+            /*LEFT JOIN (
+                SELECT user_id, SUM(amount) AS total_amount_eur
+                FROM " . MAIN_DB_PREFIX . "financialreport_userinvoice
+                WHERE payment_type = 2 AND payed = 1 AND currency = 1 AND paymentdate BETWEEN '{$start_date}' AND '{$end_date}'
+                GROUP BY user_id
+            ) AS payment_count_eur ON u.rowid = payment_count_eur.user_id*/
+            WHERE ue.user_category = '1'
+            ORDER BY name ASC;
+            ";
+        $resultUserdata = $this->db->query($sql);
+        $allUsers = pg_fetch_all($resultUserdata);
+
+        $sheet = $spreadsheet->getActiveSheet();
+        $sheet->setTitle("{$felirat}");
+        $sheet->setCellValue("A1", "Felhasználó");
+        $sheet->setCellValue("B1", "Login");
+        $sheet->setCellValue("C1", "Adóazonosító jel");
+        $sheet->setCellValue("D1", "Ledolgozott napok száma");
+        $sheet->setCellValue("E1", "Kifizetett jutalék HUF");
+        //$sheet->setCellValue("F1", "Kifizetett jutalék EUR");
+
+        $i = 2;
+        foreach ($allUsers as $user) {
+            $sheet->setCellValue("A" . $i, $user['name']);
+            $sheet->setCellValue("B" . $i, $user['login']);
+            $sheet->setCellValue("C" . $i, $user['tax_identification_number']);
+            $sheet->setCellValue("D" . $i, $user['ledolgozott_napok_szama']);
+            $sheet->setCellValue("E" . $i, $user['kifizetett_osszeg_huf'] . ' HUF');
+            //  $sheet->setCellValue("F" . $i, $user['kifizetett_osszeg_eur'] . ' EUR');
+            $i++;
+        }
+        //$sheet->setCellValue("A1", "Hello World!");
+        //$sheet->setCellValue("A1", "Hello World!");
+        //$sheet->setCellValue("A2", "Goodbye World!");
+
+        // (D) ADD NEW WORKSHEET + YOU CAN ALSO USE FORMULAS!
+        /* $spreadsheet->createSheet();
+        $sheet = $spreadsheet->getSheet(1);
+        $sheet->setTitle("Formula");
+        $sheet->setCellValue("A1", "5");
+        $sheet->setCellValue("A2", "6");
+        $sheet->setCellValue("A3", "=SUM(A1:A2)"); */
+
+        $date = date('d-m-y-' . substr((string) microtime(), 1, 8));
+        $date = str_replace(".", "", $date);
+        $filename = "export_" . $date . ".xlsx";
+
+        try {
+            $writer = new Xlsx($spreadsheet);
+            $writer->save($filename);
+            $content = file_get_contents($filename);
+        } catch (Exception $e) {
+            exit($e->getMessage());
+        }
+
+        header("Content-Disposition: attachment; filename=" . $filename);
+        unlink($filename);
+        exit($content);
+    }
+
+    function createExcelHotelReport($daterange, $id, $entity, $groups)
+    {
+        $spreadsheet = new Spreadsheet();
+        $usersList = $this->getUsersOfHotelGroup($id, $daterange, $entity);
+        $felirat = $daterange;
+        $usersIdList = $this->getUsersIdList($id, $daterange, $entity);
+        $amountHUF = $this->getAllAmountInPeriod($id, $daterange, 'HUF', $usersIdList, $entity);
+        $amountEUR = $this->getAllAmountInPeriod($id, $daterange, 'EUR', $usersIdList, $entity);
+        $commissionHUF = $this->getAllCommissionInPeriod($id, $daterange, 'HUF', $usersIdList, $entity);
+        $commissionEUR = $this->getAllCommissionInPeriod($id, $daterange, 'EUR', $usersIdList, $entity);
+        $hotelsArray = $this->getAllHotels();
+        $hotelName = $hotelsArray[$groups[$id]['fk_hotel_id']];
+
+        $style = [
+            'alignment' => [
+                'horizontal' => Alignment::HORIZONTAL_CENTER, // Vízszintes középre igazítás
+                'vertical' => Alignment::VERTICAL_CENTER,     // Függőleges középre igazítás
+            ],
+        ];
+
+        $styleBold = [
+            'font' => [
+                'bold' => true,
+            ],
+        ];
+
+        $sheet = $spreadsheet->getActiveSheet();
+        $sheet->getStyle('A1')->applyFromArray($styleBold);
+        $sheet->getStyle('A3:B3')->applyFromArray($styleBold);
+        $sheet->getStyle('A7')->applyFromArray($styleBold);
+        $sheet->getStyle('A9:D9')->applyFromArray($styleBold);
+        $sheet->getStyle('A1:D9')->applyFromArray($style);
+        $sheet->setTitle("{$felirat}");
+        $sheet->getColumnDimension('A')->setWidth(25);
+        $sheet->getColumnDimension('B')->setWidth(25);
+        $sheet->getColumnDimension('C')->setWidth(25);
+        $sheet->getColumnDimension('D')->setWidth(25);
+        $sheet->setCellValue("A1", strtoupper($hotelName));
+        $sheet->mergeCells("A1:B1");
+        $sheet->setCellValue("A2", $daterange);
+        $sheet->mergeCells("A2:B2");
+        $sheet->setCellValue("A3", "INCOMES");
+        $sheet->setCellValue("B3", "COMMISSIONS");
+        $sheet->setCellValue("A4", $this->correctNumber($amountHUF) . ' HUF');
+        $sheet->setCellValue("B4", $this->correctNumber($commissionHUF) . ' HUF');
+        $sheet->setCellValue("A5", $this->correctNumber($amountEUR) . ' EUR');
+        $sheet->setCellValue("B5", $this->correctNumber($commissionEUR) . ' EUR');
+        $sheet->setCellValue("A6", "");
+        $sheet->setCellValue("B6", "");
+
+        $sheet->setCellValue("A7", strtoupper($hotelName));
+        $sheet->mergeCells("A7:D7");
+        $sheet->setCellValue("A8", $daterange);
+        $sheet->mergeCells("A8:D8");
+        $sheet->setCellValue("A9", "USER");
+        $sheet->setCellValue("B9", "GROUP");
+        $sheet->setCellValue("C9", "AMOUNT OF SALES");
+        $sheet->setCellValue("D9", "AMOUNT OF SALES");
+
+        $i = 10;
+        foreach ($usersList as $userVal) {
+            $sheet->setCellValue("A" . $i, $userVal['firstname'] . ' ' . $userVal['lastname']);
+            $sheet->setCellValue("B" . $i, ' (' . $this->userCategoryArray[$userVal['user_category']] . ')');
+            $sheet->setCellValue("C" . $i, $this->correctNumber($this->getAllAmountInPeriod($id, $daterange, 'HUF', $userVal['rowid'], $entity)) . ' HUF');
+            $sheet->setCellValue("D" . $i, $this->correctNumber($this->getAllAmountInPeriod($id, $daterange, 'EUR', $userVal['rowid'], $entity)) . ' EUR');
+            $i++;
+        }
+        $sheet->getStyle('C10:C' . $i)->applyFromArray($style);
+        $sheet->getStyle('D10:D' . $i)->applyFromArray($style);
+        //$sheet->setCellValue("A1", "Hello World!");
+        //$sheet->setCellValue("A1", "Hello World!");
+        //$sheet->setCellValue("A2", "Goodbye World!");
+
+        // (D) ADD NEW WORKSHEET + YOU CAN ALSO USE FORMULAS!
+        /* $spreadsheet->createSheet();
+        $sheet = $spreadsheet->getSheet(1);
+        $sheet->setTitle("Formula");
+        $sheet->setCellValue("A1", "5");
+        $sheet->setCellValue("A2", "6");
+        $sheet->setCellValue("A3", "=SUM(A1:A2)"); */
+
+        $date = date('d-m-y-' . substr((string) microtime(), 1, 8));
+        $date = str_replace(".", "", $date);
+        $filename = "hotelexport_" . $hotelName . '_' . $date . ".xlsx";
+
+        try {
+            $writer = new Xlsx($spreadsheet);
+            $writer->save($filename);
+            $content = file_get_contents($filename);
+        } catch (Exception $e) {
+            exit($e->getMessage());
+        }
+
+        header("Content-Disposition: attachment; filename=" . $filename);
+        unlink($filename);
+        exit($content);
+    }
+
+    function createExcelMonthlyExport($daterange, $entity, $saledTickets)
+    {
+        $spreadsheet = new Spreadsheet();
+        $felirat = $daterange;
+        $entities = $this->getAllEntities();
+
+        $entityName = str_replace(" ", "_", $entities[$entity]);
+        $entityName = str_replace(".", "_", $entityName);
+
+        $style = [
+            'alignment' => [
+                'horizontal' => Alignment::HORIZONTAL_CENTER, // Vízszintes középre igazítás
+                'vertical' => Alignment::VERTICAL_CENTER,     // Függőleges középre igazítás
+            ],
+        ];
+
+        $styleBold = [
+            'font' => [
+                'bold' => true,
+            ],
+        ];
+
+        $sheet = $spreadsheet->getActiveSheet();
+        $sheet->getStyle('A1')->applyFromArray($styleBold);
+        $sheet->getStyle('A3:P3')->applyFromArray($styleBold);
+        //$sheet->getStyle('A7')->applyFromArray($styleBold);
+        //$sheet->getStyle('A9:D9')->applyFromArray($styleBold);
+        //$sheet->getStyle('A1:D9')->applyFromArray($style);
+        $sheet->setTitle("{$felirat}");
+        $sheet->getColumnDimension('A')->setWidth(20);
+        $sheet->getColumnDimension('B')->setWidth(20);
+        $sheet->getColumnDimension('C')->setWidth(20);
+        $sheet->getColumnDimension('D')->setWidth(20);
+        $sheet->getColumnDimension('E')->setWidth(20);
+        $sheet->getColumnDimension('F')->setWidth(20);
+        $sheet->getColumnDimension('G')->setWidth(15);
+        $sheet->getColumnDimension('H')->setWidth(15);
+        $sheet->getColumnDimension('I')->setWidth(15);
+        $sheet->getColumnDimension('J')->setWidth(15);
+        $sheet->getColumnDimension('K')->setWidth(15);
+        $sheet->getColumnDimension('L')->setWidth(15);
+        $sheet->getColumnDimension('M')->setWidth(10);
+        $sheet->getColumnDimension('N')->setWidth(15);
+        $sheet->getColumnDimension('O')->setWidth(10);
+        $sheet->getColumnDimension('P')->setWidth(10);
+        $sheet->setCellValue("A1", strtoupper($entities[$entity]));
+        $sheet->mergeCells("A1:B1");
+        $sheet->setCellValue("A2", $daterange);
+        $sheet->mergeCells("A2:B2");
+        $sheet->setCellValue("A3", "Facture");
+        $sheet->setCellValue("B3", "Type");
+        $sheet->setCellValue("C3", "Environment");
+        $sheet->setCellValue("D3", "VATnumber");
+        $sheet->setCellValue("E3", "Creation date");
+        $sheet->setCellValue("F3", "Completion date");
+        $sheet->setCellValue("G3", "Payment deadline");
+        $sheet->setCellValue("H3", "Net");
+        $sheet->setCellValue("I3", "VAT");
+        $sheet->setCellValue("J3", "Gross");
+        $sheet->setCellValue("K3", "Net");
+        $sheet->setCellValue("L3", "VAT");
+        $sheet->setCellValue("M3", "Gross");
+        $sheet->setCellValue("N3", "Currency");
+        $sheet->setCellValue("O3", "PaymentMethod");
+        $sheet->setCellValue("P3", "VAT  %");
+        $i = 4;
+
+        foreach ($saledTickets as $item) {
+            $mtht = $item->multicurrency_total_ht == $item->total_ht ? '' : number_format($item->multicurrency_total_ht, 4, ',', ' ');
+            $mttva = $item->multicurrency_total_tva == $item->total_tva ? '' : number_format($item->multicurrency_total_ht, 4, ',', ' ');
+            $mtttc = $item->multicurrency_total_ttc == $item->total_ttc ? '' : number_format($item->multicurrency_total_ttc, 4, ',', ' ');
+            $sheet->setCellValue("A" . $i, $item->ref);
+            $sheet->setCellValue("B" . $i, $this->getFectureType($item->type));
+            $sheet->setCellValue("C" . $i, $item->label);
+            $sheet->setCellValue("D" . $i, $item->value);
+            $sheet->setCellValue("E" . $i, $item->datef);
+            $sheet->setCellValue("F" . $i, $item->date_lim_reglement);
+            $sheet->setCellValue("G" . $i, $item->datef);
+            $sheet->setCellValue("H" . $i, number_format($item->total_ht, 4, ',', ' '));
+            $sheet->setCellValue("I" . $i, number_format($item->total_tva, 4, ',', ' '));
+            $sheet->setCellValue("J" . $i, number_format($item->total_ttc, 4, ',', ' '));
+            $sheet->setCellValue("K" . $i, $mtht);
+            $sheet->setCellValue("L" . $i, $mttva);
+            $sheet->setCellValue("M" . $i, $mtttc);
+            $sheet->setCellValue("N" . $i, $item->multicurrency_code);
+            $sheet->setCellValue("O" . $i, $item->libelle);
+            $sheet->setCellValue("P" . $i, number_format($item->tva_tx, 0) . ' %');
+            $i++;
+        }
+
+        ## file name
+        $date = date('d-m-y-' . substr((string) microtime(), 1, 8));
+        $date = str_replace(".", "", $date);
+        $filename = "monthlyexport_" . $entityName . '_' . $date . ".xlsx";
+
+        try {
+            $writer = new Xlsx($spreadsheet);
+            $writer->save($filename);
+            $content = file_get_contents($filename);
+        } catch (Exception $e) {
+            exit($e->getMessage());
+        }
+
+        header("Content-Disposition: attachment; filename=" . $filename);
+        unlink($filename);
+        exit($content);
+    }
+
+    function getTypeOfPayment($payment_type)
+    {
+        switch ($payment_type) {
+            case '0':
+                return 'prepay';
+            case '1':
+                return 'withhold';
+            case '2':
+                return 'commission';
+            default:
+                return 'prepay';
+        }
+    }
+
+    function getFectureType($type)
+    {
+        global $langs;
+        switch ($type) {
+            case '0':
+                return $langs->trans("Invoice");
+            case '2':
+                return $langs->trans("CreditNote");
+            case '7':
+                return $langs->trans("Receipt");
+            case '8':
+                return $langs->trans("ReceiptCreditNote");
+        }
+    }
+
+    function getTitle($payment_type)
+    {
+        global $langs;
+        switch ($payment_type) {
+            case '0':
+                return $langs->trans("UserInvoices");
+            case '1':
+                return $langs->trans("Withhold");
+            case '2':
+                return $langs->trans("Commissionpaidamount");
+            default:
+                return $langs->trans("UserInvoices");
+        }
+    }
+
+    function getViewTplTitle($payment_type)
+    {
+        global $langs;
+        switch ($payment_type) {
+            case '0':
+                return $langs->trans("Deposit");
+            case '1':
+                return $langs->trans("WithheldAmount");
+            case '2':
+                return $langs->trans("Commissionpaidamount");
+            default:
+                return $langs->trans("Deposit");
+        }
+    }
+
+    function backPageSelector($payment_type)
+    {
+        switch ($payment_type) {
+            case '0':
+                return 'prepaymentsindex';
+            case '1':
+                return 'withholdingindex';
+            case '2':
+                return 'commissionindex';
+            default:
+                return 'prepaymentsindex';
+        }
+    }
+
+    function createHTML($id)
+    {
+        $currencies = ['0' => 'HUF', '1' => 'EUR'];
+
+        $sql = "SELECT user1.lastname as creatorlastname, user1.firstname as creatorfirstname, user1.login as creatorlogin, user2.lastname as lastname, user2.firstname as firstname, user2.login as userlogin, ui.amount, ui.currency, ui.paymentdate FROM " . MAIN_DB_PREFIX . "financialreport_userinvoice as ui
+        INNER JOIN " . MAIN_DB_PREFIX . "user AS user1 ON user1.rowid = ui.fk_user_creat
+        INNER JOIN " . MAIN_DB_PREFIX . "user AS user2 ON user2.rowid = ui.user_id
+        WHERE ui.rowid={$id}";
+        //print $sql;
+
+        $resultUserdata = $this->db->query($sql);
+        $UserInvoice = pg_fetch_assoc($resultUserdata);
+
+        $result = '<table style="width:100%"><tr><td><b>Átadó adatai <br>Donor / Giver user data</b></td><td style="text-align: right;"><b>Átvevő adatai <br>Receiving user data</b></td></tr>';
+        $result .= '<div>&nbsp;</div>';
+        $result .= '<tr><td>' . $UserInvoice['creatorlastname'] . ' ' . $UserInvoice['creatorfirstname'] . ' - ' . $UserInvoice['creatorlogin'] . '</td><td  style="text-align: right;">' . $UserInvoice['lastname'] . ' ' . $UserInvoice['firstname'] . ' - ' . $UserInvoice['userlogin'] . '</td></tr></table>';
+        $result .= '<div style="padding-top: 100px;">&nbsp;</div>';
+        $result .= '<table style="width:100%">';
+        $result .= '<tr><td style="width:75%">Jutalék összege / Amount of commission: </td><td style="text-align: right; width:20%;">' . number_format($UserInvoice['amount'], 0, '.', ' ') . '</td></tr>';
+        $result .= '<tr><td style="width:75%">Jutalék pénznem / Amount of currency: </td><td style="text-align: right; width:20%;">' . $currencies[$UserInvoice['currency']] . '</td></tr>';
+        $result .= '</table>';
+        $result .= '<div style="padding-top: 100px;">&nbsp;</div>';
+        $result .= '<div style="width:100%; text-align: left;">Budapest, Bajcsy-Zsilinszky út 17, 1065</div>';
+        $result .= '<div style="width:100%; text-align: left;">' . $UserInvoice['paymentdate'] . '</div>';
+        $result .= '<div style="padding-top: 100px;">&nbsp;</div>';
+        $result .= '<table style="width:100%; text-align:right;">';
+        $result .= '</table>';
+        $result .=
+            '<table style="width:100%">
+            <tr>
+                <td>_________________________________</td>
+                <td>_________________________________</td>
+            </tr>
+            <tr>
+                <td style="text-align: center;">Átadó aláírása <br> (Donor / Giver)</td>
+                <td style="text-align: center;">Átvevő aláírása <br>  (Recipient / Receiver)</td>
+            </tr>
+        </table>';
+        return $result;
+    }
+
+    function createHTMLForSettlement($dataArray)
+    {
+        $result = '
+        <table style="width:100%; text-align: center;">
+            <tr style="font-weight: bold;">
+                <td>Jutalék / Commisson</td>
+            </tr>
+            <tr><td>&nbsp;</td></tr>
+            <tr style="background-color:lightgrey; font-weight: bold;">
+                <td>Name of group</td>
+            </tr>
+            <tr>
+                <td>' . $dataArray['GroupName'] . '</td>
+            </tr>
+            <tr><td>&nbsp;</td></tr>
+            <tr style="background-color:lightgrey; font-weight: bold;">
+                <td>Interval</td>
+            </tr>
+            <tr>
+                <td>' . $dataArray['Interval'] . '</td>
+            </tr>
+            <tr><td>&nbsp;</td></tr>
+            <tr style="background-color:lightgrey; font-weight: bold;">
+                <td>Total amount</td>
+            </tr>
+            <tr>
+                <td>' . $dataArray['FullAmount'] . ' HUF</td>
+            </tr>
+            <tr><td>&nbsp;</td></tr>
+
+            <tr style="background-color:lightgrey; font-weight: bold;">
+                <td>Data of Users</td>
+            </tr>
+        </table>';
+        $result .= '
+        <table>';
+        foreach ($dataArray['UsersData'] as $userdata) {
+            $result .= '<tr><td style="font-weight: bold;">User: </td><td style="font-style: italic;">' . $userdata['namedata'] . '</td></tr>';
+            $result .= '<tr><td style="font-weight: bold;">Amount: </td><td style="font-style: italic;">' . $userdata['amount'] . ' HUF</td></tr>';
+            //$result .= '<tr><td style="font-weight: bold;">Invoices: </td><td style="font-style: italic;">' . $userdata['invoices'] . '</td></tr>';
+            $result .= '<tr><td>&nbsp;</td><td>&nbsp;</td></tr>';
+        }
+        $result .= '</table>';
+        return $result;
+    }
+
+    function checkinterval($db)
+    {
+
+        $id = GETPOST('id', 'int');
+        $interval_startyear = GETPOST('interval_startyear', 'int');
+        $interval_startmonth = GETPOST('interval_startmonth', 'int');
+        $interval_startday = GETPOST('interval_startday', 'int');
+        $interval_starthour = GETPOST('interval_starthour', 'int');
+        $interval_startmin = GETPOST('interval_startmin', 'int');
+        $interval_startsec = GETPOST('interval_startsec', 'int');
+        $interval_endyear = GETPOST('interval_endyear', 'int');
+        $interval_endmonth = GETPOST('interval_endmonth', 'int');
+        $interval_endday = GETPOST('interval_endday', 'int');
+        $interval_endhour = GETPOST('interval_endhour', 'int');
+        $interval_endmin = GETPOST('interval_endmin', 'int');
+
+        $startdate = $interval_startyear . '-' . $interval_startmonth . '-' . $interval_startday . ' ' . $interval_starthour . ':' . $interval_startmin . ':' . $interval_startsec;
+        $enddate = $interval_endyear . '-' . $interval_endmonth . '-' . $interval_endday . ' ' . $interval_endhour . ':' . $interval_endmin . ':59';
+
+        if ($id) {
+            $sql = "SELECT *
+                FROM " . MAIN_DB_PREFIX . "financialreport_commissioninterval
+                WHERE rowid <> {$id} 
+                AND '{$startdate}' BETWEEN interval_start AND interval_end
+                OR rowid <> {$id} AND  '{$enddate}' BETWEEN interval_start AND interval_end
+            ";
+            $result = $db->query($sql);
+            return $db->num_rows($result) != 0;
+        } else {
+            $sql = "SELECT *
+                FROM " . MAIN_DB_PREFIX . "financialreport_commissioninterval
+                WHERE  
+                '{$startdate}' BETWEEN interval_start AND interval_end
+                OR  '{$enddate}' BETWEEN interval_start AND interval_end
+            ";
+            $result = $db->query($sql);
+            if ($result) {
+                return $db->num_rows($result) != 0;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    public function getEntities($entitiesArrayIsEmpty = false, $entities, $entitiesArray)
+    {
+        if ($entitiesArrayIsEmpty) {
+            $array = [];
+            foreach ($entities as $key => $value) {
+                $array[] = $key;
+            }
+            $selectedEntities = implode(', ', $array);
+        } else {
+            $array = [];
+            foreach ($entitiesArray as $entity) {
+                if ($entity)
+                    $array[] = $entity;
+            }
+            $selectedEntities = implode(', ', $array);
+        }
+        return $selectedEntities;
+    }
+
+    function getAllGroupsFromGroupClass($selectedEntities)
+    {
+        global $db;
+        $groups = [];
+        $sql = "SELECT rowid, ref FROM " . MAIN_DB_PREFIX . "settlements_group WHERE hotelgroup IS NULL ";
+        if ($selectedEntities != '') {
+            $sql .= " AND fk_entity IN ({$selectedEntities})";
+        }
+        $sql .= "ORDER BY ref ASC";
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage('A csoport tábla lekérdezése sikertelen volt.', 'errors');
+            return $groups;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $groups[$row['rowid']] = $row['ref'];
+        }
+        return $groups;
+    }
+
+    function getAllHotelGroupsFromGroupClass($db)
+    {
+        $groups = [];
+        $sql = "SELECT g.rowid, g.ref, g.fk_entity, gh.fk_hotel_id
+        FROM " . MAIN_DB_PREFIX . "settlements_group AS g
+        INNER JOIN " . MAIN_DB_PREFIX . "settlements_grouphotels as gh ON gh.fk_group_id = g.rowid 
+        WHERE g.hotelgroup IS NOT NULL ORDER BY ref ASC";
+        //$sql = "SELECT rowid, ref, fk_entity FROM " . MAIN_DB_PREFIX . "settlements_group WHERE hotelgroup IS NOT NULL ORDER BY ref ASC";
+        //print $sql;exit;
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage('A csoport tábla lekérdezése sikertelen volt.', 'errors');
+            return $groups;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $groups[$row['rowid']] = ["ref" => $row['ref'], "entity" => $row['fk_entity'], "fk_hotel_id" => $row['fk_hotel_id']];
+        }
+        return $groups;
+    }
+
+    function getGroupHotels()
+    {
+        global $db;
+        $groupHotels = [];
+        $sql = "SELECT gh.fk_group_id, gh.fk_hotel_id, g.ref as groulabel, h.label as hotellabel FROM " . MAIN_DB_PREFIX . "settlements_grouphotels AS gh
+        INNER JOIN " . MAIN_DB_PREFIX . "settlements_group AS g ON g.rowid = gh.fk_group_id
+        INNER JOIN " . MAIN_DB_PREFIX . "settlements_hotel AS h ON h.rowid = gh.fk_hotel_id
+        ORDER BY h.label ASC";
+        $data = $db->query($sql);
+        while ($row = pg_fetch_assoc($data)) {
+            $groupHotels[] = $row;
+        }
+        return $groupHotels;
+    }
+
+    function getUsersByIdWithDateCol2($db, $id, $date)
+    {
+        $usersOfGroup = [];
+        $date = date('Y-m-d', strtotime("-20 day", strtotime($date)));
+        /* $sqlLastLogin = "SELECT date_creation FROM llx_settlements_usernaplo WHERE status = 1 AND user_id = $id ORDER BY date_creation DESC LIMIT 1";
+        $result = $db->query($sqlLastLogin);
+        if($db->num_rows($result) > 0){
+            while($row = $db->fetch_object($result)){
+                $date = $row->date_creation;
+            }
+        }else{
+            $date = date('Y-m-d', strtotime("-20 day", dol_now()));
+            $date = $date . ' 00:00:00';
+        } */
+        $dateNow = date('Y-m-d H:i:s', dol_now());
+        if (isset($id)) {
+            $sql = "SELECT un.user_id, u.firstname as firstname, u.lastname as lastname, u.login as login FROM " . MAIN_DB_PREFIX . "settlements_usernaplo AS un
+            INNER JOIN " . MAIN_DB_PREFIX . "user as u ON u.rowid = un.user_id
+            WHERE un.group_user_id = {$id} AND un.date_creation BETWEEN '{$date} 00:00:00' AND '{$dateNow}' AND un.status = 1 
+            GROUP BY un.user_id, u.firstname, u.lastname, u.login ORDER BY u.lastname";
+            $data = $db->query($sql);
+            if (!$data) {
+                dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+                setEventMessage('A csoporthoz rendelt felhasználók naplózási lekérdezésébe valami hiba csúszott.', 'errors');
+                return $usersOfGroup;
+            }
+            while ($row = pg_fetch_assoc($data)) {
+                $usersOfGroup[] = $row;
+            }
+        }
+        return $usersOfGroup;
+    }
+
+    /**
+     * @param  int $id	Group ID
+     */
+    function getUsersByIdWithDate($db, $id, $date)
+    {
+        $usersOfGroup = [];
+        $date = date('Y-m-d', strtotime("-20 day", strtotime($date)));
+        $dateNow = date('Y-m-d H:i:s', dol_now());
+        if (isset($id)) {
+            $sql = "SELECT un.user_id, u.firstname as firstname, u.lastname as lastname, u.login as login, un.date_creation FROM " . MAIN_DB_PREFIX . "settlements_usernaplo AS un
+            INNER JOIN " . MAIN_DB_PREFIX . "user as u ON u.rowid = un.user_id
+            WHERE un.group_user_id = {$id} AND un.date_creation BETWEEN '{$date} 00:00:00' AND '{$dateNow}' AND un.status = 1 
+            GROUP BY un.user_id, u.firstname, u.lastname, u.login, un.date_creation ORDER BY u.lastname";
+            //print $sql.'<br>';
+            $data = $db->query($sql);
+            if (!$data) {
+                dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+                setEventMessage('A csoporthoz rendelt felhasználók naplózási lekérdezésébe valami hiba csúszott.', 'errors');
+                return $usersOfGroup;
+            }
+            while ($row = pg_fetch_assoc($data)) {
+                $usersOfGroup[] = $row;
+            }
+        }
+        return $usersOfGroup;
+    }
+
+    function getDeletedUsers($db, $id, $date)
+    {
+        $deletedUsersArray = [];
+        $date = date('Y-m-d', strtotime("-1 day", strtotime($date)));
+        $dateNow = date('Y-m-d H:i:s', dol_now());
+        //print $id;
+        //$sql = "SELECT user_id, MAX(date_creation) as date FROM " . MAIN_DB_PREFIX . "settlements_usernaplo WHERE group_user_id = {$id} and date_creation BETWEEN '{$date} 00:00:00' AND '{$date} 23:59:59' AND status = 0 GROUP BY user_id ";
+        $sql = "SELECT user_id, date_creation as date 
+        FROM " . MAIN_DB_PREFIX . "settlements_usernaplo 
+        WHERE group_user_id = {$id} 
+        AND date_creation BETWEEN '{$date} 00:00:00' AND '{$dateNow}' 
+        AND status = 0 ORDER BY date_creation ASC";
+        //print $sql;
+        //print '<br>';
+
+        $data = $db->query($sql);
+        $dataArray = pg_fetch_all($data);
+        if (empty($dataArray)) {
+            dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            return $deletedUsersArray;
+        }
+        foreach ($dataArray as $row) {
+            $deletedUsersArray[$row['user_id']][] = $row['date'];
+        }
+        return $deletedUsersArray;
+    }
+
+    function getSum($db, $currency, $id, $users, $date = null)
+    {
+        $sum = [];
+        foreach ($users as $user) {
+            $usersArray[] = $user['user_id'];
+        }
+        $usersString = implode(',', $usersArray);
+        $sql = "SELECT SUM(total_ht) as total_ht, SUM(total_tva) as total_tva, SUM(total_ttc) as total_ttc 
+            FROM " . MAIN_DB_PREFIX . "facture 
+            WHERE fk_user_closing IN({$usersString}) 
+            AND fk_statut = 2 
+            AND multicurrency_code = '{$currency}' 
+            AND date_closing BETWEEN '{$date} 00:00:00' AND '{$date} 23:59:59'";
+        //print $sql;
+        $data = $db->query($sql);
+
+        if (!$data) {
+            dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage('A számlák összesítésének számításába valami hiba csúszott.', 'errors');
+            return $sum;
+        }
+        $dataArray = pg_fetch_all($data);
+        foreach ($dataArray as $row) {
+            $sum[] = $row;
+        }
+        return $sum;
+    }
+
+    function correctNumber($number)
+    {
+        $integerPart = floor($number);
+        $formattedNumber = number_format($integerPart, 0, '.', ' ');
+        return $formattedNumber;
+    }
+
+    function getFullBalance($user_id, $db)
+    {
+        $sql = "SELECT
+        currency,
+        SUM(CASE WHEN payed = 0 AND payment_type = 2 THEN amount ELSE 0 END) -
+        SUM(CASE WHEN payed = 1 AND payment_type = 0 THEN amount ELSE 0 END) -
+        SUM(CASE WHEN payment_type = 1 THEN amount ELSE 0 END) AS amount
+    FROM " . MAIN_DB_PREFIX . "financialreport_userinvoice
+    WHERE user_id = {$user_id}
+    GROUP BY currency;";
+        //print $sql;exit;
+        $resultUserdata = $db->query($sql);
+        return pg_fetch_all($resultUserdata);
+    }
+
+    private function isWarning($amount)
+    {
+        return $amount < 0 ? '<font style="color: red;"> <span class="fa fa-exclamation pictofixedwidth"></span> </font>' : '';
+    }
+
+    private function getBgColor($amount)
+    {
+        return $amount < 0 ? 'red' : 'green';
+    }
+
+    function tableDrawer($allSalesUsers, $db, $idmenu, $payment_type)
+    {
+        $rownum = 0;
+        foreach ($allSalesUsers as $user) {
+            $url = '/custom/financialreport/userinvoice_list.php?user_id=' . $user['rowid'] . '&idmenu=' . $idmenu . '&payment_type=' . $payment_type . '&mainmenu=financialreport&leftmenu=';
+            $bgcolor = $this->setRowColor($rownum);
+            print '<tr style="height:30px; background-color: ' . $bgcolor . '">
+            <td><a style="display: block; width: 100%; height: 100%;" href="' . $url . '">' . $user['lastname'] . ' ' . $user['firstname'] . '</a></td>';
+            print '<td style="text-align: center;">' . $user['nickname'] . '</td>';
+            print '<td style="text-align: center;">' . $user['login'] . '</td>';
+            $this->drawCurrentBalance($user['rowid']);
+            $this->drawPayedRows($user['rowid'], $payment_type);
+            print '</tr>';
+            $rownum++;
+        }
+    }
+
+    function tableDrawerForBasicCommission($allSalesUsers, $db, $idmenu, $year, $month)
+    {
+        global $langs;
+        $rownum = 0;
+        $percentage = 0;
+        $commmissionhandler = new CommissionHandler();
+        foreach ($allSalesUsers as $user) {
+            $amountHUF = $commmissionhandler->getCommisonByUserIdForAMonth($user['rowid'], $year, $month);
+            $amount = $amountHUF;
+            $userCommissionMinimumAmount = $commmissionhandler->getUserMinimumCommission($user['rowid']);
+            $suplement = $userCommissionMinimumAmount - $amount < 0 ? 0 : $userCommissionMinimumAmount - $amount;
+            $bgcolor = $this->setRowColor($rownum);
+            $percentage = $this->getPercentage($userCommissionMinimumAmount, $amount);
+            $amountcolor = $amount < $userCommissionMinimumAmount ? 'red' : 'lightgreen';
+            $fontcolor = $percentage < 4 || $amount >= $userCommissionMinimumAmount ? 'black' : 'white';
+            $makeUpToValue = $user['rowid'] . '|' . $suplement . '|' . $year . '|' . $month . '|' . $user['lastname'] . ' ' . $user['firstname'];
+            $buttondisplay = $suplement > 0 ? 'style="display:block;"' : 'style="display:none;"';
+            $makeUpToButton = strtotime($year . '-' . $month) < strtotime(date('Y-m')) ? '<td style="padding-left: 10px; padding-right: 10px;">
+            <button ' . $buttondisplay . ' id="confirmmakeupto" name="confirmmakeupto" type="submit" value="' . $makeUpToValue . '">' . $langs->trans('MakeUpTo') . '</button>
+            </td>' : '<td>&nbsp;</td>';
+            //$url = '/custom/financialreport/userinvoicebasiccommission_list.php?user_id=' . $user['rowid'] . '&idmenu=' . $idmenu . '&mainmenu=financialreport&leftmenu=';
+            print '<tr style="height:30px; background-color: ' . $bgcolor . '">';
+            print '<td style="width: 15%;"><a href="/custom/financialreport/userinvoice_list.php?user_id=' . $user['rowid'] . '&idmenu=1618&payment_type=2&mainmenu=financialreport&leftmenu=">' . $user['lastname'] . ' ' . $user['firstname'] . '</td>';
+            print '<td style="width: 10%; text-align: center;">' . $user['nickname'] . '</td>';
+            print '<td style="width: 10%; text-align: center;">' . $this->correctNumber($userCommissionMinimumAmount) . ' HUF</td>';
+            print '<td style="width: 10%; text-align: center; color:red;">' . $this->correctNumber($suplement) . ' HUF</td>';
+            print '<td style="text-align: center; width:60%;"><div style="display:block; width:' . $percentage . '%; background-color: ' . $amountcolor . '; color:' . $fontcolor . '; white-space: nowrap;"> ' . $this->correctNumber($amount) . ' HUF </div></td>';
+            print $makeUpToButton;
+            print '</tr>';
+            $rownum++;
+        }
+    }
+
+    function getPercentage($minAmount, $amount)
+    {
+        if ($minAmount != 0) {
+            $percentage = ($amount / $minAmount) * 100;
+            if ($percentage > 100) {
+                $percentage = 100;
+            }
+        } else {
+            $percentage = $amount == 0 ? 0 : 100;
+        }
+        return $percentage;
+    }
+
+    private function drawCurrentBalanceForTpls($amount, $currency)
+    {
+        global $langs;
+        $color = $this->getBgColor($amount);
+        print '<div style="flex: 1; text-align: center;">
+            <h3>' . $langs->trans("CurrentBalance") . ' ' . $currency . '</h3>
+            <p style="background-color:' . $color . '; color:white;">' . number_format($amount, 0, '.', ' ') . ' ' . $currency . '</p>
+            </div>';
+    }
+
+    private function drawMinimumCommissionForTpls($amount, $currency)
+    {
+        global $langs;
+        $color = $this->getBgColor($amount);
+        print '<div style="flex: 1; text-align: center;">
+            <h3>' . $langs->trans("MinimumCommission") . ' ' . $currency . '</h3>
+            <p style="background-color:' . $color . '; color:white;">' . number_format($amount, 0, '.', ' ') . ' ' . $currency . '</p>
+            </div>';
+    }
+
+    function tableDrawerForViewTpls($user_id, $db, $userData, $payment_type)
+    {
+        global $langs;
+        print '<div style="width: 100%; height: 40px;padding: 5px; background-color:lightgrey; text-align:center;"><b>' . $userData->firstname . ' ' . $userData->lastname . '</b> <br> ( ' . $userData->login . ' )</div>';
+        print '<div></div>';
+
+        $balance = $this->getFullBalance($user_id, $db);
+        $earlierCommissionHUF = $balance[0]['amount'] == null ? 0 : $balance[0]['amount'];
+
+        print '<div style="display: flex; width: 100%;">';
+        $this->drawCurrentBalanceForTpls($earlierCommissionHUF, 'HUF');
+
+        $amounts = $this->getAllPaymenttype($user_id, $db, $payment_type);
+        foreach ($amounts as $amount) {
+            print '<div style="flex: 1; text-align: center;">
+                    <h3>' . $this->getViewTplTitle($payment_type) . ' ' . $amount['type'] . '</h3>
+                    <p>' . number_format($amount['amount'], 0, '.', ' ') . ' ' . $amount['type'] . '</p>
+                    </div>';
+        }
+        print '</div>';
+        if ($payment_type == 2) {
+            print '<div></div>';
+            $minimumCommission = $this->getminimumCommissionGorUser($user_id);
+            print '<div style="display: flex; width: 100%;">';
+            $this->drawMinimumCommissionForTpls($minimumCommission, 'HUF');
+            print '</div>';
+        }
+    }
+
+    private function getminimumCommissionGorUser($user_id)
+    {
+        global $langs, $db;
+        $userObj = new User($this->db);
+        $sql = "SELECT * FROM llx_user as u INNER JOIN llx_user_extrafields as ue ON ue.fk_object = u.rowid WHERE u.rowid = {$user_id}";
+        $result = $db->query($sql);
+        while ($row = $db->fetch_object($result)) {
+            $minimum_monthly_commission = $row->minimum_monthly_commission;
+        }
+        if (!$result) {
+            dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($langs->trans('noUserForMinimumCommission'), 'errors');
+        }
+        return $minimum_monthly_commission;
+    }
+
+    private function setRowColor($rownum)
+    {
+        return $rownum % 2 == 0 ? '#b0c4de' : 'white';
+    }
+
+    private function drawCurrentBalance($user_id)
+    {
+        $balance = $this->getFullBalance($user_id, $this->db);
+        if (isset($ammount[0])) {
+            $earlierCommissionHUF = $balance[0]['amount'] == null ? 0 : $balance[0]['amount'];
+        } else {
+            $earlierCommissionHUF = 0;
+        }
+        $earlierCommissionHUF = $balance[0]['amount'] == null ? 0 : $balance[0]['amount'];
+        //$earlierCommissionEUR = $balance[1]['amount'] == null ? 0 : $balance[1]['amount'];
+        $warning = $this->isWarning($earlierCommissionHUF);
+        print '<td style="text-align:center;">' . number_format($earlierCommissionHUF, 0, '.', ' ') . ' HUF ' . $warning . '</td>';
+        /* $warning = $this->isWarning($earlierCommissionEUR);
+        print '<td style="text-align:center;">' . number_format($earlierCommissionEUR, 0, '.', ' ') . ' EUR ' . $warning . '</td>'; */
+    }
+
+    private function drawPayedRows($user_id, $payment_type)
+    {
+        $amounts = $this->getAllPaymenttype($user_id, $this->db, $payment_type);
+        foreach ($amounts as $amount) {
+            print '<td style="text-align:center;">' . number_format($amount['amount'], 0, '.', ' ') . ' ' . $amount['type'] . ' </td>';
+        }
+    }
+
+    function tableDrawerForHistory($allSalesUsers, $idmenu)
+    {
+        $rownum = 0;
+        foreach ($allSalesUsers as $user) {
+            $url = '/custom/financialreport/commissionhistory_list.php?user_id=' . $user['rowid'] . '&idmenu=' . $idmenu . '&payment_type=2&mainmenu=financialreport&leftmenu=';
+            $bgcolor = $this->setRowColor($rownum);
+            print '<tr style="height:30px; background-color: ' . $bgcolor . '">
+            <td><a style="display: block; width: 100%; height: 100%;" href="' . $url . '">' . $user['lastname'] . ' ' . $user['firstname'] . '</a></td>';
+            print '<td style="text-align: center;">' . $user['nickname'] . '</td>';
+            print '<td style="text-align: center;">' . $user['login'] . '</td>';
+            // Itt azt kell megejelníteni, ami a még ki nem fizetett jutalékokból és a kifizetett előlegek és visszatartsások összegének különbségéből áll össze.
+            $this->drawCurrentBalance($user['rowid']);
+            $this->drawPayedRows($user['rowid'], 2);
+            $this->drawPayedRows($user['rowid'], 0);
+            print '</tr>';
+            $rownum++;
+        }
+    }
+
+    function tableDrawerForDailyClosing($allSalesUsers, $idmenu)
+    {
+        $rownum = 0;
+        foreach ($allSalesUsers as $user) {
+            $url = '/custom/settlements/dailyclosing_card.php?user_id=' . $user['rowid'] . '&idmenu=' . $idmenu . '&mainmenu=settlements&leftmenu=';
+            $bgcolor = $this->setRowColor($rownum);
+            print '<tr style="height:30px; background-color: ' . $bgcolor . '">
+            <td><a style="display: block; width: 100%; height: 100%;" href="' . $url . '">' . $user['lastname'] . ' ' . $user['firstname'] . '</a></td>';
+            print '<td style="text-align: center;">' . $user['nickname'] . '</td>';
+            print '<td style="text-align: center;">' . $user['login'] . '</td>';
+            // Itt azt kell megejelníteni, ami a még ki nem fizetett jutalékokból és a kifizetett előlegek és visszatartsások összegének különbségéből áll össze.
+            $this->drawCurrentBalance($user['rowid']);
+            $this->drawPayedRows($user['rowid'], 2);
+            $this->drawPayedRows($user['rowid'], 0);
+            print '</tr>';
+            $rownum++;
+        }
+    }
+
+    function generateRef($payment_type)
+    {
+        return $this->getTypeOfPayment($payment_type) . '_' . dol_now() . '_' . rand(1000000, 9999999);
+    }
+
+    /* function checkBalance($user_id, $date)
+    {
+        $sql = "SELECT invoices FROM " . MAIN_DB_PREFIX . "financialreport_userinvoice 
+        WHERE user_id = {$user_id} 
+        AND date_creation BETWEEN '{$date} 00:00:00' AND '{$date} 23:59:59'
+        AND payment_type = 2
+        ";
+        $resultBalanceData = $this->db->query($sql);
+        $result = pg_fetch_all($resultBalanceData);
+        return is_array($result);
+    } */
+
+    function getOccassionOfThisPeriodByDateAndUserId($user_id, $from, $to)
+    {
+        return rand(100, 1000);
+    }
+
+    function createDataArrayForLoginLogotOccassionTable($results)
+    {
+        $array = [];
+        $i = 0;
+        foreach ($results as $record) {
+            if ($record->login_logout_status == 0) {
+                $array[$i]['login'] = date('Y-m-d H:i:s', $record->date_creation);
+            } else {
+                if (isset($record->date_creation)) {
+                    $array[$i]['logout'] = date('Y-m-d H:i:s', $record->date_creation);
+                }
+            }
+            $i++;
+        }
+        return $array;
+    }
+
+    function createUserDataArray($array, $userOfGroups)
+    {
+        $userDataArray = [];
+        $count = count($array);
+        for ($k = 0; $k < $count; $k++) {
+            if (isset($array[$k]['login'])) {
+                if (!isset($userDataArray[$k - 1]['logout']) && $k != 0) {
+                    $userDataArray[$k - 1]['logout'] = $array[$k]['login'] . '*';
+                }
+                $userDataArray[$k]['login'] = $array[$k]['login'];
+            }
+            if (isset($array[$k]['logout'])) {
+                $userDataArray[$k - 1]['logout'] = $array[$k]['logout'];
+            }
+            if ($k == $count - 1 && isset($deletedUsersArray[$userOfGroups['user_id']])) {
+                $userDataArray[$k]['logout'] = $array[$userOfGroups['user_id']];
+            }
+        }
+        return $userDataArray;
+    }
+
+    function updateUserDataArray($userDataArray, $deletedUsersArray, $userOfGroups, $commmissionhandler)
+    {
+        foreach ($userDataArray as $key => $period) {
+            $from = $period['login'];
+            $to = isset($period['logout']) ? $period['logout'] : (isset($deletedUsersArray[$userOfGroups['user_id']]) ? $deletedUsersArray[$userOfGroups['user_id']] : date('Y-m-d', dol_now()) . ' 23:59:59');
+            //print $from . ' - ' . $to . '<br>';
+            if (isset($from)) {
+                $commission_HUF = $commmissionhandler->getOccassionOfThisPeriodByDateAndUserId_HUF($userOfGroups['user_id'], $from, $to);
+                $commission_EURToHUF = $commmissionhandler->getOccassionOfThisPeriodByDateAndUserId_EURToHUF($userOfGroups['user_id'], $from, $to);
+                $userDataArray[$key]['commission'] = $commission_HUF + $commission_EURToHUF;
+            }
+        }
+        return $userDataArray;
+    }
+
+    function getAmountOfCommissions($userDataArray)
+    {
+        $amount = 0;
+        foreach ($userDataArray as $record) {
+            $amount += intval($record);
+        }
+        return $amount;
+    }
+
+    function getAllFacturesOfThisUser($user_id, $from, $to)
+    {
+        $crossShoppingFacturesString = '';
+        $sql = "SELECT ref 
+            FROM llx_facture AS f 
+            WHERE fk_user_closing = {$user_id} 
+            AND date_closing BETWEEN '{$from}' AND '{$to}'";
+        $result = $this->db->query($sql);
+        if ($this->db->num_rows($result) > 0) {
+            while ($row = $this->db->fetch_object($result)) {
+                if ($crossShoppingFacturesString == "") {
+                    $crossShoppingFacturesString .= "'" . $row->ref . "'";
+                } else {
+                    $crossShoppingFacturesString .= ",'" . $row->ref . "'";
+                }
+            }
+        }
+        return $crossShoppingFacturesString;
+    }
+
+    function getInvoicesRowidFromFacture($user_id, $from, $to)
+    {
+        $invocesRowidArray = [];
+        $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "facture AS f WHERE fk_user_closing = {$user_id} 
+        AND EXISTS (SELECT * FROM " . MAIN_DB_PREFIX . "bbus_bbticketinvoiceprinting as bbip WHERE bbip.fk_facture = f.rowid ORDER BY bbip.rowid DESC LIMIT 1)
+        AND date_closing BETWEEN '{$from}' AND '{$to}'";
+        $resultInvoicesData = $this->db->query($sql);
+        if ($this->db->num_rows($resultInvoicesData) != 0) {
+            $result = pg_fetch_all($resultInvoicesData);
+            foreach ($result as $value) {
+                $invocesRowidArray[] = $value['rowid'];
+            }
+            $invocesRowidString = implode(',', $invocesRowidArray);
+        }
+        $readyInvoices = $this->getAllComissionInvoicesOfUserInTheGroupFromUserInvoice($user_id, $from, $to);
+
+        if (!empty($readyInvoices)) {
+            $invocesRowidString = $this->giveMeTheDifferenceInString($readyInvoices, $invocesRowidString);
+        }
+        return $invocesRowidString;
+    }
+
+    function getCrossShoppingInvoicesRowidFromFacture($allFactures, $from, $to)
+    {
+        $facturesRowids = '';
+        $params = ["from" => $from, "to" => $to, "factures" => $allFactures];
+        $postFields = json_encode($params);
+        $crossShoppingFactures = $this->curlRunner('bookingapi/getPrintedFacturesRefs', $postFields, 'POST', true);
+        if ($crossShoppingFactures !== '') {
+            $sql = "SELECT rowid FROM llx_facture WHERE ref IN ($crossShoppingFactures)";
+            $result = $this->db->query($sql);
+            if ($this->db->num_rows($result) > 0) {
+                while ($row = $this->db->fetch_object($result)) {
+                    if ($facturesRowids == "") {
+                        $facturesRowids .= $row->rowid;
+                    } else {
+                        $facturesRowids .= "," . $row->rowid;
+                    }
+                }
+            }
+        }
+        return $facturesRowids;
+    }
+
+    function getInvoicesRowidFromFactureInAnIntervalByEveryUser($users, $from, $to, $exception)
+    {
+        $invocesRowidArray = [];
+        $sql = "SELECT f.rowid FROM " . MAIN_DB_PREFIX . "facture as f WHERE fk_user_closing IN({$users})";
+        if ($exception != '') {
+            $sql .= " AND rowid NOT IN({$exception})";
+        }
+        $sql .= " AND EXISTS (SELECT * FROM " . MAIN_DB_PREFIX . "bbus_bbticketinvoiceprinting as bbip WHERE bbip.fk_facture = f.rowid ORDER BY bbip.rowid DESC LIMIT 1)
+         AND date_closing BETWEEN '{$from}' AND '{$to}'";
+        //print $sql . "\r\n";
+        $resultInvoicesData = $this->db->query($sql);
+        if ($this->db->num_rows($resultInvoicesData) != 0) {
+            $result = pg_fetch_all($resultInvoicesData);
+            foreach ($result as $value) {
+                $invocesRowidArray[] = $value['rowid'];
+            }
+            $invocesRowidString = implode(',', $invocesRowidArray);
+        }
+        return $invocesRowidString;
+    }
+
+    function getInvoicesRowidFromFactureInAnIntervalByEveryUserWithoutInvoicePrinting($users, $from, $to, $exception)
+    {
+        $crossShoppingFacturesString = '';
+        $sql = "SELECT f.ref FROM " . MAIN_DB_PREFIX . "facture as f WHERE fk_user_closing IN({$users})";
+        if ($exception != '') {
+            $sql .= " AND rowid NOT IN({$exception})";
+        }
+        $sql .= " AND date_closing BETWEEN '{$from}' AND '{$to}'";
+        //print $sql . "\r\n";
+        $resultInvoicesData = $this->db->query($sql);
+        if ($this->db->num_rows($resultInvoicesData) > 0) {
+            while ($row = $this->db->fetch_object($resultInvoicesData)) {
+                if ($crossShoppingFacturesString == "") {
+                    $crossShoppingFacturesString .= "'" . $row->ref . "'";
+                } else {
+                    $crossShoppingFacturesString .= ",'" . $row->ref . "'";
+                }
+            }
+        }
+        return $crossShoppingFacturesString;
+    }
+
+
+    function getAllComissionInvoicesOfUserInTheGroupFromUserInvoice($user_id, $from, $to)
+    {
+        $arraytmp = [];
+        $invocesRowidString = '';
+        $userInvocesObj = new UserInvoice($this->db);
+        $result = $userInvocesObj->fetchAll('ASC', 'rowid', 0, 0, ['customsql' => "user_id = " . $user_id . " AND date_creation BETWEEN '" . $from . "' AND '" . $to . "'"]);
+        foreach ($result as $data) {
+            if (!empty($data->invoices) || $data->invoices != '') {
+                $array1 = explode(',', $data->invoices);
+                $arraytmp = array_merge($arraytmp, $array1);
+            }
+        }
+        $invocesRowidString = implode(',', $arraytmp);
+        //print $invocesRowidString;
+        return $invocesRowidString;
+    }
+
+    function giveMeTheDifferenceInString($readyInvoices, $invocesRowidString)
+    {
+        $string = '';
+        if ($readyInvoices != '' && $invocesRowidString != '') {
+            $array1 = explode(',', $readyInvoices);
+            $array2 = explode(',', $invocesRowidString);
+            /*             print 'array1: ';
+                        print_r($array1);
+                        print '<br>';
+                        print 'array2: ';
+                        print_r($array2);     
+                        print '<br>'; */
+            $arrayDiff = array_diff($array2, $array1);
+            //$arrayDiff = array_diff($array1, $array2);  
+
+            /* print 'Diff: ';
+            print_r($arrayDiff);
+            print '<br>';
+            print '<br>';
+            print '<br>';
+     */
+            //$arrayDiff = count($array2) > count($array1) ? array_diff($array2, $array1) : array_diff($array1, $array2);
+            $string = implode(',', $arrayDiff);
+            return $string;
+        }
+        return $string;
+    }
+
+    function getHtmlForConfirmWindow($commission)
+    {
+        $userData = [];
+        $userObj = new User($this->db);
+        foreach ($commission as $value) {
+            $itemData = explode('_', $value);
+            $userdata = $userObj->fetch($itemData[0]);
+            //print_r($userObj);exit;
+            $userData[$userObj->id]['name'] = $userObj->lastname . ' ' . $userObj->firstname . ' (' . $userObj->login . ') ' . $userObj->array_options['options_nickname'];
+            $summaHUF += $itemData[2];
+        }
+        $uniformHUF = $summaHUF / count($commission);
+        $array[] = $userData;
+        $array[] = $uniformHUF;
+        return $array;
+    }
+
+    function azosszesElemEgyezik($tomb)
+    {
+        $szamlalo = array_count_values($tomb);
+        $kulonbozoErtekekSzama = count($szamlalo);
+        return $kulonbozoErtekekSzama === 1;
+    }
+
+    function getUsersArray($data)
+    {
+        foreach ($data as $item) {
+            $itemData = explode('_', $item);
+            $usersArray[] = $itemData[0];
+        }
+        return $usersArray;
+    }
+
+    function checkUserInvoiceRecordAvailability($user_id)
+    {
+        $userInvoiceObj = new UserInvoice($this->db);
+        $now = dol_now();
+        $result = $userInvoiceObj->fetchAll('DESC', 'date_creation', 1, 0, ['customsql' => "user_id = " . $user_id . " AND date_creation BETWEEN '" . date('Y-m-d', $now) . " 00:00:00' AND '" . date('Y-m-d', $now) . " 23:59:59'"]);
+        return $result;
+    }
+
+    function deleteUserFromUsersArrayTMPArray($key, $usersArrayTMP)
+    {
+        $index = array_search($key, $usersArrayTMP);
+        if ($index !== false) {
+            unset($usersArrayTMP[$index]);
+        }
+        return $usersArrayTMP;
+    }
+
+    function saveUserInvoiceRecord($usersArrayFilteredUsersFrom, $val, $uniformHUF, $settledInvoices)
+    {
+        global $user;
+        $userinvoice = new UserInvoice($this->db);
+        $currency = 0;
+        $userinvoice->ref = $this->generateRef(2);
+        $userinvoice->label = 'Jutalék/Commission ' . $usersArrayFilteredUsersFrom[$val];
+        $userinvoice->description = 'Összeg / Amount: ' . $uniformHUF . 'HUF.';
+        $userinvoice->user_id = $val;
+        $userinvoice->payment_type = 2;
+        $userinvoice->amount = $uniformHUF;
+        $userinvoice->currency = $currency;
+        $userinvoice->individual = 0;
+        $userinvoice->invoices = $settledInvoices;
+        $userinvoice->date_creation = strtotime($usersArrayFilteredUsersFrom[$val]);
+        $userinvoice->create($user);
+    }
+
+    function getAllDifferentDatesASC($from, $to)
+    {
+        foreach ($from as $fromvalue) {
+            foreach ($fromvalue as $value1) {
+                $allDates[] = $value1;
+            }
+        }
+        foreach ($to as $tovalue) {
+            foreach ($tovalue as $value1) {
+                $allDates[] = $value1;
+            }
+        }
+        $allDates = array_unique($allDates);
+        return $allDates;
+    }
+
+    function getQueryArray($from, $to)
+    {
+        $allDates = $this->getAllDifferentDatesASC($from, $to);
+        uasort($allDates, 'datumOsszehasonlitas');
+        $countAllDatesArray = count($allDates);
+        $allDates = array_values($allDates);
+        for ($i = 0; $i < $countAllDatesArray - 1; $i++) {
+            $queryArray[$i]['from'] = $allDates[$i];
+            $queryArray[$i]['to'] = $allDates[$i + 1];
+        }
+        return $queryArray;
+    }
+
+
+    function getAllComissionInvoicesOfUserInTheGroupFromUserInvoiceCreated($usersArray, $from, $to)
+    {
+        $userInvocesObj = new UserInvoice($this->db);
+        $result = $userInvocesObj->fetchAll('ASC', 'rowid', 0, 0, ['customsql' => "user_id IN(" . $usersArray . ") AND date_creation BETWEEN '" . $from . "' AND '" . $to . "'"]);
+        $all = [];
+        foreach ($result as $key => $value) {
+            //print $value->user_id . ' - ';
+            //print $value->invoices . "\r\n";
+            $arrayTmp = explode(',', $value->invoices);
+            $all = array_merge($all, $arrayTmp);
+        }
+        $all = array_unique($all);
+        $all = array_filter($all);
+        sort($all);
+        return implode(',', $all);
+    }
+
+    public function getGroupMemberHistory($user_id, $group_id, $date)
+    {
+        $groupMemberHistory = [];
+        $from = $date . ' 00:00:00';
+        $to = $date . ' 23:59:59';
+        $UserNaplo = new UserNaplo($this->db);
+        $result = $UserNaplo->fetchAll('ASC', 'rowid', 0, 0, ['customsql' => "user_id = {$user_id} AND group_user_id = {$group_id} AND date_creation BETWEEN '{$from}' AND '{$to}'"]);
+        foreach ($result as $record) {
+            if ($record->status == 1) {
+                $groupMemberHistory[]['added'] = date("Y-m-d H:i:s", $record->date_creation);
+            } else {
+                $groupMemberHistory[]['deleted'] = date("Y-m-d H:i:s", $record->date_creation);
+            }
+        }
+        return $groupMemberHistory;
+    }
+
+    function getUsersByIdFromGroupUsers($id)
+    {
+        global $db;
+        $usersOfGroup = [];
+        if (isset($id)) {
+            $sql = "SELECT gu.fk_user AS user_id, gu.date_creation, u.firstname as firstname, u.lastname as lastname, u.login as login FROM " . MAIN_DB_PREFIX . "settlements_groupusers as gu  
+            INNER JOIN " . MAIN_DB_PREFIX . "user AS u ON u.rowid = gu.fk_user
+            WHERE gu.fk_Settlements_group = {$id}";
+            $data = $db->query($sql);
+            if (!$data) {
+                dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+                setEventMessage('A csoporthoz rendelt felhasználók naplózási lekérdezésébe valami hiba csúszott.', 'errors');
+                return $usersOfGroup;
+            }
+            while ($row = pg_fetch_assoc($data)) {
+                $usersOfGroup[] = $row;
+            }
+        }
+        return $usersOfGroup;
+    }
+
+    function getDeletedHotelUsers($id)
+    {
+        global $db;
+        $deletedUsersArray = [];
+        if (isset($id)) {
+            $sql = "SELECT user_id, date_creation as date 
+        FROM " . MAIN_DB_PREFIX . "settlements_usernaplo 
+        WHERE group_user_id = {$id} 
+        AND status = 0 ORDER BY date_creation ASC";
+            //print $sql;exit;
+            $data = $db->query($sql);
+            $dataArray = pg_fetch_all($data);
+            if (empty($dataArray)) {
+                dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+                return $deletedUsersArray;
+            }
+            foreach ($dataArray as $row) {
+                $deletedUsersArray[$row['user_id']][] = $row['date'];
+            }
+        }
+        return $deletedUsersArray;
+    }
+
+    function getUserdataFromNaploByUaserId($user_id, $userGroupId)
+    {
+        global $db;
+        $date = '';
+        $sql = "SELECT date_creation as date FROM " . MAIN_DB_PREFIX . "settlements_usernaplo
+        WHERE user_id = {$user_id} AND group_user_id = {$userGroupId} AND status = 1
+        ORDER BY rowid ASC LIMIT 1";
+        //print $sql;
+        $data = $db->query($sql);
+        $dataArray = pg_fetch_all($data);
+        if (empty($dataArray)) {
+            dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            return $date;
+        }
+        foreach ($dataArray as $row) {
+            return $row['date'];
+        }
+    }
+
+    function createDaterangeString($daterange)
+    {
+        $array = explode(' - ', $daterange);
+        return str_replace('-', '.', $array[0]) . ' - ' . str_replace('-', '.', $array[1]);
+    }
+
+    function getUsersOfHotelGroup2($id, $daterange)
+    {
+        global $db;
+        $dates = explode(' - ', $daterange);
+        $now = dol_now();
+        $to = $dates[1] > date('Y-m-d', $now) ? date('Y-m-d', $now) : $dates[1];
+
+        $sql = "SELECT u.rowid, u.firstname, u. lastname, ue.user_category FROM " . MAIN_DB_PREFIX . "settlements_usernaplo AS un
+        INNER JOIN " . MAIN_DB_PREFIX . "user as u ON u.rowid = un.user_id
+        INNER JOIN " . MAIN_DB_PREFIX . "user_extrafields AS ue ON ue.fk_object = u.rowid
+        WHERE un.date_creation BETWEEN '{$dates[0]} 00:00:00' AND '{$to} 23:59:59'
+        AND un.group_user_id = {$id}
+        GROUP BY u.firstname, u.lastname, ue.user_category, u.rowid";
+        $data = $db->query($sql);
+        $result = pg_fetch_all($data);
+        if (empty($result)) {
+            return [];
+        }
+        return $result;
+    }
+
+
+    function getUsersOfHotelGroup($id, $daterange, $entity)
+    {
+        global $db;
+        $array = [];
+        $dates = explode(' - ', $daterange);
+        $now = dol_now();
+        $to = $dates[1] > date('Y-m-d', $now) ? date('Y-m-d', $now) : $dates[1];
+        if (isset($id)) {
+            $sql = "SELECT u.rowid, u.firstname, u. lastname, ue.user_category FROM " . MAIN_DB_PREFIX . "facture AS f
+            INNER JOIN " . MAIN_DB_PREFIX . "user as u ON u.rowid = f.fk_user_closing
+            INNER JOIN " . MAIN_DB_PREFIX . "user_extrafields AS ue ON ue.fk_object = u.rowid
+            INNER JOIN " . MAIN_DB_PREFIX . "facture_extrafields as fe ON fe.fk_object = f.rowid
+            WHERE f.date_closing BETWEEN '{$dates[0]} 00:00:00' AND '{$to} 23:59:59'
+            AND f.entity = {$entity}
+            AND fe.react_facture = {$id}
+            GROUP BY u.rowid, u.firstname, u. lastname, ue.user_category";
+            //print $sql;
+            $data = $db->query($sql);
+            $array = pg_fetch_all($data);
+            if (empty($result)) {
+                return $array;
+            }
+        }
+        return $array;
+    }
+
+    function getUsersList($id, $daterange, $entity)
+    {
+        global $db;
+        $string = '';
+        $result = $this->getUsersOfHotelGroup($id, $daterange, $entity);
+        foreach ($result as $row) {
+            $string .= '<tr class="smallredcolor"><td><b>' . $row['firstname'] . ' ' . $row['lastname'] . '</b></td><td>(' . $this->userCategoryArray[$row['user_category']] . ')</td><td>' . $this->correctNumber($this->getAllAmountInPeriod($id, $daterange, 'HUF', $row['rowid'], $entity)) . ' HUF</td><td>' . $this->correctNumber($this->getAllAmountInPeriod($id, $daterange, 'EUR', $row['rowid'], $entity)) . ' EUR</td></tr>';
+        }
+        return $string;
+    }
+
+    function getUsersIdList($id, $daterange, $entity)
+    {
+        global $db;
+        $result = $this->getUsersOfHotelGroup($id, $daterange, $entity);
+        if (!empty($result)) {
+            foreach ($result as $row) {
+                $array[] = $row['rowid'];
+            }
+            return implode(',', $array);
+        }
+        return '';
+    }
+
+    function getAllAmountInPeriod($id, $daterange, $currency, $usersIdList, $entity)
+    {
+        //$entity = 1;
+        global $db;
+        $result = 0;
+        $dates = explode(' - ', $daterange);
+        $now = dol_now();
+        $to = $dates[1] > date('Y-m-d', $now) ? date('Y-m-d', $now) : $dates[1];
+        if (isset($id)) {
+            $sql = "SELECT sum(f.total_ttc) FROM " . MAIN_DB_PREFIX . "facture as f
+            INNER JOIN " . MAIN_DB_PREFIX . "facture_extrafields as fe ON fe.fk_object = f.rowid
+            WHERE f.paye = 1
+            AND f.date_closing BETWEEN '{$dates[0]} 00:00:00' AND '{$to} 23:59:59'";
+            if ($usersIdList !== '') {
+                $sql .= " AND f.fk_user_closing in($usersIdList)";
+            }
+            $sql .= " AND f.multicurrency_code = '{$currency}'
+        AND f.entity = {$entity}
+        AND fe.react_facture = {$id}";
+            //print $sql;
+            $data = $db->query($sql);
+            $result = pg_fetch_all($data);
+            return is_null($result[0]['sum']) ? 0 : $result[0]['sum'];
+        }
+    }
+
+    function getAllCommissionInPeriod($id, $daterange, $currency, $usersIdList, $entity)
+    {
+        global $db;
+        $commissionsArray = [];
+        $dates = explode(' - ', $daterange);
+        $now = dol_now();
+        $to = $dates[1] > date('Y-m-d', $now) ? date('Y-m-d', $now) : $dates[1];
+        if (isset($id)) {
+            $sql = "SELECT f.total_ttc, fe.commission
+        FROM " . MAIN_DB_PREFIX . "facture as f 
+        INNER JOIN " . MAIN_DB_PREFIX . "facture_extrafields as fe ON fe.fk_object = f.rowid 
+        WHERE f.paye = 1 
+        AND f.date_closing BETWEEN '{$dates[0]} 00:00:00' AND '{$to} 23:59:59'";
+            if ($usersIdList !== '') {
+                $sql .= " AND f.fk_user_closing in($usersIdList)";
+            }
+            $sql .= " AND f.multicurrency_code = '{$currency}' 
+        AND f.entity = '{$entity}'
+        AND fe.react_facture = {$id}";
+            //print $sql;exit;
+            $data = $db->query($sql);
+            $result = pg_fetch_all($data);
+            //print_r($result);
+            if (!empty($result)) {
+                foreach ($result as $row) {
+                    $commissionValue = $this->getCommissionData($row['commission'], 0);
+                    $commissionUnit = $this->getCommissionData($row['commission'], 1);
+                    if ($commissionUnit == '%') {
+                        $commissionsArray[] = ($row['total_ttc'] / 100) * $commissionValue;
+                    } else {
+                        $commissionsArray[] = $commissionValue;
+                    }
+                }
+            }
+            return $this->getAmountOfCommissions($commissionsArray);
+        }
+        return 0;
+    }
+
+    private function getCommissionData($commission, $number)
+    {
+        $array = explode('_', $commission);
+        return $array[$number];
+    }
+
+    public function getAllHotels()
+    {
+        global $db;
+        $resultArray = [];
+        $hotelsObj = new Hotel($db);
+        $hotelsArray = $hotelsObj->fetchAll('ASC', 'label', 0, 0);
+        if (!empty($hotelsArray)) {
+            foreach ($hotelsArray as $hotelRecord) {
+                $resultArray[$hotelRecord->id] = $hotelRecord->label;
+            }
+        }
+        return $resultArray;
+    }
+
+    public function getGroupRefByID($id)
+    {
+        if (isset($id)) {
+
+            global $db;
+            $sql = "SELECT ref FROM " . MAIN_DB_PREFIX . "settlements_group WHERE rowid = {$id}";
+            $data = $db->query($sql);
+            if (!$data) {
+                dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            }
+            while ($row = pg_fetch_assoc($data)) {
+                return $row['ref'];
+            }
+        }
+        return '';
+    }
+
+    public function getGroupEntityId($id)
+    {
+        if (isset($id)) {
+            global $db;
+            $sql = "SELECT fk_entity FROM " . MAIN_DB_PREFIX . "settlements_group WHERE rowid = {$id}";
+            $data = $db->query($sql);
+            if (!$data) {
+                dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            }
+            while ($row = pg_fetch_assoc($data)) {
+                return $row['fk_entity'];
+            }
+        }
+        return null;
+    }
+
+    public function getGroupLabelById($id)
+    {
+        global $db;
+        $groupObj = new Group($db);
+        $groupObj->fetch($id);
+        return $groupObj->ref;
+    }
+
+    public function getFirstDateFromUserNaplo($id)
+    {
+        global $db;
+        $from = date("Y-m-d") . ' 00:00:00';
+        $to = date("Y-m-d H:i:s");
+        $sql = "SELECT un.date_creation FROM " . MAIN_DB_PREFIX . "settlements_usernaplo AS un
+            WHERE un.group_user_id = {$id} AND un.date_creation BETWEEN '{$from}' AND '{$to}' AND un.status = 1 
+            ORDER BY un.date_creation ASC LIMIT 1";
+        //print $sql;exit;
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+        }
+        while ($row = pg_fetch_all($data)) {
+            return $row[0]['date_creation'];
+        }
+        return null;
+    }
+
+    public function getNamedataFoTheUser($user_id)
+    {
+        global $db;
+        $sql = "SELECT u.firstname, u.lastname, u.login FROM " . MAIN_DB_PREFIX . "user AS u WHERE rowid = {$user_id}";
+        //print $sql;exit;
+        $data = $db->query($sql);
+        foreach (pg_fetch_all($data) as $userData) {
+            return $userData['firstname'] . ' ' . $userData['lastname'] . ' (' . $userData['login'] . ')';
+        }
+    }
+
+    public function checklogoutRecordInUserNaplo($user_id, $from, $id)
+    {
+        global $db;
+        $sql = "SELECT date_creation FROM " . MAIN_DB_PREFIX . "settlements_usernaplo
+        WHERE group_user_id = {$id}
+        AND user_id = {$user_id}
+        AND date_creation > '{$from}'
+        AND status = 0
+        ORDER BY date_creation ASC LIMIT 1";
+        $data = $db->query($sql);
+        while ($row = pg_fetch_assoc($data)) {
+            return $row['date_creation'];
+        }
+    }
+
+    public function getGTAndGUArray()
+    {
+        global $db;
+        $sql = "SELECT fk_groupid, fk_group_tools_id FROM " . MAIN_DB_PREFIX . "settlements_usergrouptoolgroup";
+        $result = $db->query($sql);
+        if (pg_num_rows($result) > 0) {
+            while ($row = pg_fetch_assoc($result)) {
+                $array[$row['fk_groupid']] = $row['fk_group_tools_id'];
+            }
+            return $array;
+        }
+        return [];
+    }
+
+    function getAllEntities()
+    {
+        $entitiesArray = [];
+        $sql = "SELECT rowid, label FROM " . MAIN_DB_PREFIX . "entity ORDER BY label ASC";
+        $data = $this->db->query($sql);
+        while ($row = pg_fetch_assoc($data)) {
+            $entitiesArray[$row['rowid']] = $row['label'];
+        }
+        return $entitiesArray;
+    }
+
+    function createPopoupBox($numberOfUsers, $usersArray, $id)
+    {
+        $popoupBox = '<div style="float:right; padding-bottom: 10px;" title="';
+        foreach ($usersArray as $users) {
+            $popoupBox .= '<span class=&quot;fas fa-user  em080&quot; style=&quot; color: #a69944;&quot; cursor: pointer;></span> 
+            <u class=&quot;paddingrightonly&quot;>' . $users['lastname'] . ' ' . $users['firstname'] . ' (' . $users['login'] . ')</u><br>';
+        }
+        $popoupBox .= '" class="classfortooltip"><div onclick="popupboxClick(' . $id . ')" class="groupColumn2ndLine">' . $numberOfUsers . '</div>';
+        return $popoupBox;
+    }
+}

+ 4 - 4
custom/rollerstorage/class/api_rollerstorage.class.php

@@ -102,10 +102,10 @@ class RollerstorageApi extends DolibarrApi
 	 */
 	 */
 	public function checkPermissionLT()
 	public function checkPermissionLT()
 	{
 	{
-		global $conf, $user;
+		global $conf, $user, $conf;
 		//ApiBbusLog::LunaToursLog("checkPermissionLT_START");
 		//ApiBbusLog::LunaToursLog("checkPermissionLT_START");
 		$memcached = new Memcached();
 		$memcached = new Memcached();
-		$memcached->addServer("szollosil-excelia-urbanms-memcached", 11211);
+		$memcached->addServer($conf->global->CONF_MEMCACHED, 11211);
 
 
 		$key = '"' . $user->api_key . '"';
 		$key = '"' . $user->api_key . '"';
 
 
@@ -228,7 +228,7 @@ class RollerstorageApi extends DolibarrApi
 	 */
 	 */
 	public function checkPermission()
 	public function checkPermission()
 	{
 	{
-		global $user, $db;
+		global $user, $db, $conf;
 		$permissionArray = [];
 		$permissionArray = [];
 		dol_include_once('/eventwizard/class/eventdetails.class.php');
 		dol_include_once('/eventwizard/class/eventdetails.class.php');
 		$sqlBasicService = "SELECT pe.basic_service FROM llx_product as p
 		$sqlBasicService = "SELECT pe.basic_service FROM llx_product as p
@@ -240,7 +240,7 @@ class RollerstorageApi extends DolibarrApi
 				$basicServices[] = $row->basic_service;
 				$basicServices[] = $row->basic_service;
 			}
 			}
 		}
 		}
-		$sqlBasicServicesTable = "SELECT basic_service_id, ref FROM llx_bbus_basicServices WHERE server_host = 'excelia' ORDER BY basic_service_id ASC";
+		$sqlBasicServicesTable = "SELECT basic_service_id, ref FROM llx_bbus_basicServices WHERE server_host = '{$conf->global->LOCAL_SERVER_HOST}' ORDER BY basic_service_id ASC";
 		$resultBasicServicesObj = $db->query($sqlBasicServicesTable);
 		$resultBasicServicesObj = $db->query($sqlBasicServicesTable);
 		if ($db->num_rows($resultBasicServicesObj) > 0) {
 		if ($db->num_rows($resultBasicServicesObj) > 0) {
 			while ($bsrow = $db->fetch_object($resultBasicServicesObj)) {
 			while ($bsrow = $db->fetch_object($resultBasicServicesObj)) {

+ 41 - 47
custom/rollerstorage/langs/hu_HU/rollerstorage.lang

@@ -18,7 +18,7 @@
 #
 #
 
 
 # Module label 'ModuleStorageName'
 # Module label 'ModuleStorageName'
-ModuleRollerstorageName = Storage
+ModuleRollerstorageName = Eszközök
 # Module description 'ModuleStorageDesc'
 # Module description 'ModuleStorageDesc'
 ModuleRollerstorageDesc = Storage description
 ModuleRollerstorageDesc = Storage description
 
 
@@ -54,60 +54,54 @@ MyWidget = My widget
 MyWidgetDescription = My widget description
 MyWidgetDescription = My widget description
 
 
 
 
-ListOfInventories=List of inventories
-Roller=Device
-Rollerhistory=The history of the device
-DeleteInventory=Delete
-
-active=Active
-faulty=Faulty
-scrap=Scrap
+ListOfInventories=Az eszközök listája
+Roller=Eszköz
+Rollerhistory=Az eszköz története
+DeleteInventory=Eszköz törlése
 
 
+active=Aktív
+faulty=Hibás
+scrap=Selejt
 
 
 # Státuszok
 # Státuszok
-invarehouse=In Warehouse
-inservice=In Service
-infaulty=Faulty
-intransportation=In motion
-inoutside=Borrowed
+invarehouse=Raktárban
+inservice=Szervízben
+infaulty=Hibás
+intransportation=Mozgatás alatt
+inoutside=Kiadva
 
 
 #Státuszváltás
 #Státuszváltás
-inoutsidestatus=Borrowed (status change)
-inwarehousestatus=Active (státustatus changeszváltás)
-infaultystatus=Faulty (status change)
-inservicestatus=In service (status change)
+inoutsidestatus=Kiadva (státuszváltás)
+inwarehousestatus=Aktív (státuszváltás)
+infaultystatus=Hibás (státuszváltás)
+inservicestatus=Szervízben (státuszváltás)
 
 
 # Átszállítás
 # Átszállítás
-toservicestatus=To service
-towarehousestatus=(transfer)
-ItemHistorys=The history of the device
-
-Company=Company
-englishlabel=English label
-devicetype=Device type
-assigneddevice=Assigned device
-uniqueidentifier=Unique identifier
-fromwhere=From where
-where=Where
-fromstatus=From status
-tostatus=To status
-
-scraphandler = Scrap management
-DeviceId=Device
-minutes=Minutes
-FilePath=Minutes PDF
-ScrapHistorys=Scrap history
-FileUpload=File upload
-FileName=Download
-nofile=Upload a minutesfile
-nominutes=Set the minutes checkbox to yes if you attached a minute
-nopdf=The attachement can only be a PDF
-ScrapHistory=ScrapHistory
-
-PackageOut=Issuing packages from the warehouse
-PackageBack=Return of packages
-
+toservicestatus=Szervízbe
+towarehousestatus=(átszállítás)
+ItemHistorys=Eszköztörténet
+
+Company=Cégnév
+englishlabel=Angol megnevezés
+devicetype=Eszköztípus
+assigneddevice=Hozzárendelt eszköz
+uniqueidentifier=Egyedi azonosító
 From=Honnan
 From=Honnan
 To=Hova
 To=Hova
 FromStatus=Státuszból
 FromStatus=Státuszból
 ToStatus=Státuszba
 ToStatus=Státuszba
+
+scraphandler=Selejt kezelés
+DeviceId=Eszköz
+minutes=Jegyzőkönyv
+FilePath=Jegyzőkönyv PDF
+ScrapHistorys=Selejtezési történet
+FileUpload=Fájl feltöltés
+FileName=Letöltés
+nofile=Csatoljon fel jegyzőkönyvet
+nominutes=Állítsa a jegyzőkönyvet igen-re, ha csatolt egy jegyzőkönyv fájlt
+nopdf=A csatolmány csak PDF lehet
+ScrapHistory=Jegyzőkönyv
+
+PackageOut=Csomag kiadása
+PackageBack=Csomag visszavétel

+ 113 - 0
custom/rollerstorage/langs/hu_HU/rollerstorage.lang.bak

@@ -0,0 +1,113 @@
+# Copyright (C) 2023 László Szollősi
+#
+# 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.
+#
+# This 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 <https://www.gnu.org/licenses/>.
+
+#
+# Generic
+#
+
+# Module label 'ModuleStorageName'
+ModuleRollerstorageName = Storage
+# Module description 'ModuleStorageDesc'
+ModuleRollerstorageDesc = Storage description
+
+#
+# Admin page
+#
+RollerstorageSetup = Storage setup
+Settings = Settings
+RollerstorageSetupPage = Storage setup page
+ROLLERSTORAGE_MYPARAM1 = My param 1
+ROLLERSTORAGE_MYPARAM1Tooltip = My param 1 tooltip
+ROLLERSTORAGE_MYPARAM2=My param 2
+ROLLERSTORAGE_MYPARAM2Tooltip=My param 2 tooltip
+
+
+#
+# About page
+#
+About = About
+RollerstorageAbout = About Storage
+RollerstorageAboutPage = Storage about page
+
+#
+# Sample page
+#
+RollerstorageArea = Eszközök kezelése
+MyPageName = My page name
+
+#
+# Sample widget
+#
+MyWidget = My widget
+MyWidgetDescription = My widget description
+
+
+ListOfInventories=List of inventories
+Roller=Device
+Rollerhistory=The history of the device
+DeleteInventory=Delete
+
+active=Active
+faulty=Faulty
+scrap=Scrap
+
+
+# Státuszok
+invarehouse=In Warehouse
+inservice=In Service
+infaulty=Faulty
+intransportation=In motion
+inoutside=Borrowed
+
+#Státuszváltás
+inoutsidestatus=Borrowed (status change)
+inwarehousestatus=Active (státustatus changeszváltás)
+infaultystatus=Faulty (status change)
+inservicestatus=In service (status change)
+
+# Átszállítás
+toservicestatus=To service
+towarehousestatus=(transfer)
+ItemHistorys=The history of the device
+
+Company=Company
+englishlabel=English label
+devicetype=Device type
+assigneddevice=Assigned device
+uniqueidentifier=Unique identifier
+fromwhere=From where
+where=Where
+fromstatus=From status
+tostatus=To status
+
+scraphandler = Scrap management
+DeviceId=Device
+minutes=Minutes
+FilePath=Minutes PDF
+ScrapHistorys=Scrap history
+FileUpload=File upload
+FileName=Download
+nofile=Upload a minutesfile
+nominutes=Set the minutes checkbox to yes if you attached a minute
+nopdf=The attachement can only be a PDF
+ScrapHistory=ScrapHistory
+
+PackageOut=Issuing packages from the warehouse
+PackageBack=Return of packages
+
+From=Honnan
+To=Hova
+FromStatus=Státuszból
+ToStatus=Státuszba

+ 1 - 2
custom/settlements/class/daily_closing.class.php

@@ -341,7 +341,7 @@ class DailyClosing
             f.fk_user_author = {$user_id} AND 
             f.fk_user_author = {$user_id} AND 
             f.datec BETWEEN '{$startdate}' AND '{$now}'
             f.datec BETWEEN '{$startdate}' AND '{$now}'
         ORDER BY f.rowid DESC;";
         ORDER BY f.rowid DESC;";
-        //print $sql;
+
         $data = $db->query($sql);
         $data = $db->query($sql);
         while ($row = pg_fetch_assoc($data)) {
         while ($row = pg_fetch_assoc($data)) {
             if (!is_null($row['bbt_rowid']) && !is_null($row['bbtip_rowid'])) {
             if (!is_null($row['bbt_rowid']) && !is_null($row['bbtip_rowid'])) {
@@ -355,7 +355,6 @@ class DailyClosing
             }
             }
         }
         }
         $params = ["from" => $startdate, "to" => $now, "factures" => $crossShoppingFacturesString];
         $params = ["from" => $startdate, "to" => $now, "factures" => $crossShoppingFacturesString];
-        //print $crossShoppingFacturesString;
         $postFields = json_encode($params);
         $postFields = json_encode($params);
         $crossShoppingFactures = $this->curlRunner('bookingapi/getPrintedFacturesRefsArray', $postFields, 'POST', true);
         $crossShoppingFactures = $this->curlRunner('bookingapi/getPrintedFacturesRefsArray', $postFields, 'POST', true);
         if(!is_null($crossShoppingFactures)){
         if(!is_null($crossShoppingFactures)){

+ 91 - 19
custom/settlements/class/daily_closing.class.php.bak

@@ -1,6 +1,10 @@
 <?php
 <?php
+require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/api_curl.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/api_bbus_log.class.php';
 class DailyClosing
 class DailyClosing
 {
 {
+    use CurlApi;
+
     public function getChecked($deviceArray, $device)
     public function getChecked($deviceArray, $device)
     {
     {
         return $this->isChecked($deviceArray, $device) ? 'checked' : '';
         return $this->isChecked($deviceArray, $device) ? 'checked' : '';
@@ -245,20 +249,35 @@ class DailyClosing
     {
     {
         global $db, $langs;
         global $db, $langs;
         $to = date("Y-m-d H:i:s", dol_now());
         $to = date("Y-m-d H:i:s", dol_now());
-        $sql = "SELECT f.rowid, f.ref, e.label, f.datec, f.total_ttc, f.multicurrency_code, f.fk_statut
+        $sql = "SELECT f.rowid, f.ref, e.label, f.datec, f.total_ttc, f.multicurrency_code, f.fk_statut, bbt.rowid as bbt_rowid, bbtip.rowid as bbtip_rowid
         FROM llx_facture AS f
         FROM llx_facture AS f
         INNER JOIN llx_entity AS e ON e.rowid = f.entity
         INNER JOIN llx_entity AS e ON e.rowid = f.entity
+        LEFT JOIN llx_bbus_bbticket as bbt ON bbt.fk_facture = f.rowid
+        LEFT JOIN llx_bbus_bbticketinvoiceprinting as bbtip ON bbtip.invoice_number = f.ref
         WHERE 
         WHERE 
             f.fk_user_author = {$user_id} AND 
             f.fk_user_author = {$user_id} AND 
             f.datec >= (SELECT un.date_creation FROM public.llx_settlements_usernaplo AS un WHERE un.user_id = {$user_id} AND un.group_user_id = {$group_id} AND un.status = 1 
             f.datec >= (SELECT un.date_creation FROM public.llx_settlements_usernaplo AS un WHERE un.user_id = {$user_id} AND un.group_user_id = {$group_id} AND un.status = 1 
-            /*AND date_trunc('day', un.date_creation) = CURRENT_DATE*/ ORDER BY un.rowid LIMIT 1) AND f.datec BETWEEN '{$from}' AND '{$to}' 
-            AND NOT EXISTS (SELECT 1 FROM llx_bbus_bbticketinvoiceprinting AS b WHERE b.fk_facture = f.rowid) 
+             ORDER BY un.rowid LIMIT 1) AND f.datec BETWEEN '{$from}' AND '{$to}' 
+            /*AND NOT EXISTS (SELECT 1 FROM llx_bbus_bbticketinvoiceprinting AS b WHERE b.fk_facture = f.rowid)*/ 
         ORDER BY f.rowid DESC;";
         ORDER BY f.rowid DESC;";
         //print $sql;
         //print $sql;
         $data = $db->query($sql);
         $data = $db->query($sql);
         $result = pg_fetch_all($data);
         $result = pg_fetch_all($data);
+        $refs = "";
+        while($row = $db->fetch_object($result)){
+            if ($refs == "") {
+                $refs .= "'" . $row->ref . "'";
+            } else {
+                $refs .= ",'" . $row->ref . "'";
+            }
+        }
+        $params = ["from" => $from, "to" => $to, "factures" => $refs];
+        $postFields = json_encode($params);
+        $crossShoppingFactures = $this->curlRunner('bookingapi/getPrintedFacturesRefsArray', $postFields, 'POST', true);
+        //print_r($crossShoppingFactures);
         print '<table id="unprintedfactureslist" style="display:none; width:100%;">';
         print '<table id="unprintedfactureslist" style="display:none; width:100%;">';
         print '<tr class="center unprintedfacturetr">
         print '<tr class="center unprintedfacturetr">
+        <td style="width:15%;">' . $langs->trans('CS') . '</td>
         <td style="width:15%;">' . $langs->trans('Invoice') . '</td>
         <td style="width:15%;">' . $langs->trans('Invoice') . '</td>
         <td style="width:20%;">' . $langs->trans('Company') . '</td>
         <td style="width:20%;">' . $langs->trans('Company') . '</td>
         <td style="width:20%;">' . $langs->trans('Date creation') . '</td>
         <td style="width:20%;">' . $langs->trans('Date creation') . '</td>
@@ -268,7 +287,10 @@ class DailyClosing
         </tr>';
         </tr>';
         if (!empty($result)) {
         if (!empty($result)) {
             foreach ($result as $record) {
             foreach ($result as $record) {
-                print '<tr class="center">
+                $isCS = $this->checkCrossShopping($record['ref']) ? '<span class="fa fa-check"></span>' : '';
+                if (((is_null($record['bbt_rowid']) && is_null($record['bbtip_rowid'])) || (!is_null($record['bbt_rowid']) && is_null($record['bbtip_rowid']))) && !in_array($record['ref'], $crossShoppingFactures)) {
+                    print '<tr class="center">
+                <td>' . $isCS . '</td>
                 <td><a href="/compta/facture/card.php?facid=' . $record['rowid'] . '&save_lastsearch_values=1">' . $record['ref'] . '</a></td>
                 <td><a href="/compta/facture/card.php?facid=' . $record['rowid'] . '&save_lastsearch_values=1">' . $record['ref'] . '</a></td>
                 <td>' . $record['label'] . '</td>
                 <td>' . $record['label'] . '</td>
                 <td>' . $record['datec'] . '</td>
                 <td>' . $record['datec'] . '</td>
@@ -276,6 +298,7 @@ class DailyClosing
                 <td>' . $record['multicurrency_code'] . '</td>
                 <td>' . $record['multicurrency_code'] . '</td>
                 <td>' . $this->setStatut($record['fk_statut']) . '</td>
                 <td>' . $this->setStatut($record['fk_statut']) . '</td>
                 </tr>';
                 </tr>';
+                }
             }
             }
         } else {
         } else {
             print '<tr><td style="color:red; text-align:center;" colspan="5">' . $langs->trans('Empty') . '</td></tr>';
             print '<tr><td style="color:red; text-align:center;" colspan="5">' . $langs->trans('Empty') . '</td></tr>';
@@ -283,24 +306,65 @@ class DailyClosing
         print '</table>';
         print '</table>';
     }
     }
 
 
-    function printedFactures($group_id, $user_id)
+    private function checkCrossShopping($facture_id){
+        global $db, $conf;
+        $sql = "SELECT bbs.server_host FROM llx_facture as f 
+            INNER JOIN llx_facturedet as fdet ON fdet.fk_facture = f.rowid
+            INNER JOIN llx_product_extrafields as pre ON pre.fk_object = fdet.fk_product
+            INNER JOIN llx_bbus_basicservices as bbs ON bbs.rowid = cast(pre.basic_service as integer)
+            WHERE f.ref = '{$facture_id}'
+            GROUP BY bbs.server_host";
+        $result = $db->query($sql);
+        if($db->num_rows($result) > 0){
+            while($row = $db->fetch_object($result)){
+                //print $facture_id . ' -> ' . $row->server_host . ' - ' . $conf->global->CURL_SERVER_HOST . '<br>';
+                return $row->server_host == $conf->global->CURL_SERVER_HOST;
+            }
+        }
+        return false;
+
+    }
+
+    function printedFactures($user_id, $date_creation)
     {
     {
         global $db, $langs;
         global $db, $langs;
+        $startdate = date("Y-m-d H:i:s", $date_creation);
         $now = date("Y-m-d H:i:s", dol_now());
         $now = date("Y-m-d H:i:s", dol_now());
         $array = [];
         $array = [];
-        $sql = "SELECT f.rowid
+        $crossShoppingFacturesString = "";
+        $sql = "SELECT f.rowid, bbt.rowid as bbt_rowid, bbtip.rowid as bbtip_rowid, f.ref
         FROM llx_facture AS f
         FROM llx_facture AS f
         INNER JOIN llx_entity AS e ON e.rowid = f.entity
         INNER JOIN llx_entity AS e ON e.rowid = f.entity
+        LEFT JOIN llx_bbus_bbticket as bbt ON bbt.fk_facture = f.rowid
+        LEFT JOIN llx_bbus_bbticketinvoiceprinting as bbtip ON bbtip.invoice_number = f.ref
         WHERE 
         WHERE 
             f.fk_user_author = {$user_id} AND 
             f.fk_user_author = {$user_id} AND 
-            f.datec >= (SELECT un.date_creation FROM public.llx_settlements_usernaplo AS un WHERE un.user_id = {$user_id} AND un.group_user_id = {$group_id} AND un.status = 1 
-            ORDER BY un.rowid LIMIT 1) AND f.datec <= '{$now}'
-            AND EXISTS (SELECT 1 FROM llx_bbus_bbticketinvoiceprinting AS b WHERE b.fk_facture = f.rowid) 
+            f.datec BETWEEN '{$startdate}' AND '{$now}'
         ORDER BY f.rowid DESC;";
         ORDER BY f.rowid DESC;";
         //print $sql;
         //print $sql;
         $data = $db->query($sql);
         $data = $db->query($sql);
         while ($row = pg_fetch_assoc($data)) {
         while ($row = pg_fetch_assoc($data)) {
-            $array[] = $row['rowid'];
+            if (!is_null($row['bbt_rowid']) && !is_null($row['bbtip_rowid'])) {
+                $array[] = $row['rowid'];
+            } else {
+                if ($crossShoppingFacturesString == "") {
+                    $crossShoppingFacturesString .= "'" . $row['ref'] . "'";
+                } else {
+                    $crossShoppingFacturesString .= ",'" . $row['ref'] . "'";
+                }
+            }
+        }
+        $params = ["from" => $startdate, "to" => $now, "factures" => $crossShoppingFacturesString];
+        //print $crossShoppingFacturesString;
+        $postFields = json_encode($params);
+        $crossShoppingFactures = $this->curlRunner('bookingapi/getPrintedFacturesRefsArray', $postFields, 'POST', true);
+        if(!is_null($crossShoppingFactures)){
+            $data = $db->query($sql);
+            while ($row2 = pg_fetch_assoc($data)) {
+                if (in_array($row2['ref'], $crossShoppingFactures)) {
+                    $array[] = $row2['rowid'];
+                }
+            }
         }
         }
         return $array;
         return $array;
     }
     }
@@ -327,17 +391,25 @@ class DailyClosing
         global $db;
         global $db;
         $array = [];
         $array = [];
         $number = 0;
         $number = 0;
-        $sql = "SELECT tip.fk_facture, tip.product_id, count(tip.product_id)  FROM llx_bbus_bbticketinvoiceprinting as tip
+        $sql = "SELECT tip.fk_facture, tip.product_id, count(tip.product_id), invoice_number  FROM llx_bbus_bbticketinvoiceprinting as tip
         WHERE tip.fk_facture = {$facture_id}
         WHERE tip.fk_facture = {$facture_id}
-        GROUP BY tip.fk_facture, tip.product_id";
+        GROUP BY tip.fk_facture, tip.product_id, invoice_number";
         $data = $db->query($sql);
         $data = $db->query($sql);
-        while ($row = $db->fetch_object($data)) {
-            $array[$row->fk_facture][$row->product_id] = $row->count;
+        if ($db->num_rows($data) > 0) {
+            while ($row = $db->fetch_object($data)) {
+                $array[$row->fk_facture][$row->product_id] = $row->count;
+            }
+            $firstKey = array_key_first($array);
+            $firstValue = $array[$firstKey];
+            $number = reset($firstValue);
+        } else {
+            $factureObj = new Facture($db);
+            $result = $factureObj->fetch($facture_id);
+            $invoice_number = $factureObj->ref;
+            $params = ["invoice_number" => $invoice_number];
+            $postFields = json_encode($params);
+            $number = $this->curlRunner('bookingapi/getFacturesNumberOfPrints', $postFields, 'POST', true);
         }
         }
-        $firstKey = array_key_first($array);
-        $firstValue = $array[$firstKey];
-        $number = reset($firstValue);
         return $number > 1 ? '<div style="color:red;">' . $number . '</div>' : '<div>' . $number . '</div>';
         return $number > 1 ? '<div style="color:red;">' . $number . '</div>' : '<div>' . $number . '</div>';
     }
     }
-
-}
+}

+ 0 - 1
custom/settlements/class/helper.class.php

@@ -585,7 +585,6 @@ class Helper
         $sql = "SELECT gtp.rowid, gtp.fk_package, pa.ref FROM " . MAIN_DB_PREFIX . "settlements_grouptoolspackages as gtp
         $sql = "SELECT gtp.rowid, gtp.fk_package, pa.ref FROM " . MAIN_DB_PREFIX . "settlements_grouptoolspackages as gtp
             INNER JOIN " . MAIN_DB_PREFIX . "settlements_package as pa ON pa.rowid = gtp.fk_package
             INNER JOIN " . MAIN_DB_PREFIX . "settlements_package as pa ON pa.rowid = gtp.fk_package
             WHERE gtp.fk_group = {$id} ORDER BY pa.ref ASC";
             WHERE gtp.fk_group = {$id} ORDER BY pa.ref ASC";
-            //print $sql;exit;
         $data = $db->query($sql);
         $data = $db->query($sql);
         if (!$data) {
         if (!$data) {
             dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
             dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);

+ 2540 - 0
custom/settlements/class/helper.class.php.bak

@@ -0,0 +1,2540 @@
+<?php
+
+require_once DOL_DOCUMENT_ROOT . '/product/inventory/class/inventory.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/logoutchangenaplo.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/settlements/class/packagenaplo.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/settlements/class/package.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/settlements/class/grouptools.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/settlements/class/group.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/settlements/class/package_additionals.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/financialreport/class/userinvoice.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/rollerstorage/class/packagehistory.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/rollerstorage/class/statuses.class.php';
+
+
+
+class Helper
+{
+    public $db;
+    public $langs;
+
+    public function __construct(DoliDB $db)
+    {
+        global $langs;
+        $this->db = $db;
+        $this->langs = $langs;
+    }
+
+    function getNumberOfUsers()
+    {
+        $userCounter = [];
+        $sql = "SELECT su.fk_group_tools_id, su.fk_groupid, count(sgu.rowid) as usercount FROM " . MAIN_DB_PREFIX . "settlements_usergrouptoolgroup AS su
+        INNER JOIN " . MAIN_DB_PREFIX . "settlements_groupusers AS sgu ON sgu.fk_settlements_group = su.fk_groupid
+        GROUP BY su.fk_groupid, su.fk_group_tools_id";
+        $data = $this->db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('queryFail', '(Function $helper->getNumberOfUsers()) llx_settlements_usergrouptoolgroup'), 'errors');
+            return $userCounter;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $userCounter[$row['fk_group_tools_id']] = [$row['usercount'], $row['fk_groupid']];
+        }
+        return $userCounter;
+
+    }
+
+    function getNumberOfDevices()
+    {
+        $deviceCounter = [];
+        $sql = "SELECT pt.package_id, count(pt.device_id) FROM " . MAIN_DB_PREFIX . "settlements_packagetool AS pt group by pt.package_id";
+        //print $sql;
+        $data = $this->db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('queryFail', '($helper->getNumberOfDevices()) queryFailpackagetool'), 'errors');
+            return $deviceCounter;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $deviceCounter[$row['package_id']] = $row['count'];
+        }
+        return $deviceCounter;
+    }
+
+    function createPopoupBox($numberOfUsers, $usersArray, $id)
+    {
+        $popoupBox = '<div style="float:right; padding-bottom: 10px;" title="';
+        foreach ($usersArray as $users) {
+            $popoupBox .= '<span class=&quot;fas fa-user  em080&quot; style=&quot; color: #a69944;&quot; cursor: pointer;></span> 
+            <u class=&quot;paddingrightonly&quot;>' . $users['lastname'] . ' ' . $users['firstname'] . ' (' . $users['login'] . ')</u><br>';
+        }
+        $popoupBox .= '" class="classfortooltip"><div onclick="popupboxClick(' . $id . ')" class="groupColumn2ndLine">' . $numberOfUsers . '</div>';
+        return $popoupBox;
+    }
+
+    function createPopoupBoxForDeviceList($number, $array)
+    {
+        $popupBox = '';
+        $not115 = false;
+        $statusesObj = new Statuses($this->db);
+        $result = $statusesObj->getStatusIds($this->db);
+        if ($number != '') {
+            $popupBox = '<div style="float:right; cursor:pointer;" title="';
+            foreach ($array as $record) {
+                if ($record['status'] != 115) {
+                    $not115 = true;
+                }
+                $statusdisplay = '<span class=&quot;badge  badge-status' . $record['status'] . ' badge-status&quot; title=&quot;' . $result[$record['status']] . '&quot;>' . $result[$record['status']] . '</span>';
+                $popupBox .= '<span class=&quot;fas fa-warehouse  em080&quot; style=&quot; color: #a69944;&quot; cursor: pointer;></span> 
+                <u class=&quot;paddingrightonly&quot; style=&quot;text-decoration: none;&quot;>' . $record['ref'] . ' (' . $record['title'] . ') - ' . $statusdisplay . '</u><br>';
+            }
+            $popupBox .= '" class="classfortooltip">' . $number . '</div>';
+            if ($not115) {
+                $popupBox .= '<div style=text-align:right;>&nbsp;<span class="fas fa-exclamation" style="color: red;" cursor: pointer;></span>&nbsp;</div>';
+            }
+        }
+
+        return $popupBox;
+    }
+
+    function getGroupsFromGroupToolsClass($db, $selectedEntities)
+    {
+        $groups = [];
+        $sql = "SELECT sgt.rowid, sgt.ref, e.label FROM " . MAIN_DB_PREFIX . "settlements_grouptools AS sgt
+        INNER JOIN " . MAIN_DB_PREFIX . "entity as e ON e.rowid=sgt.fk_entity";
+        if ($selectedEntities != '') {
+            $sql .= " AND sgt.fk_entity IN ({$selectedEntities})";
+        }
+        $sql .= " AND sgt.rowid NOT IN (SELECT ugtg.fk_group_tools_id FROM " . MAIN_DB_PREFIX . "settlements_usergrouptoolgroup as ugtg INNER JOIN " . MAIN_DB_PREFIX . "settlements_group as g ON g.rowid = ugtg.fk_groupid WHERE g.hotelgroup is true)
+         ORDER BY sgt.ref ASC";
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('queryFail', '($helper->getGroupsFromGroupToolsClass()) llx_settlements_grouptools'), 'errors');
+            return $groups;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            //$groups[$row['rowid']] = $row['ref'];
+            $groups[] = $row;
+        }
+        return $groups;
+    }
+
+    function getFilteredpackageGroups($string, $selectedEntities)
+    {
+        global $db;
+        $groups = [];
+        $sql = "SELECT sgt.rowid, sgt.ref, e.label FROM " . MAIN_DB_PREFIX . "settlements_grouptools AS sgt
+        INNER JOIN " . MAIN_DB_PREFIX . "entity as e ON e.rowid=sgt.fk_entity WHERE sgt.ref LIKE '%{$string}%'";
+        if ($selectedEntities != '') {
+            $sql .= " AND sgt.fk_entity IN ({$selectedEntities})";
+        }
+        $sql .= " AND sgt.rowid NOT IN (SELECT ugtg.fk_group_tools_id FROM " . MAIN_DB_PREFIX . "settlements_usergrouptoolgroup as ugtg INNER JOIN " . MAIN_DB_PREFIX . "settlements_group as g ON g.rowid = ugtg.fk_groupid WHERE g.hotelgroup is true)
+         ORDER BY sgt.ref ASC";
+        //print $sql;exit;
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('queryFail', '($helper->getFilteredpackageGroups()) llx_settlements_grouptools'), 'errors');
+            return $groups;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $groups[] = $row;
+        }
+        return $groups;
+
+    }
+
+    function getPackagesFromPackageClass($db, $selectedEntities)
+    {
+        $groups = [];
+        $sql = "SELECT pac.rowid, pac.ref, e.label as entity FROM " . MAIN_DB_PREFIX . "settlements_package AS pac
+        INNER JOIN " . MAIN_DB_PREFIX . "entity as e ON e.rowid=pac.fk_entity";
+        if ($selectedEntities != '') {
+            $sql .= " AND pac.fk_entity IN ({$selectedEntities})";
+        }
+        $sql .= " ORDER BY pac.ref ASC";
+        //print $sql;
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getPackagesFromPackageClass()) llx_settlements_package'), 'errors');
+            return $groups;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            //$groups[$row['rowid']] = $row['ref'];
+            $groups[] = $row;
+        }
+        return $groups;
+    }
+
+    function getAllGroupsFromGroupClass($db)
+    {
+        $groups = [];
+        $sql = "SELECT rowid, ref FROM " . MAIN_DB_PREFIX . "settlements_group  ORDER BY ref ASC";
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getAllGroupsFromGroupClass()) llx_settlements_group'), 'errors');
+            return $groups;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $groups[$row['rowid']] = $row['ref'];
+        }
+        return $groups;
+    }
+
+    function getGroupsFromGroupClass($db, $selectedEntities)
+    {
+        $groups = [];
+        $sql = "SELECT sg.rowid, sg.ref, e.label FROM " . MAIN_DB_PREFIX . "settlements_group AS sg 
+        INNER JOIN " . MAIN_DB_PREFIX . "entity as e ON e.rowid=sg.fk_entity WHERE sg.single_user_group is null AND sg.hotelgroup is null";
+        if ($selectedEntities != '') {
+            $sql .= " AND sg.fk_entity IN ({$selectedEntities})";
+        }
+        $sql .= " ORDER BY sg.ref ASC";
+        //print $sql;
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getGroupsFromGroupClass()) llx_settlements_group'), 'errors');
+            return $groups;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            //$groups[$row['rowid']] = $row['ref'];
+            $groups[] = $row;
+        }
+        return $groups;
+    }
+
+    public function getGroupRefByID($id)
+    {
+        global $db;
+        if (isset($id)) {
+            $sql = "SELECT ref FROM " . MAIN_DB_PREFIX . "settlements_group WHERE rowid = {$id}";
+            $data = $db->query($sql);
+            if (!$data) {
+                dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            }
+            if (pg_num_rows($data) > 0) {
+                while ($row = pg_fetch_assoc($data)) {
+                    return $row['ref'];
+                }
+            }
+        }
+        return '';
+    }
+
+    function getFilteredGroups($string, $selectedEntities)
+    {
+        global $db;
+        $string = strtoupper($string);
+        $filteredGroups = [];
+        $sql = "SELECT sg.rowid, sg.ref, e.label FROM " . MAIN_DB_PREFIX . "settlements_group AS sg 
+            INNER JOIN " . MAIN_DB_PREFIX . "entity as e ON e.rowid=sg.fk_entity WHERE sg.single_user_group is null AND sg.hotelgroup is null
+             AND sg.ref LIKE '%{$string}%'";
+        if ($selectedEntities != '') {
+            $sql .= " AND sg.fk_entity IN ({$selectedEntities})";
+        }
+        $sql .= " ORDER BY sg.ref ASC";
+        //print $sql;
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $filteredGroups[] = $row;
+        }
+        return $filteredGroups;
+    }
+
+    function getHotelGroupsFromGroupClass($db, $selectedEntities)
+    {
+        $groups = [];
+        $sql = "SELECT sg.rowid, sg.ref, e.label FROM " . MAIN_DB_PREFIX . "settlements_group AS sg 
+        INNER JOIN " . MAIN_DB_PREFIX . "entity as e ON e.rowid=sg.fk_entity";
+        if ($selectedEntities != '') {
+            $sql .= " AND fk_entity IN ({$selectedEntities})";
+        }
+        $sql .= " WHERE sg.hotelgroup is NOT null  ORDER BY sg.ref ASC";
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getHotelGroupsFromGroupClass()) llx_settlements_group'), 'errors');
+            return $groups;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $groups[$row['rowid']] = $row['ref'];
+            //$groups[] = $row;
+        }
+        return $groups;
+    }
+
+    function getSingleUserGroupsFromGroupClass($db)
+    {
+        $groups = [];
+        $sql = "SELECT rowid, ref FROM " . MAIN_DB_PREFIX . "settlements_group WHERE single_user_group is not null ORDER BY ref ASC";
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getSingleUserGroupsFromGroupClass()) llx_settlements_group'), 'errors');
+            return $groups;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $groups[$row['rowid']] = $row['ref'];
+        }
+        return $groups;
+    }
+
+    function getAllTools($db)
+    {
+        $allTools = [];
+        $sql = "SELECT i.rowid, i.ref, i.title FROM " . MAIN_DB_PREFIX . "inventory as i WHERE rowid NOT IN (SELECT fk_inventory FROM " . MAIN_DB_PREFIX . "settlements_grouptoolstools) ORDER BY i.ref";
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getAllTools()) llx_inventory'), 'errors');
+            return $allTools;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $allTools[] = $row;
+        }
+        return $allTools;
+    }
+
+    function getAllToolsFromSelectedEntity($db, $id)
+    {
+        $entity_id = $this->getEntityIdFromPackage($id);
+        $allTools = [];
+        $sql = "SELECT i.rowid, i.ref, i.title, ie.device_type, ie2.fk_object, i.status, i.fk_warehouse
+        FROM " . MAIN_DB_PREFIX . "inventory as i 
+        INNER JOIN " . MAIN_DB_PREFIX . "inventory_extrafields as ie ON ie.fk_object = i.rowid 
+        LEFT JOIN " . MAIN_DB_PREFIX . "inventory_extrafields AS ie2 ON ie2.assigned_device::integer = i.rowid
+        WHERE i.rowid NOT IN (SELECT device_id FROM " . MAIN_DB_PREFIX . "settlements_packagetool) AND ie.device_type::integer NOT IN (3,4) AND ie.fk_entity::integer = {$entity_id}  ORDER BY i.rowid";
+        //print $sql;
+        $data = $db->query($sql);
+
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getAllToolsFromSelectedEntity()) llx_inventory'), 'errors');
+            return $allTools;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $allTools['freeTools'][$row['rowid']] = $row;
+            if (isset($row['fk_object'])) {
+                $inventoryObj = new Inventory($db);
+                $inventoryObj->fetch($row['fk_object']);
+                $assigned_device_data = ['rowid' => $inventoryObj->id, 'title' => $inventoryObj->title, 'ref' => $inventoryObj->ref, 'device_type' => $inventoryObj->array_options['options_device_type'], 'status' => $inventoryObj->status, 'warehouse' => $inventoryObj->fk_warehouse];
+                $allTools['freeTools'][$row['rowid']]['assigned_device_data'] = $assigned_device_data;
+            }
+        }
+        $sql = "SELECT i.rowid, i.ref, i.title, ie.device_type, ie2.fk_object, i.status, (SELECT ref FROM " . MAIN_DB_PREFIX . "settlements_package as package WHERE package.rowid = pt.package_id) as package_ref, pt.package_id as packageid, i.fk_warehouse
+        FROM " . MAIN_DB_PREFIX . "inventory as i 
+        INNER JOIN " . MAIN_DB_PREFIX . "inventory_extrafields as ie ON ie.fk_object = i.rowid 
+        INNER JOIN " . MAIN_DB_PREFIX . "settlements_packagetool AS pt ON pt.device_id=i.rowid
+        LEFT JOIN " . MAIN_DB_PREFIX . "inventory_extrafields AS ie2 ON ie2.assigned_device::integer = i.rowid
+        WHERE i.rowid IN (SELECT device_id FROM " . MAIN_DB_PREFIX . "settlements_packagetool) AND ie.device_type::integer NOT IN (3,4) AND ie.fk_entity::integer = {$entity_id}  ORDER BY i.rowid";
+        //print $sql;
+        $data = $db->query($sql);
+
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getAllToolsFromSelectedEntity()) llx_inventory'), 'errors');
+            return $allTools;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $allTools['addedTools'][$row['packageid']][$row['rowid']] = $row;
+            if (isset($row['fk_object'])) {
+                $inventoryObj = new Inventory($db);
+                $inventoryObj->fetch($row['fk_object']);
+                $assigned_device_data = ['rowid' => $inventoryObj->id, 'title' => $inventoryObj->title, 'ref' => $inventoryObj->ref, 'device_type' => $inventoryObj->array_options['options_device_type'], 'status' => $inventoryObj->status, 'warehouse' => $inventoryObj->fk_warehouse];
+                $allTools['addedTools'][$row['packageid']][$row['rowid']]['assigned_device_data'] = $assigned_device_data;
+            }
+            $allTools['addedPackages'][$row['packageid']] = $row['package_ref'];
+        }
+        return $allTools;
+    }
+
+    function getAllPackagesFromSelectedEntity($id, $selectedEntities = '')
+    {
+        $entity_id = $this->getEntityIdFromgoupTools($id);
+        $allPackages = [];
+        $sql = "SELECT pa.rowid, pa.ref, pa.label
+        FROM " . MAIN_DB_PREFIX . "settlements_package as pa 
+        WHERE pa.rowid NOT IN (SELECT fk_package FROM " . MAIN_DB_PREFIX . "settlements_grouptoolspackages)";
+        if ($selectedEntities != '') {
+            $sql .= " AND pa.fk_entity IN ({$selectedEntities})";
+        }
+        $sql .= " AND pa.fk_entity = '{$entity_id}' ORDER BY pa.ref";
+        //print $sql;
+        //exit;
+
+        $data = $this->db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getAllPackagesFromSelectedEntity()) llx_settlements_package'), 'errors');
+            return $allPackages;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $allPackages['freePackages'][$row['rowid']] = $row;
+        }
+
+        $sqlAddedPackages = "SELECT pa.rowid, pa.ref, pa.label, gp.rowid as gprowid, gp.ref as gpref, gp.label as gplabel FROM " . MAIN_DB_PREFIX . "settlements_grouptoolspackages as gpp
+        INNER JOIN " . MAIN_DB_PREFIX . "settlements_package as pa ON pa.rowid = gpp.fk_package
+        INNER JOIN " . MAIN_DB_PREFIX . "settlements_grouptools as gp ON gp.rowid = gpp.fk_group";
+        $data2 = $this->db->query($sqlAddedPackages);
+        if (!$data2) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getAllPackagesFromSelectedEntity()) settlements_grouptoolspackages'), 'errors');
+            return $allPackages;
+        }
+        while ($row = pg_fetch_assoc($data2)) {
+            $allPackages['addedPackages'][] = $row;
+
+        }
+
+        return $allPackages;
+    }
+
+    function getEntityIdFromgoupTools($id)
+    {
+        $entity = [];
+        $sql = "SELECT fk_entity FROM " . MAIN_DB_PREFIX . "settlements_grouptools WHERE rowid = {$id}";
+        //print $sql;
+        $data = $this->db->query($sql);
+
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getEntityIdFromgoupTools()) llx_settlements_grouptools'), 'errors');
+            return $entity;
+        }
+        while ($row = pg_fetch_array($data)) {
+            $entity[] = $row['fk_entity'];
+        }
+        return $entity[0];
+    }
+
+    function getEntityIdFromPackage($id)
+    {
+        $entity = [];
+        $sql = "SELECT fk_entity FROM " . MAIN_DB_PREFIX . "settlements_package WHERE rowid = {$id}";
+        $data = $this->db->query($sql);
+
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getEntityIdFromPackage()) llx_settlements_package'), 'errors');
+            return $entity;
+        }
+        while ($row = pg_fetch_array($data)) {
+            $entity[] = $row['fk_entity'];
+        }
+        return $entity[0];
+    }
+
+    function getAllUsers($db)
+    {
+        $allUsers = [];
+        $sql = "SELECT u.rowid, u.login, u.firstname, u.lastname, ue.nickname, ue.user_category FROM " . MAIN_DB_PREFIX . "user as u 
+        INNER JOIN " . MAIN_DB_PREFIX . "user_extrafields AS ue ON ue.fk_object = u.rowid
+        WHERE ue.user_category = '1' AND u.rowid NOT IN (SELECT fk_user FROM " . MAIN_DB_PREFIX . "settlements_groupusers) 
+        ORDER BY ue.nickname";
+        $data = $db->query($sql);
+        //print $sql;
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getAllUsers()) llx_user'), 'errors');
+            return $allUsers;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $row['openDailyClosing'] = 0;
+            $dailyclosingSql = "SELECT * FROM llx_rollerstorage_packagehistory WHERE user_id = {$row['rowid']} AND status = 0 ORDER BY rowid DESC LIMIT 1";
+            $dailyclosingData = $db->query($dailyclosingSql);
+            if ($db->num_rows($dailyclosingData) > 0) {
+                $dCRow = $db->fetch_object($dailyclosingData);
+                $row['openDailyClosing'] = $dCRow->rowid;
+            }
+
+            $allUsers['freeUsers'][] = $row;
+        }
+        $sqlAddedUsers = "SELECT gu.fk_user, u.firstname, u.lastname, u.login, ue.nickname, sg.ref as groupref, sg.rowid as groupid
+        FROM " . MAIN_DB_PREFIX . "settlements_groupusers as gu
+        INNER JOIN " . MAIN_DB_PREFIX . "user as u ON u.rowid = gu.fk_user
+        INNER JOIN " . MAIN_DB_PREFIX . "user_extrafields as ue ON gu.fk_user = ue.fk_object 
+		INNER JOIN " . MAIN_DB_PREFIX . "settlements_group as sg ON sg.rowid = gu.fk_settlements_group
+		ORDER BY ue.nickname";
+        //print $sql;
+        $dataAddedUser = $db->query($sqlAddedUsers);
+        if (!$dataAddedUser) {
+            return $allUsers;
+        }
+        while ($rowAddedUser = pg_fetch_assoc($dataAddedUser)) {
+            $allUsers['addedUsers'][] = $rowAddedUser;
+        }
+        //print_r($allUsers);exit;
+
+        return $allUsers;
+    }
+
+    function getAllUsersForEdit($user_id)
+    {
+        global $db;
+        $allUsers = [];
+        //$sql = "SELECT u.rowid, u.login, u.firstname, u.lastname FROM " . MAIN_DB_PREFIX . "user as u ORDER BY u.lastname";
+        $sql = "SELECT u.rowid, u.login, u.firstname, u.lastname, ue.nickname, ue.user_category FROM " . MAIN_DB_PREFIX . "user as u 
+        INNER JOIN " . MAIN_DB_PREFIX . "user_extrafields AS ue ON ue.fk_object = u.rowid
+        WHERE ue.user_category = '1'";
+        if ($user_id) {
+            $sql .= " AND u.rowid NOT IN (SELECT fk_user FROM " . MAIN_DB_PREFIX . "settlements_groupusers WHERE fk_user != $user_id)";
+        }
+        $sql .= " ORDER BY u.lastname";
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getAllUsersForEdit()) llx_user'), 'errors');
+            return $allUsers;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $allUsers['freeUsers'][] = $row;
+        }
+        return $allUsers;
+    }
+
+    function getAllHotelsForEdit($hotel_id)
+    {
+        global $db;
+        $allHotels = [];
+        $sql = "SELECT rowid, label FROM " . MAIN_DB_PREFIX . "settlements_hotel
+        WHERE status = 1
+        ORDER BY label ASC";
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getAllHotelsForEdit()) llx_user'), 'errors');
+            return $allHotels;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $allHotels['freeHotels'][] = $row;
+        }
+        return $allHotels;
+    }
+
+    function getFilteredUsers($db, $string)
+    {
+        $allUsers = [];
+        $sql = "SELECT * FROM " . MAIN_DB_PREFIX . "user as u WHERE rowid NOT IN (SELECT fk_user FROM " . MAIN_DB_PREFIX . "settlements_groupusers) AND (u.lastname LIKE '%{$string}%' OR u.firstname LIKE '%{$string}%') ORDER BY u.lastname";
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            return $allUsers;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $allUsers[] = $row;
+        }
+        return $allUsers;
+    }
+
+    function getFilteredTools($db, $string)
+    {
+        $allUsers = [];
+        $sql = "SELECT * FROM " . MAIN_DB_PREFIX . "inventory as i WHERE rowid NOT IN (SELECT fk_inventory FROM " . MAIN_DB_PREFIX . "settlements_grouptools) AND i.ref LIKE '%{$string}%' ORDER BY i.ref";
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            return $allUsers;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $allUsers[] = $row;
+        }
+        return $allUsers;
+    }
+
+
+    function getToolsById($db, $id)
+    {
+        $array = [];
+        $sql = "SELECT gtt.rowid, i.ref, i.title, iextra.unique_identifier, iextra.device_type, gtt.device_id, ie2.fk_object, i.status, i.fk_warehouse 
+        FROM " . MAIN_DB_PREFIX . "settlements_packagetool as gtt 
+        INNER JOIN " . MAIN_DB_PREFIX . "inventory as i ON i.rowid = gtt.device_id 
+        LEFT JOIN " . MAIN_DB_PREFIX . "inventory_extrafields AS iextra ON iextra.fk_object = i.rowid 
+        LEFT JOIN " . MAIN_DB_PREFIX . "inventory_extrafields AS ie2 ON ie2.assigned_device::integer = i.rowid 
+        WHERE package_id = {$id} ORDER BY i.ref ASC";
+        //print $sql;
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getToolsById()) llx_settlements_packagetool'), 'errors');
+            return $array;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            if (isset($row['fk_object'])) {
+                $inventoryObj = new Inventory($db);
+                $inventoryObj->fetch($row['fk_object']);
+                $assigned_device_data = ['rowid' => $inventoryObj->id, 'title' => $inventoryObj->title, 'ref' => $inventoryObj->ref, 'device_type' => $inventoryObj->array_options['options_device_type'], 'status' => $inventoryObj->status, 'warehouse' => $inventoryObj->fk_warehouse];
+            }
+            $array[$row['rowid']] = $row;
+            $array[$row['rowid']]['assigned_device_data'] = $assigned_device_data;
+            //$array[] = $row;
+        }
+        return $array;
+    }
+
+    function getPackagesById($id)
+    {
+        global $db;
+        $array = [];
+        $sql = "SELECT gtp.rowid, gtp.fk_package, pa.ref FROM " . MAIN_DB_PREFIX . "settlements_grouptoolspackages as gtp
+            INNER JOIN " . MAIN_DB_PREFIX . "settlements_package as pa ON pa.rowid = gtp.fk_package
+            WHERE gtp.fk_group = {$id} ORDER BY pa.ref ASC";
+            //print $sql;exit;
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getPackagesById()) llx_settlements_grouptoolspackages'), 'errors');
+            return $array;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $array[] = $row;
+        }
+        return $array;
+    }
+
+    function getGroupIdBygroupToolId($id)
+    {
+        global $db;
+        $array = [];
+        if (isset($id)) {
+            $sql = "SELECT fk_groupid
+            FROM " . MAIN_DB_PREFIX . "settlements_usergrouptoolgroup
+            WHERE fk_group_tools_id = {$id}";
+            $data = $db->query($sql);
+            if (!$data) {
+                dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+                setEventMessage($this->langs->trans('($helper->getGroupIdBygroupToolId()) llx_settlements_usergrouptoolgroup'), 'errors');
+                return $array;
+            }
+            $array = pg_fetch_assoc($data);
+            return $array['fk_groupid'];
+        }
+        return $array;
+    }
+
+    function getUsersById($db, $id)
+    {
+        $usersOfGroup = [];
+        $sql = "SELECT sug.rowid, u.login, u.lastname, u.firstname, sug.fk_user, u.api_key FROM " . MAIN_DB_PREFIX . "settlements_groupusers as sug
+            INNER JOIN " . MAIN_DB_PREFIX . "user as u ON u.rowid = sug.fk_user
+            WHERE fk_settlements_group = {$id}
+            ORDER BY u.lastname ASC";
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            //setEventMessage($this->langs->trans('($helper->getUsersById()) llx_settlements_groupusers'), 'errors');
+            return $usersOfGroup;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $usersOfGroup[] = $row;
+        }
+        return $usersOfGroup;
+    }
+
+    function getDevicesById($db, $id)
+    {
+        $devicesOfGroup = [];
+        $sql = "SELECT pt.rowid, pt.device_id, i.title, i.ref, i.status FROM " . MAIN_DB_PREFIX . "settlements_packagetool AS pt 
+        INNER JOIN " . MAIN_DB_PREFIX . "inventory as i ON i.rowid = pt.device_id
+        WHERE pt.package_id = {$id}";
+        //print $sql;
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage('A csoporthoz rendelt felhasználók lekérdezésébe valami hiba csúszott.', 'errors');
+            return $devicesOfGroup;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $devicesOfGroup[] = $row;
+        }
+        return $devicesOfGroup;
+    }
+
+    function getUsersByIdWithDate($db, $id, $date)
+    {
+        $usersOfGroup = [];
+        $sql = "SELECT un.user_id, u.firstname as firstname, u.lastname as lastname, u.login as login FROM " . MAIN_DB_PREFIX . "settlements_usernaplo AS un
+            INNER JOIN " . MAIN_DB_PREFIX . "user as u ON u.rowid = un.user_id
+            WHERE un.group_user_id = {$id} AND un.date_creation BETWEEN '{$date} 00:00:00' AND '{$date} 23:59:59' AND un.status = 1 
+            GROUP BY un.user_id, u.firstname, u.lastname, u.login ORDER BY u.lastname";
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage('A csoporthoz rendelt felhasználók naplózási lekérdezésébe valami hiba csúszott.', 'errors');
+            return $usersOfGroup;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $usersOfGroup[] = $row;
+        }
+        return $usersOfGroup;
+    }
+
+    function getUsersOfGroupsFromNaploToday($db, $id)
+    {
+        $users = [];
+        $now = date('Y-m-d', dol_now());
+        $nowDatetime = date('Y-m-d H:i:s', dol_now());
+        $sql = "SELECT user_id FROM " . MAIN_DB_PREFIX . "settlements_usernaplo WHERE group_user_id = {$id} AND status = 1 AND date_creation BETWEEN '{$now} 05:00:00' AND '{$now} 23:59:59' GROUP BY user_id";
+        //$sql = "SELECT user_id FROM " . MAIN_DB_PREFIX . "settlements_usernaplo WHERE group_user_id = {$id} AND status = 1 AND date_creation < '{$nowDatetime}' GROUP BY user_id";
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No users found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            //setEventMessage('A csoporthoz rendelt felhasználók naplózási lekérdezésébe valami hiba csúszott.', 'errors');
+            return $users;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $users[] = $row['user_id'];
+        }
+        return $users;
+    }
+
+    function getToolsFromNaploToday($db, $id)
+    {
+        $tools = [];
+        $now = date('Y-m-d', dol_now());
+        $sql = "SELECT tool_id FROM " . MAIN_DB_PREFIX . "settlements_toolnaplo WHERE group_tool_id = {$id} AND status = 1 AND date_creation BETWEEN '{$now} 00:00:00' AND '{$now} 23:59:59' GROUP BY tool_id";
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No tool found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage('A csoporthoz rendelt eszközök naplózási lekérdezésébe valami hiba csúszott.', 'errors');
+            return $tools;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $tools[] = $row['user_id'];
+        }
+        return $tools;
+    }
+
+    function confirmButtonCheck($array1, $array2)
+    {
+        return empty(array_diff($array1, $array2));
+    }
+
+    function getSum($db, $currency, $id, $users, $date = null)
+    {
+        $sum = [];
+        foreach ($users as $user) {
+            $usersArray[] = $user['user_id'];
+        }
+        $usersString = implode(',', $usersArray);
+        $sql = "SELECT SUM(total_ht) as total_ht, SUM(total_tva) as total_tva, SUM(total_ttc) as total_ttc 
+            FROM " . MAIN_DB_PREFIX . "facture 
+            WHERE fk_user_closing IN({$usersString}) 
+            AND fk_statut = 2 
+            AND multicurrency_code = '{$currency}' 
+            AND date_closing BETWEEN '{$date} 00:00:00' AND '{$date} 23:59:59'";
+        $data = $db->query($sql);
+
+        if (!$data) {
+            dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage('A számlák összesítésének számításába valami hiba csúszott.', 'errors');
+            return $sum;
+        }
+        $dataArray = pg_fetch_all($data);
+        foreach ($dataArray as $row) {
+            $sum[] = $row;
+        }
+        return $sum;
+    }
+
+    function getDeletedUsers($db, $id, $date)
+    {
+        $deletedUsersArray = [];
+        $sql = "SELECT user_id, MAX(date_creation) as date FROM " . MAIN_DB_PREFIX . "settlements_usernaplo WHERE group_user_id = {$id} and date_creation BETWEEN '{$date} 00:00:00' AND '{$date} 23:59:59' AND status = 0 GROUP BY user_id ";
+        $data = $db->query($sql);
+        $dataArray = pg_fetch_all($data);
+        if (empty($dataArray)) {
+            dol_syslog("No data found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            return $deletedUsersArray;
+        }
+        foreach ($dataArray as $row) {
+            $deletedUsersArray[$row['user_id']] = $row['date'];
+        }
+        return $deletedUsersArray;
+    }
+
+    function correctNumber($number)
+    {
+        $integerPart = floor($number);
+        $formattedNumber = number_format($integerPart, 0, '.', ' ');
+        return $formattedNumber;
+    }
+
+    function createArray($daterange)
+    {
+        $dates = explode(" - ", $daterange);
+        $startDate = new DateTime($dates[0]);
+        $endDate = new DateTime($dates[1]);
+
+        $dateArray = array();
+
+        $currentDate = clone $startDate;
+        while ($currentDate <= $endDate) {
+            $dateArray[] = $currentDate->format('Y-m-d');
+            $currentDate->modify('+1 day');
+        }
+
+        return $dateArray;
+    }
+
+    function createDataArray($id, $action, $userId)
+    {
+        $data['id'] = $id;
+        $data['action'] = $action;
+        $data['userid'] = $userId;
+        return $data;
+    }
+
+    function createDataToolArray($id, $action, $toolid)
+    {
+        $data['id'] = $id;
+        $data['action'] = $action;
+        $data['toolid'] = $toolid;
+        return $data;
+    }
+
+    function getAllEntities()
+    {
+        $entitiesArray = [];
+        $sql = "SELECT rowid, label FROM " . MAIN_DB_PREFIX . "entity ORDER BY label ASC";
+        $data = $this->db->query($sql);
+        while ($row = pg_fetch_assoc($data)) {
+            $entitiesArray[$row['rowid']] = $row['label'];
+        }
+        return $entitiesArray;
+    }
+
+    function getEntityDataById($id)
+    {
+        $entity_id = $this->getEntityIdFromPackage($id);
+        $entitiArray = [];
+        $sql = "SELECT name, value FROM " . MAIN_DB_PREFIX . "const
+        WHERE entity = {$entity_id}
+        AND name IN('MAIN_INFO_SOCIETE_ZIP', 'MAIN_INFO_SOCIETE_TOWN', 'MAIN_INFO_SOCIETE_ADDRESS', 'MAIN_INFO_SOCIETE_NOM', 'MAIN_INFO_TVAINTRA')
+        ORDER BY rowid DESC";
+
+        $data = $this->db->query($sql);
+        if (!$data) {
+            dol_syslog("No tool found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage('Nincs ilyen cég.', 'errors');
+            return $entitiArray;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $entitiArray[$row['name']] = $row['value'];
+        }
+        return $entitiArray;
+
+    }
+
+    function createHTML($id)
+    {
+        $printbuttonData = explode('_', $id);
+
+        $bpcard = $printbuttonData[2];
+        $dandc = $printbuttonData[3];
+        $riverride = $printbuttonData[4];
+
+        global $user;
+        global $conf;
+        global $db;
+        global $langs;
+
+        $entity = $this->getEntityDataById($printbuttonData[0]);
+        $devicesArray = $this->getDevicesById($db, $printbuttonData[0]);
+        $userDataObj = $this->getUserData($printbuttonData[1]);
+        $address = $userDataObj->town != '' ? $userDataObj->zip . ' ' . $userDataObj->town . ', ' . $userDataObj->address : '';
+
+        $result = '<table style="width:100%;"><tr><td style="width:50%;"><b>' . $langs->trans('transferingUserData') . '</b></td><td style="width:50%; text-align: right;"><b>' . $langs->trans('receivingUserData') . '</b></td></tr>';
+        $result .= '<tr><td>' . $user->firstname . ' ' . $user->lastname . '</td><td  style="text-align: right;">' . $userDataObj->firstname . ' ' . $userDataObj->lastname . '</td></tr>';
+        $result .= '<tr><td>' . $entity['MAIN_INFO_SOCIETE_NOM'] . '</td><td  style="text-align: right;"></td></tr>';
+        $result .= '<tr><td>' . $entity['MAIN_INFO_TVAINTRA'] . '</td><td  style="text-align: right;">' . $userDataObj->array_options['options_tax_identification_number'] . '</td></tr>';
+        $result .= '<tr><td>' . $entity['MAIN_INFO_SOCIETE_ZIP'] . ', ' . $entity['MAIN_INFO_SOCIETE_TOWN'] . '</td><td  style="text-align: right;">' . $address . '</td></tr>';
+        $result .= '<tr><td>' . $entity['MAIN_INFO_SOCIETE_ADDRESS'] . '</td><td  style="text-align: right;"></td></tr>';
+        $result .= '</table>';
+        $result .= '<div style="width:100%; text-align: center;">' . date('Y.m.d H:i:s') . '</div>';
+        $result .= '<table style="width:100%; text-align:right;">';
+        $count = 1;
+        foreach ($devicesArray as $device) {
+            $result .= '<tr><td style="width: 5%;">' . $count . '</td><td style="text-align: left; width: 30%;">' . $device['ref'] . '</td><td style="text-align: left; width: 55%;"> (' . $device['title'] . ')</td><td style="width:15%;">1 ' . $langs->trans('Pieces') . '</td></tr>';
+            $result .= '<tr><td style="width: 5%;">&nbsp;</td><td colspan="2" style="text-align: center; width: 100%;"> ' . $device['unique_identifier'] . '</td></tr>';
+            $count++;
+        }
+        $changes = $this->getChanges();
+        if ($changes) {
+            foreach ($changes as $change) {
+                $tmpArray = explode('_', $change['ref']);
+                $result .= '<tr><td style="width: 5%;">' . $count . '</td><td style="text-align: left; width: 30%;">' . str_replace("_", " ", $change['ref']) . '</td><td style="text-align: left; width: 60%;"> ' . $this->correctNumber($change['title']) . ' ' . $tmpArray[1] . '</td><td style="width:10%;"></td></tr>';
+                $result .= '<tr><td style="width: 5%;">&nbsp;</td><td colspan="2" style="text-align: center; width: 100%;">&nbsp;</td></tr>';
+                $count++;
+            }
+        }
+        $result .= '<tr><td style="width: 5%;">' . $count . '</td><td style="text-align: left; width: 30%;">Budapest Card</td><td style="text-align: left; width: 60%;"> ' . $bpcard . '</td><td style="width:10%;">' . $langs->trans('Pieces') . '</td></tr>';
+        $result .= '<tr><td style="width: 5%;">&nbsp;</td><td colspan="2" style="text-align: center; width: 100%;">&nbsp;</td></tr>';
+        $count++;
+        $result .= '<tr><td style="width: 5%;">' . $count . '</td><td style="text-align: left; width: 30%;">Dinner & Cruise</td><td style="text-align: left; width: 60%;"> ' . $dandc . '</td><td style="width:10%;"></td></tr>';
+        $result .= '<tr><td style="width: 5%;">&nbsp;</td><td colspan="2" style="text-align: center; width: 100%;">&nbsp;</td></tr>';
+        $count++;
+        $result .= '<tr><td style="width: 5%;">' . $count . '</td><td style="text-align: left; width: 30%;">RiverRide</td><td style="text-align: left; width: 60%;"> ' . $riverride . '</td><td style="width:10%;"></td></tr>';
+        $result .= '<tr><td style="width: 5%;">&nbsp;</td><td colspan="2" style="text-align: center; width: 100%;">&nbsp;</td></tr>';
+        $result .= '</table>';
+        $result .= '<div style="width:100%; text-align: left;">' . date('Y.m.d H:i:s') . '</div>';
+        $result .= '<div style="padding-top: 100px; height: 100px;">&nbsp;</div>';
+        $result .=
+            '<table style="width:100%;">
+            <tr>
+                <td style="width:50%; text-align:left;">_________________________________</td>
+                <td style="width:50%; text-align:right;">_________________________________</td>
+            </tr>
+            <tr>
+                <td style="width:50%; text-align: center;">' . $langs->trans('transferingUser') . '</td>
+                <td style="width:50%; text-align: center;">' . $langs->trans('receivingUser') . '</td>
+            </tr>
+        </table>';
+        return $result;
+    }
+
+    function createHTMLIncome($id, $BLock3rdData, $withholdingArray, $additionals)
+    {
+        //print_r($withholdingArray);
+        $witholdings = $this->createWitholdings($withholdingArray);
+
+        $printbuttonData = explode('_', $id);
+        global $user, $langs, $conf, $db;
+        $entity = $this->getEntityDataById($printbuttonData[0]);
+        $devicesArray = $this->getDevicesById($db, $printbuttonData[0]);
+        $userDataObj = $this->getUserData($printbuttonData[1]);
+        $address = $userDataObj->town != '' ? $userDataObj->zip . ' ' . $userDataObj->town . ', ' . $userDataObj->address : '';
+        #
+        #   Fejléc
+        #
+        $result = '<table style="width:100%; border-collapse: collapse; border: 1px solid #000;"><tr><td style="width:50%; padding-left: 20px;"><b>' . $langs->trans('transferingUserData') . '</b></td><td style="width:50%; text-align: right; padding-right: 20px;"><b>' . $langs->trans('receivingUserData') . '</b></td></tr>';
+        $result .= '<tr><td style="padding-left: 20px;">' . $userDataObj->firstname . ' ' . $userDataObj->lastname . '</td><td  style="text-align: right; padding-right: 20px;">' . $user->firstname . ' ' . $user->lastname . '</td></tr>';
+        $result .= '<tr><td></td><td  style="text-align: right; padding-right: 20px;">' . $entity['MAIN_INFO_SOCIETE_NOM'] . '</td></tr>';
+        $result .= '<tr><td style="padding-left: 20px;">' . $userDataObj->array_options['options_tax_identification_number'] . '</td><td  style="text-align: right; padding-right: 20px;">' . $entity['MAIN_INFO_TVAINTRA'] . '</td></tr>';
+        $result .= '<tr><td style="padding-left: 20px;">' . $address . '</td><td  style="text-align: right; padding-right: 20px;">' . $entity['MAIN_INFO_SOCIETE_ZIP'] . ', ' . $entity['MAIN_INFO_SOCIETE_TOWN'] . '</td></tr>';
+        $result .= '<tr><td></td><td style="text-align: right; padding-right: 20px;">' . $entity['MAIN_INFO_SOCIETE_ADDRESS'] . '</td></tr>';
+        $result .= '</table>';
+        $result .= '<div style="width:100%; text-align: center;">' . date('Y.m.d H:i:s') . '</div>';
+        $result .= '<table style="width:100%; text-align:right;">';
+        $result .= '<tr><td colspan="3" style="text-align: center; font-weight:bold;">' . $langs->trans('Devices') . '</td></tr>';
+        #
+        #   Tartalom
+        #
+        $count = 1;
+        foreach ($devicesArray as $device) {
+            $withholding1 = $witholdings[$device['device_id']] == '' ? '' : $langs->trans('withhold') . ' ' . $witholdings[$device['device_id']] . ' HUF';
+            $result .= '<tr><td style="width: 5%; text-align: left;">' . $count . '</td><td style="text-align: left; width: 30%;">' . $device['ref'] . '</td><td style="text-align: left; width: 55%;"> (' . $device['title'] . ')</td><td style="width:10%;">1 ' . $langs->trans('pcs') . '</td></tr>';
+            $result .= '<tr><td style="width: 5%;">&nbsp;</td><td style="width: 30%;">&nbsp;</td><td style="text-align: left;">' . $withholding1 . '</td></tr>';
+            $count++;
+        }
+        //print_r($additionals);exit;
+        $withholding1 = $witholdings['bp_card'] == '' ? '' : $langs->trans('withhold') . ' ' . $witholdings['bp_card'] . ' HUF';
+        $result .= '<tr><td style="width: 5%; text-align: left;">' . $count . '</td><td style="text-align: left; width: 30%;">' . $this->getAdditionalTitle('bp_card') . '</td><td style="text-align: left; width: 55%;"> ' . $additionals['bp_card']['pieces'] . '</td><td style="width:10%;">&nbsp;</td></tr>';
+        $result .= '<tr><td style="width: 5%;">&nbsp;</td><td style="width: 30%;">&nbsp;</td><td style="text-align: left; background-color: grey;">' . $withholding1 . '</td></tr>';
+        $count++;
+        $withholding1 = $witholdings['dnc_ticket'] == '' ? '' : $langs->trans('withhold') . ' ' . $witholdings['dnc_ticket'] . ' HUF';
+        $result .= '<tr><td style="width: 5%; text-align: left;">' . $count . '</td><td style="text-align: left; width: 30%;">' . $this->getAdditionalTitle('dnc_ticket') . '</td><td style="text-align: left; width: 55%;"> ' . $additionals['dnc_ticket']['pieces'] . '</td><td style="width:10%;">&nbsp;</td></tr>';
+        $result .= '<tr><td style="width: 5%;">&nbsp;</td><td style="width: 30%;">&nbsp;</td><td style="text-align: left; background-color: grey;">' . $withholding1 . '</td></tr>';
+        $count++;
+        $withholding1 = $witholdings['rr_ticket'] == '' ? '' : $langs->trans('withhold') . ' ' . $witholdings['rr_ticket'] . ' HUF';
+        $result .= '<tr><td style="width: 5%; text-align: left;">' . $count . '</td><td style="text-align: left; width: 30%;">' . $this->getAdditionalTitle('rr_ticket') . '</td><td style="text-align: left; width: 55%;"> ' . $additionals['rr_ticket']['pieces'] . '</td><td style="width:10%;">&nbsp;</td></tr>';
+        $result .= '<tr><td style="width: 5%;">&nbsp;</td><td style="width: 30%;">&nbsp;</td><td style="text-align: left; background-color: grey;">' . $withholding1 . '</td></tr>';
+        $count++;
+
+        $result .= '<tr><td colspan="3" style="text-align: center; font-weight:bold;">' . $langs->trans('Changes') . '</td></tr>';
+        $changes = $this->getChanges();
+        if ($changes) {
+            foreach ($changes as $change) {
+                $tmpArray = explode('_', $change['ref']);
+                $result .= '<tr><td style="width: 5%; text-align: left;">' . $count . '</td><td style="text-align: left; width: 30%;">' . str_replace("_", " ", $change['ref']) . '</td><td style="text-align: left; width: 55%;"> ' . $this->correctNumber($change['title']) . ' ' . $tmpArray[1] . '</td><td style="width:10%;"></td></tr>';
+                $result .= '<tr><td style="width: 5%;">&nbsp;</td><td style="width: 30%;">&nbsp;</td><td style="text-align: left;">&nbsp;</td></tr>';
+                $count++;
+            }
+        }
+        $result .= '<tr><td colspan="3" style="text-align: center; font-weight:bold;">' . $langs->trans('Incomes') . '</td></tr>';
+        //print_r($BLock3rdData);exit;
+        foreach ($BLock3rdData as $key => $value) {
+            $withholding2 = $witholdings['daily_' . $key] == '' ? '' : $langs->trans('withhold') . ' ' . $witholdings['daily_' . $key] . ' HUF';
+            $keyIncomes = $this->getIncomesKey($key);
+            $keyValue = $this->getValueKey($key);
+            $result .= '<tr><td style="width: 5%; text-align: left;">' . $count . '</td><td style="text-align: left; width: 30%;">' . $langs->trans('todaysIncomes') . ' (' . $langs->trans($keyIncomes) . ')</td><td style="text-align: left; width: 55%;">' . $this->correctNumber($value) . ' ' . $keyValue . '</td><td style="width:10%;"></td></tr>';
+            if ($keyIncomes == 'Cash') {
+                $result .= '<tr><td style="width: 5%;">&nbsp;</td><td style="width: 30%;">&nbsp;</td><td style="text-align: left; background-color: grey;">' . $withholding2 . '</td></tr>';
+            } else {
+                $result .= '<tr><td style="width: 5%;">&nbsp;</td><td style="width: 30%;">&nbsp;</td><td style="text-align: left;">&nbsp;</td></tr>';
+            }
+            $count++;
+        }
+        $result .= '</table>';
+        $result .= '<div style="height: 20px;">&nbsp;</div>';
+        $result .= '<div style="width:100%; text-align: left;">' . date('Y.m.d H:i:s') . '</div>';
+        $result .= '<div style="padding-top: 50px; height: 20px;">&nbsp;</div>';
+        $result .=
+            '<table style="width:100%;">
+            <tr>
+                <td style="width:50%; text-align:left;">_________________________________</td>
+                <td style="width:50%; text-align:right;">_________________________________</td>
+            </tr>
+            <tr>
+                <td style="width:50%; text-align: center;">' . $langs->trans('transferingUser') . '</td>
+                <td style="width:50%; text-align: center;">' . $langs->trans('receivingUser') . '</td>
+            </tr>
+        </table>';
+        return $result;
+    }
+
+    private function createWitholdings($withholdingArray)
+    {
+        foreach ($withholdingArray as $whkey => $whvalue) {
+            if ($whkey !== 'daily_HUF' && $whkey !== 'daily_EUR') {
+                $witholdings[$this->getDeviceIdFromString($whkey)] = $whvalue;
+            } else {
+                $witholdings[$whkey] = $whvalue;
+            }
+        }
+        return $witholdings;
+    }
+
+    function getValueKey($key)
+    {
+        return strpos($key, 'HUF') !== false ? 'HUF' : 'EUR';
+    }
+
+    function getIncomesKey($key)
+    {
+        return strpos($key, 'cash') !== false ? 'Cash' : 'Card';
+    }
+
+    function getUserData($user_id)
+    {
+        global $db;
+        $userObj = new User($db);
+        $result = $userObj->fetch($user_id);
+        return $userObj;
+
+    }
+
+    function getUserName($id)
+    {
+        $db = $this->db;
+        $sql = "SELECT u.lastname, u.firstname, u.login FROM " . MAIN_DB_PREFIX . "settlements_groupusers AS sg 
+        INNER JOIN " . MAIN_DB_PREFIX . "user AS u ON u.rowid = sg.fk_user
+        WHERE sg.fk_settlements_group = {$id} ORDER BY sg.rowid LIMIT 1";
+        $data = $db->query($sql);
+        $dataArray = pg_fetch_all($data);
+        $name = $dataArray[0]['lastname'] . ' ' . $dataArray[0]['firstname'] . ' (' . $dataArray[0]['login'] . ')';
+        return $name;
+    }
+
+    function getHotelName($id)
+    {
+        $db = $this->db;
+        $sql = "SELECT h.label FROM " . MAIN_DB_PREFIX . "settlements_grouphotels AS sgh 
+        INNER JOIN " . MAIN_DB_PREFIX . "settlements_hotel AS h ON h.rowid = sgh.fk_hotel_id
+        WHERE sgh.fk_group_id = {$id} ORDER BY sgh.rowid DESC LIMIT 1";
+        $data = $db->query($sql);
+        $dataArray = pg_fetch_all($data);
+        $name = $dataArray[0]['label'];
+        return $name;
+    }
+
+    function getSelectedUserId($id)
+    {
+        $db = $this->db;
+        $sql = "SELECT u.rowid FROM " . MAIN_DB_PREFIX . "settlements_groupusers AS sg 
+        INNER JOIN " . MAIN_DB_PREFIX . "user AS u ON u.rowid = sg.fk_user
+        WHERE sg.fk_settlements_group = {$id} ORDER BY sg.rowid LIMIT 1";
+        $data = $db->query($sql);
+        $dataArray = pg_fetch_all($data);
+        return $dataArray[0]['rowid'];
+    }
+
+    function getSelectedHotelId($id)
+    {
+        $db = $this->db;
+        $sql = "SELECT h.rowid FROM " . MAIN_DB_PREFIX . "settlements_grouphotels AS sgh 
+        INNER JOIN " . MAIN_DB_PREFIX . "settlements_hotel AS h ON h.rowid = sgh.fk_hotel_id 
+        WHERE sgh.fk_group_id = {$id} ORDER BY sgh.rowid DESC LIMIT 1";
+        $data = $db->query($sql);
+        $dataArray = pg_fetch_all($data);
+        return $dataArray[0]['rowid'];
+    }
+
+    function getGroupuserId($id)
+    {
+        $db = $this->db;
+        $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "settlements_groupusers WHERE fk_settlements_group = {$id} ORDER BY rowid DESC LIMIT 1";
+        $data = $db->query($sql);
+        $dataArray = pg_fetch_all($data);
+        return $dataArray[0]['rowid'];
+    }
+
+    function getGrouphotelsId($id)
+    {
+        $db = $this->db;
+        $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "settlements_grouphotels WHERE fk_group_id = {$id} ORDER BY rowid DESC LIMIT 1";
+        $data = $db->query($sql);
+        $dataArray = pg_fetch_all($data);
+        return $dataArray[0]['rowid'];
+    }
+
+    function getGroupuserIdByUserId($id)
+    {
+        $db = $this->db;
+        $sql = "SELECT fk_settlements_group FROM " . MAIN_DB_PREFIX . "settlements_groupusers WHERE fk_user = {$id} ORDER BY rowid DESC LIMIT 1";
+        $data = $db->query($sql);
+        $dataArray = pg_fetch_all($data);
+        return $dataArray[0]['fk_settlements_group'];
+    }
+
+    /**
+     * Output the buttons to submit a creation/edit form
+     *
+     * @param   string  $save_label     	Alternative label for save button
+     * @param   string  $cancel_label   	Alternative label for cancel button
+     * @param   array   $morebuttons    	Add additional buttons between save and cancel
+     * @param   bool    $withoutdiv     	Option to remove enclosing centered div
+     * @param	string	$morecss			More CSS
+     * @param	string	$dol_openinpopup	If the button are shown in a context of a page shown inside a popup, we put here the string name of popup.
+     * @return 	string						Html code with the buttons
+     */
+    public function buttonsSaveCancel($save_label = 'Save', $cancel_label = 'Cancel', $cancelURL = '', $morebuttons = array(), $withoutdiv = 0, $morecss = '', $dol_openinpopup = '')
+    {
+        global $langs;
+
+        $buttons = array();
+
+        $save = array(
+            'name' => 'save',
+            'label_key' => $save_label,
+        );
+
+        if ($save_label == 'Create' || $save_label == 'Add') {
+            $save['name'] = 'add';
+        } elseif ($save_label == 'Modify') {
+            $save['name'] = 'edit';
+        }
+
+        $cancel = array(
+            'name' => 'cancel',
+            'label_key' => 'Cancel',
+        );
+
+        !empty($save_label) ? $buttons[] = $save : '';
+
+        if (!empty($morebuttons)) {
+            $buttons[] = $morebuttons;
+        }
+        $retstring = $withoutdiv ? '' : '<div class="center">';
+
+        foreach ($buttons as $button) {
+            $addclass = empty($button['addclass']) ? '' : $button['addclass'];
+            $retstring .= '<input type="submit" class="button button-' . $button['name'] . ($morecss ? ' ' . $morecss : '') . ' ' . $addclass . '" name="' . $button['name'] . '" value="' . dol_escape_htmltag($langs->trans($button['label_key'])) . '">';
+        }
+
+        if ($cancel_label == "Cancel") {
+            $retstring .= '<a class="button button-' . $cancel['name'] . '" href="' . dol_buildpath($cancelURL, 1) . /*'?restore_lastsearch_values=1' .*/ (!empty($socid) ? '&socid=' . $socid : '') . '">' . $langs->trans($cancel['label_key']) . '</a>';
+        }
+
+        $retstring .= $withoutdiv ? '' : '</div>';
+
+        if ($dol_openinpopup) {
+            $retstring .= '<!-- buttons are shown into a $dol_openinpopup=' . $dol_openinpopup . ' context, so we enable the close of dialog on cancel -->' . "\n";
+            $retstring .= '<script>';
+            $retstring .= 'jQuery(".button-cancel").click(function(e) {
+				e.preventDefault(); console.log(\'We click on cancel in iframe popup ' . $dol_openinpopup . '\');
+				window.parent.jQuery(\'#idfordialog' . $dol_openinpopup . '\').dialog(\'close\');
+				 });';
+            $retstring .= '</script>';
+        }
+
+        return $retstring;
+    }
+
+    function createButtonContent($db, $id, $toolsOfGroups, $confirmButtonDisplay, $PrintButtonDisplay)
+    {
+        global $langs;
+        if (empty($this->getToolsFromNaploToday($db, $id)) && !empty($toolsOfGroups)) {
+            return '<tr style="width=100%; height:40px;"><td colspan="3" class="center"><button class="btn" name="confirmbutton" value="1" onclick="groupconfirm()" 
+            style="width:100%; height:45px; cursor:pointer; background-color: #98FB98; ' . $confirmButtonDisplay . '">' . $langs->trans('Confirm') . '</button></td></tr>';
+        }
+        if (!empty($toolsOfGroups)) {
+            return '<tr style="width=100%; height:40px;"><td colspan="3" class="center"><button class="btn" name="printbutton" value="1" onclick="" 
+            style="width:100%; height:45px; cursor:pointer; background-color: yellow; ' . $PrintButtonDisplay . '">' . $langs->trans('Print') . '</button></td></tr>';
+        }
+    }
+
+    function massactionDelete()
+    {
+        global $langs;
+        return '
+        <table class="valid centpercent">
+        <tbody><tr class="validtitre"><td class="validtitre" colspan="2"><span class="fas fa-question" style=""></span> ' . $langs->trans('MassDeleteConfirm') . '</td></tr>
+        <tr class="valid"><td class="valid" colspan="2">
+        <tr class="valid"><td class="valid">' . $langs->trans('MassDeletConfirmContent') . '</td><td class="valid center"><select class="flat width75 marginleftonly marginrightonly" id="confirm" name="confirm">
+        <option value="delete">' . $langs->trans('Yes') . '</option>
+        <option value="no" selected="">' . $langs->trans('No') . '</option>
+        </select>
+        <input class="button valignmiddle confirmvalidatebutton small" type="submit" value="' . $langs->trans('Confirm') . '"></td></tr>
+        </tbody></table>
+        ';
+    }
+
+    function confirmButtonConfirmeText()
+    {
+        global $langs;
+        return '
+        <table class="valid centpercent">
+        <tbody><tr class="validtitre"><td class="validtitre" colspan="2"><span class="fas fa-question" style=""></span>' . $langs->trans('MassConfirm') . '</td></tr>
+        <tr class="valid"><td class="valid" colspan="2">
+        <tr class="valid"><td class="valid">' . $langs->trans('MassConfirmContent') . '</td><td class="valid center"><select class="flat width75 marginleftonly marginrightonly" id="confirmtools" name="confirmtools">
+        <option value="confirm">' . $langs->trans('Yes') . '</option>
+        <option value="no" selected="">' . $langs->trans('No') . '</option>
+        </select>
+        <input class="button valignmiddle confirmvalidatebutton small" type="submit" value="' . $langs->trans('Confirm') . '"></td></tr>
+        </tbody></table>
+        ';
+    }
+
+    function saveToolsData($object, $package_id, $device_id, $langs, $massactionadd)
+    {
+        global $user;
+        $toolNaplo = new ToolNaplo($this->db);
+        $object->package_id = $package_id;
+        $object->device_id = $device_id;
+        $result = $object->create($user);
+        if (!$result) {
+            $error = pg_last_error($this->db);
+            dol_syslog("Nem sikerult a packagetools tabla mentese.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($langs->trans("error"), 'errors');
+        } else {
+            $data = $this->createDataToolArray($package_id, $massactionadd, $device_id);
+            $toolNaplo->createToolsNaplo($user, $data);
+        }
+
+    }
+
+    function savePackageData($grouptoolsPackages, $fk_group, $fk_package, $langs)
+    {
+        global $user;
+        $packageNaplo = new PackageNaplo($this->db);
+        $grouptoolsPackages->fk_group = $fk_group;
+        $grouptoolsPackages->fk_package = $fk_package;
+        $result = $grouptoolsPackages->create($user);
+        if (!$result) {
+            $error = pg_last_error($this->db);
+            dol_syslog("Nem sikerult a grouptoolsPackages tabla mentese.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($langs->trans("duplicate"), 'errors');
+        } else {
+            $data = $this->createDataToolArray($fk_group, 1, $fk_package);
+            $packageNaplo->createNaplo($user, $data);
+        }
+
+    }
+
+    function getListOfUsersRowid($data)
+    {
+        $rowidArray = [];
+        while ($row = pg_fetch_assoc($data)) {
+            $rowidArray[$row['rowid']]['fk_settlements_group'] = $row['fk_settlements_group'];
+            $rowidArray[$row['rowid']]['fk_user'] = $row['fk_user'];
+        }
+        return !empty($rowidArray) ? $rowidArray : '';
+    }
+
+    function getListOfToolsRowid($data)
+    {
+        $rowidArray = [];
+        foreach ($data as $tool) {
+            $rowidArray[$tool->id]['fk_group'] = $tool->fk_group;
+            $rowidArray[$tool->id]['fk_inventory'] = $tool->fk_inventory;
+        }
+        return $rowidArray;
+    }
+
+    function getListOfPackagesRowid($data)
+    {
+        $rowidArray = [];
+        foreach ($data as $tool) {
+            $rowidArray[$tool->id]['fk_group'] = $tool->fk_group;
+            $rowidArray[$tool->id]['fk_package'] = $tool->fk_package;
+        }
+        return $rowidArray;
+    }
+
+    function getListOfUsersFromTheGroups()
+    {
+        $sql = "SELECT rowid, fk_settlements_group, fk_user FROM " . MAIN_DB_PREFIX . "settlements_groupusers
+	WHERE fk_settlements_group NOT IN(SELECT rowid FROM " . MAIN_DB_PREFIX . "settlements_group WHERE single_user_group IS NOT NULL OR hotelgroup IS NOT NULL)
+    ORDER BY rowid ASC";
+        //print $sql;exit;
+        $data = $this->db->query($sql);
+        return $data;
+    }
+
+    function getListOfUsersFromTheGroupTable()
+    {
+        $data = $this->getListOfUsersFromTheGroups();
+        if (pg_num_rows($data) > 0) {
+            $rows = pg_fetch_all($data);
+            return $rows;
+        }
+        return [];
+    }
+
+    function userGroupsAreEmpty()
+    {
+        $data = $this->getListOfUsersFromTheGroups();
+        return pg_num_rows($data) == 0;
+    }
+
+
+    function getListOfToolsFromTheGroups()
+    {
+        $allObj = new PackageTool($this->db);
+        $result = $allObj->fetchAll();
+        return $result;
+    }
+
+    function getListOfPackagesFromTheGroups()
+    {
+        $allObj = new GrouptoolsPackages($this->db);
+        $result = $allObj->fetchAll();
+        return $result;
+    }
+
+    function toolGroupsAreEmpty()
+    {
+        $data = $this->getListOfToolsFromTheGroups();
+        return count($data) == 0;
+    }
+
+    function packageGroupsAreEmpty()
+    {
+        $data = $this->getListOfPackagesFromTheGroups();
+        return $data > 0 ? count($data) == 0 : true;
+    }
+
+    function createUserNaplo($record)
+    {
+        global $user;
+        $userNaploObj = new UserNaplo($this->db);
+        $userNaploObj->user_id = $record->fk_user;
+        $userNaploObj->group_user_id = $record->fk_settlements_group;
+        $userNaploObj->status = 0;
+        $insertResult = $userNaploObj->create($user);
+        return $insertResult;
+    }
+
+    function createToolNaplo($record)
+    {
+        global $user;
+        $toolNaploObj = new ToolNaplo($this->db);
+        $toolNaploObj->tool_id = $record->device_id;
+        $toolNaploObj->group_tool_id = $record->package_id;
+        $toolNaploObj->status = 0;
+        return $toolNaploObj->create($user);
+    }
+
+    function createPackageNaplo($record)
+    {
+        global $user;
+        $packageNaploObj = new PackageNaplo($this->db);
+        $packageNaploObj->package_id = $record->fk_package;
+        $packageNaploObj->group_tool_id = $record->fk_group;
+        $packageNaploObj->status = 0;
+        return $packageNaploObj->create($user);
+    }
+
+    function deleteLine($object, $key)
+    {
+        global $user;
+        return $object->deleteline($user, $key);
+    }
+
+    function returnWindowLocation($url, $id, $idmenu)
+    {
+        echo '<script type="text/javascript">window.location.href="' . $url . '?id=' . $id . '&idmenu=' . $idmenu . '";</script>';
+    }
+
+    function returnDailyClosingWindowLocation($url, $id, $user_id, $idmenu)
+    {
+        echo '<script type="text/javascript">window.location.href="' . $url . '?id=' . $id . '&user_id=' . $user_id . '&idmenu=' . $idmenu . '";</script>';
+    }
+
+    function returnDailyClosingHistoryWindowLocation($url, $id, $user_id, $idmenu)
+    {
+        echo '<script type="text/javascript">window.location.href="' . $url . '?id=' . $id . '&user_id=' . $user_id . '&idmenu=' . $idmenu . '";</script>';
+    }
+
+    function getAllSalesWithSQL($userObj, $sql)
+    {
+        $salesUsers = [];
+        $result = $this->db->query($sql);
+        while ($row = pg_fetch_assoc($result)) {
+            $salesUsers[] = $row;
+        }
+        return $salesUsers;
+    }
+
+    function tableDrawer($allSalesUsers, $db, $idmenu)
+    {
+        $rownum = 0;
+        foreach ($allSalesUsers as $user) {
+            $url = '/custom/settlements/userloginnaplo_list.php?user_id=' . $user['rowid'] . '&idmenu=' . $idmenu . '&mainmenu=settlements&leftmenu=';
+            $bgcolor = $this->setRowColor($rownum);
+            print '<tr style="height:30px; background-color: ' . $bgcolor . '">
+            <td><a style="display: block; width: 100%; height: 100%;" href="' . $url . '">' . $user['lastname'] . ' ' . $user['firstname'] . '</a></td>';
+            print '<td style="text-align: center;">' . $user['nickname'] . '</td>';
+            print '<td style="text-align: center;">' . $user['login'] . '</td>';
+            print '</tr>';
+            $rownum++;
+        }
+    }
+
+    private function setRowColor($rownum)
+    {
+        return $rownum % 2 == 0 ? '#b0c4de' : 'white';
+    }
+
+    public function getChangedDateRecord($id)
+    {
+        global $db;
+        $changedRecord = [];
+        $logoutChangeNaploObj = new LogoutChangeNaplo($db);
+        $result = $logoutChangeNaploObj->fetchAll('DESC', 'rowid', 1, 0, array('fk_logout' => $id));
+        if (!empty($result)) {
+            foreach ($result as $record) {
+                $changedRecord['id'] = $record->id;
+                $changedRecord['corrected_date'] = $record->corrected_date;
+                return $changedRecord;
+            }
+        }
+        return false;
+    }
+
+    public function getEntities($entitiesArrayIsEmpty = false, $entities, $entitiesArray)
+    {
+        if ($entitiesArrayIsEmpty) {
+            $array = [];
+            foreach ($entities as $key => $value) {
+                $array[] = $key;
+            }
+            $selectedEntities = implode(', ', $array);
+        } else {
+            $array = [];
+            foreach ($entitiesArray as $entity) {
+                if ($entity)
+                    $array[] = $entity;
+            }
+            $selectedEntities = implode(', ', $array);
+        }
+        return $selectedEntities;
+    }
+
+    function getTheUsersOfGroup($id, $nemkell)
+    {
+        global $db;
+        $sql = "SELECT ugtg.fk_groupid, gu.fk_user, u. lastname, u.firstname, u.login, ue.nickname
+        FROM " . MAIN_DB_PREFIX . "settlements_usergrouptoolgroup as ugtg 
+        INNER JOIN " . MAIN_DB_PREFIX . "settlements_groupusers as gu ON gu.fk_settlements_group = ugtg.fk_groupid 
+        INNER JOIN " . MAIN_DB_PREFIX . "user as u ON u.rowid = gu.fk_user 
+        INNER JOIN " . MAIN_DB_PREFIX . "user_extrafields as ue ON ue.fk_object = gu.fk_user 
+        WHERE ugtg.fk_group_tools_id = {$id} 
+        AND ugtg.fk_groupid NOT IN (SELECT gu2.fk_settlements_group FROM " . MAIN_DB_PREFIX . "settlements_groupusers as gu2 WHERE date_creation < DATE_TRUNC('day', CURRENT_DATE) GROUP BY gu2.fk_settlements_group)";
+        if ($nemkell != '') {
+            $sql .= " AND gu.fk_user NOT IN({$nemkell})";
+        }
+        //print $sql . '<br>';
+        $data = $this->db->query($sql);
+        $dataArray = pg_fetch_all($data);
+        return $dataArray;
+    }
+
+    function savePackageUserAssignement($packageuser, $id)
+    {
+        global $db;
+        global $user;
+        global $langs;
+
+        $packageHistoryObj = new PackageHistory($db);
+
+        foreach ($packageuser as $key => $value) {
+            $groupuser_id = $this->getGroupuserIdByUserId($value);
+            $printbutton = $key . '_' . $value;
+            $html = $this->createHTML($printbutton);
+            $pdf = new SettlementsPDFPrint($html);
+            $fullPath = $pdf->generateSettlementsPDF();
+            $package_entity = $this->getEntityOfPackage($key);
+            $packageHistoryObj->package_manager_user = $user->id;
+            $packageHistoryObj->package_id = $key;
+            $packageHistoryObj->user_id = $value;
+            $packageHistoryObj->status = 0;
+            $packageHistoryObj->package_entity = $package_entity;
+            $packageHistoryObj->fk_group_id = $id;
+            $packageHistoryObj->fk_groupuser_id = $groupuser_id;
+            $packageHistoryObj->delivery_pdf = $fullPath;
+            //print_r($packageHistoryObj);exit;
+            $result = $packageHistoryObj->create($user);
+            if ($result < 0) {
+                return -1;
+            }
+            //sleep(1);
+        }
+        return 0;
+    }
+
+    function saveDailyClosing($jsonArray, $user_id, $package_id, $fk_group_id)
+    {
+        global $db;
+        global $user;
+        global $langs;
+
+        $packageHistoryObj = new PackageHistory($db);
+        $fullPath = '';
+        $package_entity = $this->getEntityOfPackage($package_id);
+        $packageHistoryObj->package_manager_user = $user->id;
+        $packageHistoryObj->package_id = $package_id;
+        $packageHistoryObj->user_id = $user_id;
+        $packageHistoryObj->status = 1;
+        $packageHistoryObj->package_entity = $package_entity;
+        $packageHistoryObj->fk_group_id = $fk_group_id;
+        $packageHistoryObj->income_pdf = $fullPath;
+        $packageHistoryObj->note_public = $jsonArray;
+        $result = $packageHistoryObj->create($user);
+        if ($result < 0) {
+            return -1;
+        }
+        return $result;
+    }
+
+    public function getEntityOfPackage($package_id)
+    {
+        global $db;
+        $packageObj = new Package($db);
+        $result = $packageObj->fetch($package_id);
+        if ($result <= 0) {
+            dol_syslog("No Entity found. (settlements->helper->getEntityOfPackage())", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage('No Entity found. (settlements->helper->getEntityOfPackage())', 'errors');
+        }
+        return $packageObj->fk_entity;
+    }
+
+    function checkPackageUserAssignement($id)
+    {
+        $array = [];
+        if (isset($id)) {
+            global $db;
+            $packageHistoryObj = new PackageHistory($db);
+            $now = dol_now();
+            $from = date('Y-m-d H:i:s', strtotime("-2 day", strtotime(date('Y-m-d', $now))));
+            $to = date('Y-m-d H:i:s', $now);
+
+            $result = $packageHistoryObj->fetchAll('DESC', 'rowid', 0, 0, ["customsql" => "fk_group_id = {$id} AND  date_creation BETWEEN '{$from}' AND '{$to}'"]);
+            if($result > 0){
+                foreach ($result as $key => $value) {
+                    $array[][$value->package_id] = $value->user_id;
+                }
+            }
+        }
+        return $array;
+    }
+
+    function getAssignementsOfThisPackage($id, $package_id)
+    {
+        $dataArray = [];
+        global $db;
+        $packageHistoryObj = new PackageHistory($db);
+        $now = dol_now();
+        $from = date('Y-m-d H:i:s', strtotime("-7 day", strtotime(date('Y-m-d', $now))));
+        $to = date('Y-m-d H:i:s', $now);
+        $sql = "SELECT rowid, package_id, fk_group_id, user_id, status FROM " . MAIN_DB_PREFIX . $packageHistoryObj->table_element . " WHERE fk_group_id = {$id} AND package_id = {$package_id} AND  date_creation BETWEEN '{$from}' AND '{$to}'";
+        //print $sql . '<br>';
+        $result = $db->query($sql);
+        if (pg_num_rows($result) > 0) {
+            return pg_fetch_all($result);
+        }
+        return $dataArray;
+    }
+
+    function checkCLoasedPackageUserAssignement($id)
+    {
+        $array = [];
+        global $db;
+        $packageHistoryObj = new PackageHistory($db);
+        $now = date("Y-m-d", dol_now());
+        $from = $now . ' 00:00:00';
+        $to = $now . ' 23:59:59';
+        $result = $packageHistoryObj->fetchAll('DESC', 'rowid', 0, 0, ["customsql" => "fk_group_id = {$id} AND status = 1 AND  date_creation BETWEEN '{$from}' AND '{$to}'"]);
+        foreach ($result as $key => $value) {
+            $array[$value->package_id] = $value->user_id;
+        }
+        return $array;
+    }
+
+    function getDailyClosingId($user_id)
+    {
+        global $db;
+        $now = dol_now();
+        $from = date('Y-m-d ', strtotime("-3 day", strtotime(date('Y-m-d', $now))));
+        //$from = date('Y-m-d', $now) . ' 00:00:00';
+        $to = date('Y-m-d H:i:s', $now);
+        $sql = "SELECT ph.rowid FROM " . MAIN_DB_PREFIX . "rollerstorage_packagehistory as ph
+        WHERE ph.user_id = {$user_id} AND ph.status = 0 
+        --AND ph.date_creation BETWEEN '{$from} 00:00:00' AND '{$to}'
+        ORDER BY ph.rowid DESC LIMIT 1";
+        //print $sql;
+        $data = $this->db->query($sql);
+        $dataArray = pg_fetch_object($data);
+        return $dataArray->rowid;
+    }
+    function get1stBlockData($user_id)
+    {
+        global $db;
+        $now = dol_now();
+        $from = date('Y-m-d ', strtotime("-2 day", strtotime(date('Y-m-d', $now))));
+        //$from = date('Y-m-d', $now) . ' 00:00:00';
+        $to = date('Y-m-d H:i:s', $now);
+        $sql = "SELECT pack.label as packetlabel, gt.label as grouptool,  ph.fk_group_id, ph.user_id, ph.package_id, ph.rowid/*, gu.fk_settlements_group, gr.ref as usergroup*/ FROM " . MAIN_DB_PREFIX . "rollerstorage_packagehistory as ph
+        INNER JOIN " . MAIN_DB_PREFIX . "settlements_package as pack ON pack.rowid=ph.package_id
+        INNER JOIN " . MAIN_DB_PREFIX . "settlements_grouptools as gt ON gt.rowid = ph.fk_group_id
+        --INNER JOIN " . MAIN_DB_PREFIX . "settlements_groupusers as gu ON gu.fk_user = ph.user_id
+        --INNER JOIN " . MAIN_DB_PREFIX . "settlements_group as gr ON gr.rowid=gu.fk_settlements_group
+        WHERE ph.user_id = {$user_id} AND ph.status = 0 
+        AND ph.date_creation BETWEEN '{$from} 00:00:00' AND '{$to}'
+        ORDER BY ph.rowid DESC LIMIT 1";
+        //print $sql;
+        $data = $this->db->query($sql);
+        $dataArray = pg_fetch_object($data);
+        return $dataArray;
+    }
+
+    function get2ndBlockData($package_id)
+    {
+        $sql = "SELECT pt.package_id, pt.device_id, inv.ref, inv.title, inve.device_type FROM " . MAIN_DB_PREFIX . "settlements_packagetool AS pt
+        INNER JOIN " . MAIN_DB_PREFIX . "inventory as inv ON inv.rowid=pt.device_id
+        INNER JOIN " . MAIN_DB_PREFIX . "inventory_extrafields as inve ON inve.fk_object = inv.rowid
+        WHERE pt.package_id = {$package_id}
+        ORDER BY inv.ref ASC ";
+        //print $sql;
+        $data = $this->db->query($sql);
+        $dataArray = pg_fetch_all($data);
+        return $dataArray;
+    }
+
+    function get3rdBlockData($packageHistoryRecordObj, $user_id)
+    {
+        $commmissionhandler = new CommissionHandler();
+        $now = dol_now();
+        $from = date("Y-m-d H:i:s", $packageHistoryRecordObj->date_creation);
+        $to = date("Y-m-d H:i:s", $now);
+        $allComissionInvoicesOfUserInTheGroupFromUserInvoice = '';
+        $commissionHUFCash = $commmissionhandler->getCashCommisonByUserId($user_id, 'HUF', $from, $to, $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $packageHistoryRecordObj->package_entity, 'LIQ');
+        $commissionEURCash = $commmissionhandler->getCashCommisonByUserId($user_id, 'EUR', $from, $to, $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $packageHistoryRecordObj->package_entity, 'LIQ');
+        $commissionHUFCard = $commmissionhandler->getCashCommisonByUserId($user_id, 'HUF', $from, $to, $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $packageHistoryRecordObj->package_entity, 'CB');
+        $commissionEURCard = $commmissionhandler->getCashCommisonByUserId($user_id, 'EUR', $from, $to, $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $packageHistoryRecordObj->package_entity, 'CB');
+        $array = $this->GiveMeAllCommissionsArray($commissionHUFCash, $commissionEURCash, $commissionHUFCard, $commissionEURCard);
+        return $array;
+    }
+
+    function get3rdBlockDataHistory($entity, $user_id, $id = null)
+    {
+        $commmissionhandler = new CommissionHandler();
+        $allComissionInvoicesOfUserInTheGroupFromUserInvoice = '';
+        $commissionHUFCash = $commmissionhandler->getCashCommisonByUserIdHistory($user_id, 'HUF', $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $id, $entity, 'LIQ');
+        $commissionEURCash = $commmissionhandler->getCashCommisonByUserIdHistory($user_id, 'EUR', $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $id, $entity, 'LIQ');
+        $commissionHUFCard = $commmissionhandler->getCashCommisonByUserIdHistory($user_id, 'HUF', $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $id, $entity, 'CB');
+        $commissionEURCard = $commmissionhandler->getCashCommisonByUserIdHistory($user_id, 'EUR', $allComissionInvoicesOfUserInTheGroupFromUserInvoice, $id, $entity, 'CB');
+        $array = $this->GiveMeAllCommissionsArray($commissionHUFCash, $commissionEURCash, $commissionHUFCard, $commissionEURCard);
+        return $array;
+    }
+
+    function GiveMeAllCommissionsArray($commissionHUFCash, $commissionEURCash, $commissionHUFCard, $commissionEURCard)
+    {
+        $array['HUFcash'] = $commissionHUFCash;
+        $array['EURcash'] = $commissionEURCash;
+        $array['HUFcard'] = $commissionHUFCard;
+        $array['EURcard'] = $commissionEURCard;
+        return $array;
+    }
+
+    function getAllFactures($packageHistoryRecordObj, $user_id)
+    {
+        $array = [];
+        $commissionHandler = new CommissionHandler();
+        $from = $commissionHandler->calculateFromDate($packageHistoryRecordObj->id);
+        $to = $commissionHandler->calculateToDate($user_id, $from);
+        $sql = "SELECT f.rowid, f.ref, f.date_closing, f.multicurrency_code, f.multicurrency_total_ttc, fe.marked_for_storno, p.libelle, fe.commission_deduction FROM " . MAIN_DB_PREFIX . "facture as f 
+        INNER JOIN " . MAIN_DB_PREFIX . "facture_extrafields as fe ON fe.fk_object = f.rowid
+        INNER JOIN " . MAIN_DB_PREFIX . "c_paiement as p ON p.id = f.fk_mode_reglement
+        WHERE f.fk_user_closing = {$user_id} AND f.entity = {$packageHistoryRecordObj->package_entity} AND f.date_closing BETWEEN '{$from}' AND '{$to}' AND f.fk_statut = 2
+        ORDER BY f.ref DESC";
+        //print $sql;
+        $data = $this->db->query($sql);
+        if (pg_num_rows($data) > 0) {
+            while ($row = pg_fetch_assoc($data)) {
+                $array[] = $row;
+            }
+        }
+        return $array;
+    }
+
+    function getAddititonalDevices($rowid)
+    {
+        global $db;
+        $dataArray = [];
+        $sql = "SELECT bp_card, dnc_ticket, rr_ticket FROM " . MAIN_DB_PREFIX . "settlements_package_additionals WHERE fk_package_history_id = {$rowid}";
+        $data = $this->db->query($sql);
+        if ($data) {
+            $dataArray = pg_fetch_assoc($data);
+        }
+        return $dataArray;
+    }
+
+    function getAddititonalChangesDevices($rowid)
+    {
+        global $db;
+        $dataArray = [];
+        $sql = "SELECT change_huf, change_eur FROM " . MAIN_DB_PREFIX . "settlements_package_additionals WHERE fk_package_history_id = {$rowid}";
+        $data = $this->db->query($sql);
+        if ($data) {
+            $dataArray = pg_fetch_assoc($data);
+        }
+        return $dataArray;
+    }
+
+    function getPDFName($package_id, $user_id)
+    {
+        global $db;
+        if (isset($user_id)) {
+            $packageHistoryObj = new PackageHistory($db);
+            $now = dol_now();
+            $from = date('Y-m-d', $now) . ' 00:00:00';
+            $to = date('Y-m-d H:i:s', $now);
+            $result = $packageHistoryObj->fetchAll('DESC', 'date_creation', 1, 0, ['customsql' => "package_id = {$package_id} AND user_id = {$user_id} AND date_creation BETWEEN '$from' AND '$to' AND status = 0"]);
+            foreach ($result as $doc) {
+                return basename($doc->delivery_pdf);
+            }
+        }
+    }
+    function getPDFName2($user_id, $package_id, $group_id)
+    {
+        //print $group_id.'<br>'; print $package_id.'<br>'; print $user_id.'<br>';
+        global $db;
+        if (isset($user_id)) {
+            $packageHistoryObj = new PackageHistory($db);
+            $now = dol_now();
+            $from = date('Y-m-d', $now) . ' 00:00:00';
+            $to = date('Y-m-d H:i:s', $now);
+            $result = $packageHistoryObj->fetchAll('DESC', 'rowid', 1, 0, ["customsql" => "fk_group_id = {$group_id} AND package_id = {$package_id} AND user_id = {$user_id} AND status = 0 AND  date_creation BETWEEN '{$from}' AND '{$to}'"]);
+            foreach ($result as $doc) {
+                return basename($doc->delivery_pdf);
+            }
+        }
+    }
+
+    function checkStatus($package_id, $user_id)
+    {
+        global $db;
+        $packageHistoryObj = new PackageHistory($db);
+        $now = dol_now();
+        $from = date('Y-m-d', $now) . ' 00:00:00';
+        $to = date('Y-m-d H:i:s', $now);
+        $result = $packageHistoryObj->fetchAll('DESC', 'date_creation', 1, 0, ['customsql' => "package_id = {$package_id} AND user_id = {$user_id}"]);
+        foreach ($result as $doc) {
+            return $doc->status;
+        }
+        //return true;
+    }
+
+    function checkStatusToUsergroups($user, $id)
+    {
+        global $db;
+        /* kikeresem a llx_settlements_groupusers táblából a date_creation értékét
+        Ha van ilyen rekord (jelenleg benne van a csoportban), akkor ezt a dátumot használom FROM-nak
+        A FROM és a jelenlegi idő között, group_id, user_id segítségével megnézem a rollerstorage_packagehistory táblában van-e nyitott státuszú rekord
+        */
+        $now = dol_now();
+        $from = date("Y-m-d H:i:s", $now);
+        $sqlGroupUser = "SELECT date_creation FROM " . MAIN_DB_PREFIX . "settlements_groupusers WHERE fk_Settlements_group = {$id} AND fk_user = {$user['fk_user']}";
+        $data = $db->query($sqlGroupUser);
+        if (pg_num_rows($data) > 0) {
+            $dataArray = pg_fetch_assoc($data);
+            $from = $dataArray['date_creation'];
+        }
+        $to = date("Y-m-d H:i:s", $now);
+        // kikeresem az eszközcsoport számát, a usercsoport alapján amiben a user van (" . MAIN_DB_PREFIX . "settlements_usergrouptoolgroup)
+        $sql = "SELECT rowid, status, fk_group_id FROM " . MAIN_DB_PREFIX . "rollerstorage_packagehistory 
+        WHERE user_id = {$user['fk_user']} AND fk_group_id = (SELECT fk_group_tools_id FROM " . MAIN_DB_PREFIX . "settlements_usergrouptoolgroup WHERE fk_groupid = {$id}) 
+        AND date_creation BETWEEN '{$from}' AND '{$to}'";
+        //print $sql;
+        $data = $db->query($sql);
+        $dataArray = pg_fetch_assoc($data);
+        if (isset($dataArray['status'])) {
+            return $dataArray;
+        }
+        return [];
+    }
+
+    function getPDFNameIncome($package_id, $user_id)
+    {
+        global $db;
+        $packageHistoryObj = new PackageHistory($db);
+        $now = dol_now();
+        $from = date('Y-m-d', $now) . ' 00:00:00';
+        $to = date('Y-m-d H:i:s', $now);
+        $result = $packageHistoryObj->fetchAll('DESC', 'date_creation', 1, 0, ['customsql' => "package_id = {$package_id} AND user_id = {$user_id} AND date_creation BETWEEN '$from' AND '$to'"]);
+        foreach ($result as $doc) {
+            return basename($doc->income_pdf);
+        }
+    }
+
+    public function searchAndFetchDailyClosingRow($Block1stData, $user_id, $status)
+    {
+        global $db;
+        $PackageHistory = new PackageHistory($db);
+        /*$now = dol_now();
+        $from = date('Y-m-d', strtotime("-3 day", strtotime(date('Y-m-d', $now))));
+        $checkFrom = $from . ' 00:00:00';
+        $checkTo = date('Y-m-d H:i:s', $now);*/
+        $checkHistory = $PackageHistory->fetchAll('DESC', 'rowid', 1, 0, [
+            "customsql" => "
+            package_id={$Block1stData->package_id} 
+            AND fk_group_id = {$Block1stData->fk_group_id} 
+            AND user_id = {$user_id}
+            AND status = {$status}"
+        ]);
+        //AND date_creation BETWEEN '$checkFrom' AND '$checkTo'"
+
+
+        if (!empty($checkHistory) && $checkHistory > -1) {
+            foreach ($checkHistory as $record) {
+                $theRowid = $record->id;
+            }
+            $PackageHistory->fetch($theRowid);
+            return $PackageHistory;
+        }
+        return -1;
+    }
+
+    public function checkForm($deviceArray, $amountArray)
+    {
+        if (!empty($deviceArray)) {
+            foreach ($deviceArray as $dkey => $dvalue) {
+                if ($dvalue == 'x') {
+                    if ($amountArray[$dkey . '_amount'] == '') {
+                        return true;
+                    }
+                }
+            }
+        } else {
+            return true;
+        }
+    }
+
+    public function updatePackageHistory($packageHistoryObj, $BLock3rdData)
+    {
+        global $db, $user;
+        $error = $this->commonUpdatePackageHistory($packageHistoryObj, $BLock3rdData);
+        if ($error) {
+            $db->rollback();
+            return -1;
+        }
+        $db->commit();
+        return 1;
+    }
+
+
+
+    public function updatePackageHistoryFromHistory($id, $BLock3rdData)
+    {
+        global $db, $user;
+        $packageHistoryObj = new PackageHistory($db);
+        $packageHistoryObj->fetch($id);
+
+        $error = $this->commonUpdatePackageHistory($packageHistoryObj, $BLock3rdData);
+
+        if ($error) {
+            $db->rollback();
+            return -1;
+        }
+        $db->commit();
+        return 1;
+    }
+
+    private function commonUpdatePackageHistory($packageHistoryObj, $BLock3rdData)
+    {
+        global $db, $user;
+        $error = 0;
+        $dailyClosing = new DailyClosing();
+
+        $withholdingArray = $this->createWitholdingsArray();
+        $withholdingRecords = $dailyClosing->getWithholdingRecords($withholdingArray);
+
+        $packageName = $this->getPackageLabelById($packageHistoryObj->package_id); //package name
+        $groupName = $this->getGroupLabelById($packageHistoryObj->fk_group_id); // grouptool name
+        $usergroupName = $this->getUserGroupRefById($packageHistoryObj->fk_groupuser_id); // usergroup name
+
+        #   1stBlock
+
+        $block1stArray = ["package_name" => $packageName, "grouptool_name" => $groupName, "groupuser_name" => $usergroupName]; // groups
+
+        #   2ndBlock
+
+        $devicesArray = $this->getDevicesById($db, $packageHistoryObj->package_id);
+        $block2ndArray = $dailyClosing->getDevicesList($devicesArray, $withholdingRecords); // devices list
+
+        $additionals =
+            [
+                'bp_card' => ["pieces" => $this->getDataFromPackageAdditionals($packageHistoryObj->id, 'bp_card'), "withholding" => $withholdingRecords['bp_card']],
+                'dnc_ticket' => ["pieces" => $this->getDataFromPackageAdditionals($packageHistoryObj->id, 'dnc_ticket'), "withholding" => $withholdingRecords['dnc_ticket']],
+                'rr_ticket' => ["pieces" => $this->getDataFromPackageAdditionals($packageHistoryObj->id, 'rr_ticket'), "withholding" => $withholdingRecords['rr_ticket']]
+            ];
+
+        #   3rdBlock
+
+        $changes = $this->getChanges();
+        $block3rdArray = $dailyClosing->getDailyIncomes($changes); //Daily incomes
+
+        #   4thBlock
+
+        $block4thArray = $BLock3rdData; //total incomes
+        if (isset($withholdingRecords['daily_HUFcash'])) {
+            $block4thArray['WHHUFcash'] = $withholdingRecords['daily_HUFcash'];
+        }
+        if (isset($withholdingRecords['daily_EURcash'])) {
+            $block4thArray['WHEURcash'] = $withholdingRecords['daily_EURcash'];
+        }
+
+        $fullBlockForJSON = ["block1" => $block1stArray, "block2" => $block2ndArray, "additionals" => $additionals, "block3" => $block3rdArray, "block4" => $block4thArray];
+
+        $savedDataJSON = json_encode($fullBlockForJSON);
+
+        $fullPath = $this->getFullPath($packageHistoryObj, $BLock3rdData, $withholdingArray, $additionals);
+
+        $jsonArray = $dailyClosing->getJSONArray($_REQUEST['withholding']);
+
+        $db->begin();
+
+        $packageHistoryObj->note_public = json_encode($jsonArray);
+        $packageHistoryObj->status = 1;
+        $packageHistoryObj->income_pdf = $fullPath;
+        $packageHistoryObj->date_closing = time();
+        $packageHistoryObj->dailyclosing_json = $savedDataJSON;
+        $result = $packageHistoryObj->update($user);
+
+        if (!$result) {
+            $error++;
+        }
+
+        #   WithHolding
+        foreach ($withholdingArray as $key => $value) {
+            $now = dol_now();
+            $deviceName = $this->getDeviceNameFromInventoryById($this->getDeviceIdFromString($key));
+            $withholdingObj = new UserInvoice($db);
+            $withholdingObj->ref = $this->generateRefForWithold();
+            $withholdingObj->label = 'Visszatartás / Withold ' . date("Y-m-d", $now);
+            $withholdingObj->description = $this->createDescriptionToWithold($key, $value, $now, $packageName, $groupName, $deviceName);
+            $withholdingObj->user_id = $packageHistoryObj->user_id;
+            $withholdingObj->payment_type = 1;
+            $withholdingObj->amount = $value;
+            $saved = $withholdingObj->create($user);
+            if (!$saved) {
+                $error++;
+            }
+        }
+
+        # Kick off from UsersGroup
+        $groupUsersObj = new GroupUsers($db);
+        $sql = "SELECT rowid, date_creation FROM " . MAIN_DB_PREFIX . $groupUsersObj->table_element . " WHERE fk_user = {$packageHistoryObj->user_id}";
+        $data = $db->query($sql);
+        $dataArray = pg_fetch_assoc($data);
+
+        $selectedGroupId = $dataArray['rowid'];
+        $selectedGroupDateCreation = $dataArray['date_creation'];
+        if (isset($selectedGroupId)) {
+            $resultKickOff = $groupUsersObj->deleteLine($user, $selectedGroupId);
+            if (!$resultKickOff) {
+                $error++;
+            }
+        }
+
+        # Set Usernaplo  
+        if (isset($selectedGroupId)) {
+            $userLogedOut = $this->checkUsernaploLogout($packageHistoryObj->user_id, $packageHistoryObj->fk_groupuser_id, $selectedGroupDateCreation);
+            if (!$userLogedOut) {
+                $userNaploObj = new UserNaplo($db);
+                $userNaploObj->user_id = $packageHistoryObj->user_id;
+                $userNaploObj->group_user_id = $packageHistoryObj->fk_groupuser_id;
+                $userNaploObj->status = 0;
+                $resultSetUserNaplo = $userNaploObj->create($user);
+                if (!$resultSetUserNaplo) {
+                    $error++;
+                }
+            }
+        }
+        return $error;
+    }
+
+    public function checkUsernaploLogout($user_id, $group_id, $date_creation)
+    {
+        global $db;
+        $sql = "SELECT date_creation, status FROM llx_settlements_usernaplo
+        WHERE group_user_id = {$group_id}
+        AND user_id = {$user_id}
+        AND date_creation > '{$date_creation}'
+        AND status = 0
+        ORDER BY date_creation DESC LIMIT 1";
+        //print $sql;exit;
+        $data = $db->query($sql);
+        while ($row = pg_fetch_assoc($data)) {
+            return true;
+        }
+        return false;
+    }
+
+    public function getDeviceNameFromInventoryById($id)
+    {
+        global $db;
+        $inventoryObj = new Inventory($db);
+        $result = $inventoryObj->fetch($id);
+        return $inventoryObj->ref;
+    }
+    private function getDeviceIdFromString($key)
+    {
+        return substr($key, 1);
+    }
+
+    public function getPackageLabelById($id)
+    {
+        global $db;
+        $packageObj = new Package($db);
+        $packageObj->fetch($id);
+        return $packageObj->label;
+    }
+
+    public function getGroupLabelById($id)
+    {
+        global $db;
+        $groupToolsObj = new Grouptools($db);
+        $groupToolsObj->fetch($id);
+        return $groupToolsObj->label;
+    }
+
+    public function getUserGroupRefById($id)
+    {
+        global $db;
+        $groupObj = new Group($db);
+        $groupObj->fetch($id);
+        return $groupObj->ref;
+    }
+
+    private function createDescriptionToWithold($key, $value, $now, $packageName, $groupName, $deviceName)
+    {
+        $string = 'Date: ' . date("Y-m-d H:i:s", $now);
+        $string .= 'Összeg / Amount: ' . $value;
+        $string .= 'Csomag / Package: ' . $packageName;
+        $string .= 'Csoport / Group: ' . $groupName;
+        $string .= 'Eszköz / Device name: ' . $deviceName;
+        return $string;
+    }
+
+    function generateRefForWithold()
+    {
+        return 'withhold_' . dol_now() . '_' . rand(1000000, 9999999);
+    }
+
+
+    private function createWitholdingsArray()
+    {
+        $withholdinArray = [];
+        foreach ($_REQUEST['withholding']['withholdingAmount'] as $key => $value) {
+            if ($value != '') {
+                $newkey = str_replace('_amount', '', $key);
+                $withholdinArray[$newkey] = $value;
+            }
+        }
+        return $withholdinArray;
+    }
+
+    private function getFullPath($PackageHistoryOpen, $BLock3rdData, $withholdingArray, $additionals)
+    {
+        $data = $PackageHistoryOpen->package_id . '_' . $PackageHistoryOpen->user_id;
+        $html = $this->createHTMLIncome($data, $BLock3rdData, $withholdingArray, $additionals);
+        $pdf = new SettlementsPDFPrint($html);
+        return $pdf->generateSettlementsPDF();
+    }
+
+    public function updateUserEntityInUser($userId, $groupEntity)
+    {
+        global $user, $db;
+        $userId = intval($userId);
+        $sql = "UPDATE " . MAIN_DB_PREFIX . "user SET entity = {$groupEntity} WHERE rowid = {$userId};";
+        $result = $db->query($sql);
+        return $result;
+    }
+
+    public function getPackageName($packages, $id)
+    {
+        foreach ($packages as $package) {
+            if ($package['rowid'] == $id) {
+                return $package['ref'];
+            }
+        }
+    }
+
+    public function isClosed($package_id)
+    {
+        $packageHistoryObj = new PackageHistory($this->db);
+        $result = $packageHistoryObj->fetchAll('DESC', 'rowid', 1, 0, ["customsql" => "package_id = {$package_id}"]);
+        if (!empty($result)) {
+            foreach ($result as $record) {
+                //print $record->status;
+                return $record->status;
+            }
+        } else {
+            return true;
+        }
+    }
+
+    public function assignedUserFromPackageHistory($package_id)
+    {
+        global $db, $langs;
+        $sql = "SELECT u.firstname, u.lastname, u.login FROM " . MAIN_DB_PREFIX . "rollerstorage_packagehistory ph
+        INNER JOIN " . MAIN_DB_PREFIX . "user as u ON u.rowid = ph.user_id
+        WHERE ph.package_id = {$package_id}
+        ORDER BY ph.rowid DESC LIMIT 1";
+        $data = $db->query($sql);
+        $dataArray = pg_fetch_assoc($data);
+        $name = $dataArray['lastname'] . ' ' . $dataArray['firstname'] . ' (' . $dataArray['login'] . ')';
+        $name = '<tr style="background-color:rgb(163,0,51); color: white; height: 30px;"><td colspan="3" style="text-align:center;">' . $name . '</td></tr>';
+        $noUser = '<tr style="color: red; height: 30px;"><td colspan="3" style="text-align:center;">' . $langs->trans('NoAssignedUser') . '</td></tr>';
+        return $dataArray['login'] != '' ? $name : $noUser;
+    }
+
+    public function getChanges()
+    {
+        global $db;
+        $sql = "SELECT ref, title FROM llx_inventory AS i INNER JOIN llx_inventory_extrafields as ie ON ie.fk_object = i.rowid WHERE ie.device_type::integer IN(3,4)";
+        $data = $db->query($sql);
+        $dataArray = pg_fetch_all($data);
+        return $dataArray;
+    }
+
+
+    public function getUsersArrayOfSelector($eztHasznalomAzosszerendelesekre, $package)
+    {
+        $usersArrayOfSelector = [];
+        foreach ($eztHasznalomAzosszerendelesekre as $package1 => $userOfPackage) {
+            if ($userOfPackage > -1 && $package1 != $package['fk_package']) {
+                $usersArrayOfSelector[] = $userOfPackage;
+            }
+        }
+        return implode(',', $usersArrayOfSelector);
+    }
+
+    public function getUserSelector($eztHasznalomAzosszerendelesekre, $package, $guser)
+    {
+        if ($eztHasznalomAzosszerendelesekre[$package['fk_package']] == $guser['fk_user']) {
+            return 'selected';
+        } else {
+            return '';
+        }
+    }
+
+    public function isRecordClosed($user_id, $package_id, $group_id)
+    {
+        global $db;
+        $packageHistoryObj = new PackageHistory($db);
+        $now = date("Y-m-d", dol_now());
+        $from = $now . ' 00:00:00';
+        $to = $now . ' 23:59:59';
+        $result = $packageHistoryObj->fetchAll('DESC', 'rowid', 1, 0, ["customsql" => "fk_group_id = {$group_id} AND package_id = {$package_id} AND user_id = {$user_id} AND status = 1 AND  date_creation BETWEEN '{$from}' AND '{$to}'"]);
+        if ($result == -1) {
+            return false;
+        }
+        foreach ($result as $record) {
+            return $record->status;
+        }
+    }
+
+    public function checkEquality($id)
+    {
+        global $db;
+        if (isset($id)) {
+            $userCounter = $this->getNumberOfUsers();
+            $usersCount = $userCounter[$id][0];
+            $assignedPackagesCount = count($this->getPackagesById($id));
+            return $usersCount == $assignedPackagesCount;
+        }
+        return true;
+    }
+
+    public function checkSumAndUsers($toselectnewpackage, $id)
+    {
+        global $db;
+        $userCounter = $this->getNumberOfUsers();
+        $userCounter[$id][0];
+        $sum = count($this->getPackagesById($id)) + count($toselectnewpackage);
+        $users = $userCounter[$id][0];
+        return $sum > $users;
+    }
+
+    public function userSelectorOptions($usersOfThisGroup, $package, $eztHasznalomAzosszerendelesekre, $id)
+    {
+        $pdfArray = [];
+        if (!empty($usersOfThisGroup)) {
+            foreach ($usersOfThisGroup as $guser) {
+                $pdfArray[$guser['fk_user']] = $this->getPDFName2($guser['fk_user'], $package['fk_package'], $id);
+                $selectedUserInSelector = $this->getUserSelector($eztHasznalomAzosszerendelesekre, $package, $guser);
+                $nickname = isset($guser['nickname']) ? $guser['nickname'] . ', ' : '';
+                $userSelector .= '<option value="' . $guser['fk_user'] . '" ' . $selectedUserInSelector . '>' . $nickname . $guser['firstname'] . ' ' . $guser['lastname'] . '</option>';
+            }
+        }
+        return [$userSelector, $pdfArray];
+    }
+
+    public function createPopupBox($package, $DeviceCounter)
+    {
+        global $db, $langs;
+        $numberOfDevices = '';
+        $devicesArray = [];
+        if (isset($DeviceCounter[$package['fk_package']])) {
+            $numberOfDevices = '(' . $DeviceCounter[$package['fk_package']] . ' ' . $langs->trans('device') . ')';
+            $devicesArray = $this->getDevicesById($db, $package['fk_package']);
+        }
+
+        $popupBox2 = $this->createPopoupBoxForDeviceList($numberOfDevices, $devicesArray);
+        if ($popupBox2 == '') {
+            $popupBox2 = '<div style="color:red;">' . $langs->trans('emptyPackage') . '</div>';
+        }
+        return $popupBox2;
+    }
+
+    public function getSelectableUsers($fk_group_id)
+    {
+        global $db;
+        $userArray = [];
+        $sql = "SELECT t.rowid, t.lastname,t.firstname, t.login FROM " . MAIN_DB_PREFIX . "user as t WHERE 
+        rowid IN(SELECT gu.fk_user 
+                 FROM " . MAIN_DB_PREFIX . "settlements_usergrouptoolgroup AS ugtg 
+                 INNER JOIN " . MAIN_DB_PREFIX . "settlements_groupusers as gu ON gu.fk_settlements_group = ugtg.fk_groupid 
+                 WHERE fk_group_tools_id = {$fk_group_id} /*AND date_trunc('day', gu.date_creation) = CURRENT_DATE*/ AND gu.fk_user NOT IN(SELECT ph.user_id FROM " . MAIN_DB_PREFIX . "rollerstorage_packagehistory AS ph 
+        WHERE ph.fk_group_id = {$fk_group_id} AND ph.status in (0) AND  date_trunc('day', ph.date_creation) = CURRENT_DATE
+        ORDER BY rowid DESC)) 
+                 ORDER BY t.lastname ASC, t.firstname ASC";
+        //print $sql;
+        $data = $db->query($sql);
+        $dataArray = pg_fetch_all($data);
+        if (is_array($dataArray)) {
+            foreach ($dataArray as $row) {
+                $userArray[$row['rowid']] = $row['firstname'] . ' ' . $row['lastname'] . ' (' . $row['login'] . ')';
+            }
+        }
+        return $userArray;
+    }
+
+    public function getPackageHistoryId($package_id, $fk_group_id, $user_id)
+    {
+        global $db;
+        $packageHistoryObj = new PackageHistory($db);
+        $result = $packageHistoryObj->fetchAll('DESC', 'rowid', 1, 0, ["customsql" => "package_id = {$package_id} AND fk_group_id = {$fk_group_id} AND user_id = {$user_id}"]);
+        foreach ($result as $row) {
+            return $row->id;
+        }
+    }
+
+    public function getAdditionalTitle($key)
+    {
+        switch ($key) {
+            case 'bp_card':
+                return 'Budapest Card';
+                break;
+            case 'dnc_ticket':
+                return 'Dinner & Cruise';
+                break;
+            case 'rr_ticket':
+                return 'RiverRide';
+                break;
+            case 'change_huf':
+                return 'Change HUF';
+                break;
+            case 'change_eur':
+                return 'Change EUR';
+                break;
+            default:
+                # code...
+                break;
+        }
+    }
+
+    private function getDataFromPackageAdditionals($id, $name)
+    {
+        global $db;
+        $packageAdditionalsObj = new Package_additionals($db);
+        $result = $packageAdditionalsObj->fetchAll('', '', 0, 0, ["customsql" => "fk_package_history_id = {$id}"]);
+        if ($result > 0) {
+            foreach ($result as $row) {
+                return ($row->$name);
+            }
+        }
+        return '';
+    }
+
+    public function checkClose($id)
+    {
+        global $db;
+        $packageHistoryObj = new PackageHistory($db);
+        $packageHistoryObj->fetch($id);
+        return $packageHistoryObj->status;
+    }
+
+    public function getJSON($id, $record)
+    {
+        global $db;
+        $packageHistoryObj = new PackageHistory($db);
+        $packageHistoryObj->fetch($id);
+        return $packageHistoryObj->$record;
+    }
+
+    public function generateDeliveryJSON($object, $bpcard = '', $dandc = '', $riverride = '')
+    {
+        global $db;
+        $dailyClosing = new DailyClosing();
+        $withholdingRecords = [];
+        $additionals = ["bp_card" => $bpcard, "dnc_ticket" => $dandc, "rr_ticket" => $riverride];
+
+        $packageName = $this->getPackageLabelById($object->package_id); //package name
+        $groupName = $this->getGroupLabelById($object->fk_group_id); // grouptool name
+        $usergroupName = $this->getUserGroupRefById($object->fk_groupuser_id); // usergroup name
+
+        $block1stArray = ["package_name" => $packageName, "grouptool_name" => $groupName, "groupuser_name" => $usergroupName]; // groups
+
+        #   2ndBlock
+
+        $devicesArray = $this->getDevicesById($db, $object->package_id);
+        $block2ndArray = $dailyClosing->getDevicesList($devicesArray, $withholdingRecords); // devices list
+
+        $fullBlockForJSON = ["block1" => $block1stArray, "block2" => $block2ndArray, "additionals" => $additionals, "changes" => $this->getChanges()];
+        return $fullBlockForJSON;
+    }
+
+    public function packageClosed($id)
+    {
+        $packageHistoryObj = new PackageHistory($this->db);
+        $packageHistoryObj->fetch($id);
+        return $packageHistoryObj->status;
+    }
+
+    public function checkConfirmation($id)
+    {
+        global $db;
+        $sql = "SELECT * FROM " . MAIN_DB_PREFIX . "settlements_groupusers 
+        WHERE date_trunc('day', date_creation) = CURRENT_DATE 
+        AND fk_settlements_group = (SELECT fk_groupid FROM " . MAIN_DB_PREFIX . "settlements_usergrouptoolgroup WHERE fk_group_tools_id = {$id})
+        ORDER BY rowid DESC";
+        $data = $db->query($sql);
+        $dataArray = pg_fetch_all($data);
+        if (is_array($dataArray)) {
+            return true;
+        }
+        return false;
+    }
+
+    public function groupList($groups, $id)
+    {
+        global $langs, $db;
+        $string = '';
+        $string .= '<table style="width:100%;">';
+        $stringEmpty = '';
+        $stringEmpty .= '<table style="width:100%;">';
+
+        foreach ($groups as $group) {
+            $usersOfGroups = $this->getUsersById($db, $group['rowid']);
+            if (count($usersOfGroups) > 0) {
+                $peopleOrPerson = count($usersOfGroups) > 1 ? $langs->trans('people') : $langs->trans('person');
+                $headcount = count($usersOfGroups) > 0 ? count($usersOfGroups) . ' ' . $peopleOrPerson : '&nbsp;';
+                $coloredLine = $id == $group['rowid'] ? ' background-color: #b0c4de;' : '';
+                $string .= '<tr class="submitFormLink" data-value="' . $group['rowid'] . '" style="height:30px;' . $coloredLine . ' cursor:pointer;"><td colspan="2"><div><span class="fa fa-group pictofixedwidth"></span> ' . $group['ref'] . '</div>
+                <p style="margin-left: 20px; margin-top:0px; margin-bottom:5px; font-size:15px;"><div style="float:left; color: grey;">' . $group['label'] . '</div><div style="text-align: right;">' . $headcount . '</div></p></td>';
+            } else {
+                $peopleOrPerson = count($usersOfGroups) > 1 ? $langs->trans('people') : $langs->trans('person');
+                $headcount = count($usersOfGroups) > 0 ? count($usersOfGroups) . ' ' . $peopleOrPerson : '&nbsp;';
+                $coloredLine = $id == $group['rowid'] ? ' background-color: #b0c4de;' : '';
+                $stringEmpty .= '<tr class="submitFormLink" data-value="' . $group['rowid'] . '" style="height:30px;' . $coloredLine . ' cursor:pointer;"><td colspan="2"><div><span class="fa fa-group pictofixedwidth"></span> ' . $group['ref'] . '</div>
+                <p style="margin-left: 20px; margin-top:0px; margin-bottom:5px; font-size:15px;"><div style="float:left; color: grey;">' . $group['label'] . '</div><div style="text-align: right;">' . $headcount . '</div></p></td>';
+            }
+        }
+
+        $string .= '</table>';
+        $string .= '<table style="width: 100%; margin-bottom: 20px;"><tr><td style="width: 33%;"><hr></td><td style="width: 20%; text-align: center; color: grey;">Empty groups</td><td style="width: 33%;"><hr></td></tr></table>';
+        $stringEmpty .= '</table>';
+
+        return $string . $stringEmpty;
+    }
+
+    function getFilteredPackages($string, $groupid)
+    {
+        global $db;
+        $allPackages = [];
+        $entity_id = $this->getEntityIdFromgoupTools($groupid);
+        $sql = "SELECT pa.rowid, pa.ref, pa.label
+    FROM " . MAIN_DB_PREFIX . "settlements_package as pa 
+    WHERE pa.rowid NOT IN (SELECT fk_package FROM " . MAIN_DB_PREFIX . "settlements_grouptoolspackages)";
+        $sql .= " AND pa.fk_entity = '{$entity_id}' AND pa.ref LIKE '%{$string}%' ORDER BY pa.ref";
+
+        //print $sql;
+        $data = $db->query($sql);
+        if (!$data) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            return $allPackages;
+        }
+        while ($row = pg_fetch_assoc($data)) {
+            $allPackages['freePackages'][$row['rowid']] = $row;
+            if (isset($row['fk_object'])) {
+                $inventoryObj = new Inventory($db);
+                $inventoryObj->fetch($row['fk_object']);
+                $assigned_device_data = ['rowid' => $inventoryObj->id, 'title' => $inventoryObj->title, 'ref' => $inventoryObj->ref, 'device_type' => $inventoryObj->array_options['options_device_type']];
+                $allPackages['freePackages'][$row['rowid']]['assigned_device_data'] = $assigned_device_data;
+            }
+        }
+        $sqlAddedPackages = "SELECT pa.rowid, pa.ref, pa.label, gp.rowid as gprowid, gp.ref as gpref, gp.label as gplabel FROM " . MAIN_DB_PREFIX . "settlements_grouptoolspackages as gpp
+        INNER JOIN " . MAIN_DB_PREFIX . "settlements_package as pa ON pa.rowid = gpp.fk_package
+        INNER JOIN " . MAIN_DB_PREFIX . "settlements_grouptools as gp ON gp.rowid = gpp.fk_group";
+        $data2 = $this->db->query($sqlAddedPackages);
+        if (!$data2) {
+            dol_syslog("No group found.", LOG_DEBUG | LOG_INFO | LOG_WARNING | LOG_ERR);
+            setEventMessage($this->langs->trans('($helper->getAllPackagesFromSelectedEntity()) settlements_grouptoolspackages'), 'errors');
+            return $allPackages;
+        }
+        while ($row = pg_fetch_assoc($data2)) {
+            $allPackages['addedPackages'][] = $row;
+
+        }
+
+        return $allPackages;
+    }
+
+    public function getGTAndGUArray()
+    {
+        global $db;
+        $sql = "SELECT fk_groupid, fk_group_tools_id FROM " . MAIN_DB_PREFIX . "settlements_usergrouptoolgroup";
+        $result = $db->query($sql);
+        if (pg_num_rows($result) > 0) {
+            while ($row = pg_fetch_assoc($result)) {
+                $array[$row['fk_groupid']] = $row['fk_group_tools_id'];
+            }
+            return $array;
+        }
+        return [];
+
+    }
+
+    public function freeToolsDiv($allTools)
+    {
+        $string = '';
+        global $langs;
+        $string .= '<table style="width:100%;">';
+        foreach ($allTools['freeTools'] as $freeTool) {
+            $status3 = $freeTool['status'] != 115 ? '<span class="fa fa-exclamation pictofixedwidth" style="color:red;"></span>' : '';
+            $url_3 = '/custom/rollerstorage/card.php?id=' . $freeTool['rowid'] . '&inventory_id=' . $freeTool['fk_warehouse'] . '&backtopage=/custom/rollerstorage/rollerstorageinventoryindex.php?inventory_id=' . $freeTool['fk_warehouse'] . '&idmenu=1599&leftmenu=';
+            if ($freeTool['device_type'] == 1) {
+                $disabled = !isset($freeTool['assigned_device_data']) ? 'disabled' : '';
+                $string .= '
+				<tr style="height:30px; background-color: lightgrey;">
+					<td><span class="fa fa-mobile pictofixedwidth"></span> <a href="' . $url_3 . '">' . $freeTool['ref'] . '</a> - ' . $freeTool['title'] . ' ' . $status3 . '</td>
+					<td class="nowrap center"><input id="id_3_' . $freeTool['rowid'] . '" class="flat checkforselectadd" type="checkbox" onclick="submitFormAddTool(event)" name="toselectnewtool[]" value="' . $freeTool['rowid'] . '" ' . $disabled . '></td>
+				</tr>';
+                $statusAssigned3 = $freeTool['assigned_device_data']['status'] != 115 ? '<span class="fa fa-exclamation pictofixedwidth" style="color:red;"></span>' : '';
+                $string .= '<tr style="height:30px; background-color: lightgrey;">';
+                if (!isset($freeTool['assigned_device_data'])) {
+                    $string .= '<td style="color: red;">&nbsp;&nbsp;&nbsp;&nbsp;<span class="fa fa-credit-card pictofixedwidth"></span>' . $langs->trans('NoCardreadder') . '</td>';
+                } else {
+                    $string .= '<td>&nbsp;&nbsp;&nbsp;&nbsp;<span class="fa fa-credit-card pictofixedwidth"></span><a href="' . $url_3 . '"> ' . $freeTool['assigned_device_data']['ref'] . '</a> - ' . $freeTool['assigned_device_data']['title'] . ' ' . $statusAssigned3 . '</td>';
+                }
+                $string .= '<td class="nowrap center"></td>
+			</tr>';
+
+            } elseif ($freeTool['device_type'] == 0 || $freeTool['device_type'] == 3 || $freeTool['device_type'] == 4 || $freeTool['device_type'] == 5) {
+                $string .= '
+				<tr style="height:30px;">
+					<td><span class="fa fa-toolbox pictofixedwidth"></span> <a href="' . $url_3 . '">' . $freeTool['ref'] . '</a> - ' . $freeTool['title'] . ' ' . $status3 . '</td>
+					<td class="nowrap center"><input id="id_3_' . $freeTool['rowid'] . '" class="flat checkforselectadd" type="checkbox" onclick="submitFormAddTool(event)" name="toselectnewtool[]" value="' . $freeTool['rowid'] . '"></td>
+				</tr>';
+            }
+        }
+        $string .= '</table>';
+        return $string;
+    }
+
+    public function addedToolsDiv($allTools)
+    {
+        global $langs;
+        $string = '';
+        $string .= '<table style="width:100%; color: red;"><tr><td>';
+        if ($allTools['addedTools']) {
+            foreach ($allTools['addedTools'] as $addedKey => $addedValue) {
+                $string .= '<table style="width: 100%; margin-bottom: 20px; border-collapse: separate; border: 2px solid #ccc; border-radius: 10px;"><tr style="height:30px; text-align:center;"><td><span class="fa fa-link pictofixedwidth"></span><a href="/custom/settlements/settlementpackagetoolssettingsindex.php?idmenu=1592&mainmenu=settlements&leftmenu=&id=' . $addedKey . '">' . $allTools['addedPackages'][$addedKey] . '</a><td></tr>';
+                foreach ($addedValue as $record) {
+                    $statusAddedTool = $record['status'] != 115 ? '<span class="fa fa-exclamation pictofixedwidth" style="color:red;"></span>' : '';
+                    if ($record['device_type'] == 1) {
+                        $url_added = '/custom/rollerstorage/card.php?id=' . $record['rowid'] . '&inventory_id=' . $record['fk_warehouse'] . '&backtopage=/custom/rollerstorage/rollerstorageinventoryindex.php?inventory_id=' . $record['fk_warehouse'] . '&idmenu=1599&leftmenu=';
+                        $string .= '
+					<tr style="height:30px;">
+					<td><span class="fa fa-mobile pictofixedwidth"></span> <a href="' . $url_added . '"> ' . $record['ref'] . '</a> - ' . $record['title'] . '</td>
+					</tr>';
+                        $statusAssigned3 = $record['assigned_device_data']['status'] != 115 ? '<span class="fa fa-exclamation pictofixedwidth" style="color:red;"></span>' : '';
+                        $url_added = '/custom/rollerstorage/card.php?id=' . $record['assigned_device_data']['rowid'] . '&inventory_id=' . $record['fk_warehouse'] . '&backtopage=/custom/rollerstorage/rollerstorageinventoryindex.php?inventory_id=' . $record['fk_warehouse'] . '&idmenu=1599&leftmenu=';
+                        $string .= '<tr style="height:30px;">';
+                        if (!isset($record['assigned_device_data'])) {
+                            $string .= '<td><span class="fa fa-credit-card pictofixedwidth"></span>' . $langs->trans('NoCardreadder') . '</td>';
+                        } else {
+                            $string .= '<td><span class="fa fa-credit-card pictofixedwidth"></span><a href="' . $url_added . '"> ' . $record['assigned_device_data']['ref'] . '</a> - ' . $record['assigned_device_data']['title'] . ' ' . $statusAssigned3 . '</td>';
+                        }
+                        $string .= '</tr>';
+                    } elseif ($record['device_type'] == 0 || $record['device_type'] == 3 || $record['device_type'] == 4 || $record['device_type'] == 5) {
+                        $url_added = '/custom/rollerstorage/card.php?id=' . $record['rowid'] . '&inventory_id=' . $record['fk_warehouse'] . '&backtopage=/custom/rollerstorage/rollerstorageinventoryindex.php?inventory_id=' . $record['fk_warehouse'] . '&idmenu=1599&leftmenu=';
+                        $string .= '
+					<tr style="height:30px;">
+						<td><span class="fa fa-toolbox pictofixedwidth"></span><a href="' . $url_added . '"> ' . $record['ref'] . '</a> - ' . $record['title'] . ' ' . $statusAddedTool . '</td>
+					</tr>';
+                    }
+                }
+            }
+        }
+        $string .= '</table></td></tr></table>';
+        return $string;
+    }
+
+    public function addedPackageDiv($allPackages, $DeviceCounter)
+    {
+        global $langs, $db;
+        $string = '';
+        foreach ($allPackages['addedPackages'] as $addedPackage) {
+            $numberOfDevices4 = '';
+            $devicesArray4 = [];
+            if (isset($DeviceCounter[$addedPackage['gprowid']])) {
+                $numberOfDevices4 = '(' . $DeviceCounter[$addedPackage['gprowid']] . ' ' . $langs->trans('device') . ')';
+                $devicesArray4 = $this->getDevicesById($db, $addedPackage['rowid']);
+            }
+            $popupBox4Text = $this->createPopoupBoxForDeviceList($numberOfDevices4, $devicesArray4);
+            $popupBox4 = $popupBox4Text != '' ? $popupBox4Text : '<font style="color:red;">' . $langs->trans('emptyPackage') . '</font>';
+            print '
+			<table style="width:100%; border: 1px solid lightgrey; border-radius: 10px; margin-bottom: 20px;">
+				<tr>
+					<td colspan="2" style="text-align: center; width: 100%;"><a href="settlementtoolssettingsindex.php?idmenu=926&mainmenu=settlements&leftmenu=&id=' . $addedPackage['gprowid'] . '&nopackageuser=1">' . $addedPackage['gplabel'] . '</td>
+				</tr>
+				<tr style="height:30px;">
+					<td style="width:60%;"><span class="fa fa-toolbox pictofixedwidth"></span><a href="/custom/settlements/settlementpackagetoolssettingsindex.php?idmenu=1592&mainmenu=settlements&leftmenu=&id=' . $addedPackage['rowid'] . '"> ' . $addedPackage['ref'] . '</a></td>
+					<td style="width:40%;">' . $popupBox4 . '</td>
+				</tr>
+			</table>';
+        }
+    }
+}

+ 40 - 0
custom/settlements/core/tpl/printPDF_szisz.php

@@ -137,4 +137,44 @@ class SettlementsPDFPrint
     return $full_path;
     return $full_path;
   }
   }
 
 
+  public function generateVoucherPDF()
+  {
+    $dompdf = new Dompdf();
+    $options = $dompdf->getOptions();
+    $dompdf->set_option('defaultFont', 'DejaVu Sans');
+    $dompdf->setOptions($options);
+
+    $html = '
+    <html>
+      <head>
+          <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+          <style type="text/css">
+            * { font-family: "DejaVu Sans" !important; }
+          </style>
+      </head>
+    <body>';
+
+    $html .= $this->htmlTemplate;
+
+    $html .= '<script type="text/php"><?=$PAGE_NUM?></script></body></html>';
+
+    $dompdf->loadHtml($html, 'UTF-8');
+    $dompdf->setPaper('A4', 'portrai');
+    $dompdf->render();
+
+    $fname = 'voucher_' . time() . '_' . uniqid();
+    $filename = $fname . '.pdf';
+    $directory_path = '/var/www/html/documents/voucher/pdf/voucher/';
+    if (!is_dir($directory_path)) {
+      mkdir($directory_path, 0775, true);
+      chmod($directory_path, 0775);
+    }
+    //$custompath = date('Y') . '/' . date('m') . '/' . 
+    $full_path = $directory_path . $filename;
+    $pdf_gen = $dompdf->output();
+    file_put_contents($full_path, $pdf_gen);
+    //$dompdf->stream($fname,array("Attachment"=>0));
+    return $full_path;
+  }
+
 }
 }

+ 0 - 2
custom/settlements/core/triggers/interface_99_modSettlements_SettlementsTriggers.class.php

@@ -121,8 +121,6 @@ class InterfaceSettlementsTriggers extends DolibarrTriggers
 		//print $action;
 		//print $action;
 		//print '<br>';
 		//print '<br>';
 		//print_r($object);
 		//print_r($object);
-		//print $object->ref;
-		//print $object->table_element;
 		//exit;
 		//exit;
 		switch ($action) {
 		switch ($action) {
 			case 'GROUP_CREATE':
 			case 'GROUP_CREATE':

+ 476 - 0
custom/settlements/core/triggers/interface_99_modSettlements_SettlementsTriggers.class.php.bak

@@ -0,0 +1,476 @@
+<?php
+/* Copyright (C) 2023 László Szollősi
+ *
+ * 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.
+ *
+ * This 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 <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file    core/triggers/interface_99_modSettlements_SettlementsTriggers.class.php
+ * \ingroup settlements
+ * \brief   Example trigger.
+ *
+ * Put detailed description here.
+ *
+ * \remarks You can create other triggers by copying this one.
+ * - File name should be either:
+ *      - interface_99_modSettlements_MyTrigger.class.php
+ *      - interface_99_all_MyTrigger.class.php
+ * - The file must stay in core/triggers
+ * - The class name must be InterfaceMytrigger
+ */
+
+require_once DOL_DOCUMENT_ROOT . '/core/triggers/dolibarrtriggers.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/settlements/class/usernaplo.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/settlements/class/groupusers.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/settlements/class/grouphotels.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/settlements/class/usergrouptoolgroupnaplo.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/settlements/class/usergrouptoolgroup.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/settlements/class/grouptools.class.php';
+
+
+
+/**
+ *  Class of triggers for Settlements module
+ */
+class InterfaceSettlementsTriggers extends DolibarrTriggers
+{
+	/**
+	 * Constructor
+	 *
+	 * @param DoliDB $db Database handler
+	 */
+	public function __construct($db)
+	{
+		$this->db = $db;
+
+		$this->name = preg_replace('/^Interface/i', '', get_class($this));
+		$this->family = "demo";
+		$this->description = "Settlements triggers.";
+		// 'development', 'experimental', 'dolibarr' or version
+		$this->version = 'development';
+		$this->picto = 'settlements@settlements';
+	}
+
+	/**
+	 * Trigger name
+	 *
+	 * @return string Name of trigger file
+	 */
+	public function getName()
+	{
+		return $this->name;
+	}
+
+	/**
+	 * Trigger description
+	 *
+	 * @return string Description of trigger file
+	 */
+	public function getDesc()
+	{
+		return $this->description;
+	}
+
+
+	/**
+	 * Function called when a Dolibarrr business event is done.
+	 * All functions "runTrigger" are triggered if file
+	 * is inside directory core/triggers
+	 *
+	 * @param string 		$action 	Event action code
+	 * @param CommonObject 	$object 	Object
+	 * @param User 			$user 		Object user
+	 * @param Translate 	$langs 		Object langs
+	 * @param Conf 			$conf 		Object conf
+	 * @return int              		<0 if KO, 0 if no triggered ran, >0 if OK
+	 */
+	public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
+	{
+		if (empty($conf->settlements) || empty($conf->settlements->enabled)) {
+			return 0; // If module is not enabled, we do nothing
+		}
+
+		// Put here code you want to execute when a Dolibarr business events occurs.
+		// Data and type of action are stored into $object and $action
+
+		// You can isolate code for each action in a separate method: this method should be named like the trigger in camelCase.
+		// For example : COMPANY_CREATE => public function companyCreate($action, $object, User $user, Translate $langs, Conf $conf)
+		$methodName = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($action)))));
+		$callback = array($this, $methodName);
+		if (is_callable($callback)) {
+			dol_syslog(
+				"Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id
+			);
+
+			return call_user_func($callback, $action, $object, $user, $langs, $conf);
+		}
+		;
+
+		// Or you can execute some code here
+		//print $action;
+		//print '<br>';
+		//print_r($object);
+		//print $object->ref;
+		//print $object->table_element;
+		//exit;
+		switch ($action) {
+			case 'GROUP_CREATE':
+				global $db, $user;
+				$fk_groupid = $object->id;
+				$fk_group_entity = $object->fk_entity;
+				$group_ref = $object->ref;
+
+				//létre kell hoznom egy llx_settlements_grouptools rekordott a groupusernevévelm entityjével
+				$grouptoolsObj = new GroupTools($db);
+				$grouptoolsObj->ref = $group_ref;
+				$grouptoolsObj->label = $group_ref;
+				$grouptoolsObj->fk_entity = $fk_group_entity;
+				$result = $grouptoolsObj->create($user);
+
+
+				//össze kell rendelnem őket a llx_settlements_usergrouptoolgroup táblában fk_groupid és fk_group_tools_id
+				$usergrouptoolgroupObj = new UserGroupToolGroup($db);
+				$usergrouptoolgroupObj->ref = $group_ref;
+				$usergrouptoolgroupObj->label = $group_ref;
+				$usergrouptoolgroupObj->fk_groupid = $fk_groupid;
+				$usergrouptoolgroupObj->fk_group_tools_id = $result;
+				$result2 = $usergrouptoolgroupObj->create($user);
+
+				if ($object->single_user_group == 1) {
+					$fk_user = $object->fk_user;
+					$group_id = $object->id;
+					$groupusers = new GroupUsers($this->db);
+					$groupusers->createGroupUserRow($group_id, $fk_user);
+				} elseif ($object->hotelgroup == 1) {
+					$fk_hotel_id = $object->hotel;
+					$group_id = $object->id;
+					$rowid = $object->grouphotels_id;
+					$groupHotels = new GroupHotels($this->db);
+					$groupHotels->updateGroupHotelRow($group_id, $fk_hotel_id, $rowid);
+				} else {
+					$object->single_user_group = null;
+				}
+				break;
+
+			case 'USERGROUPTOOLGROUP_DELETE':
+				$usergrouptoolgroupnaplo = new UserGroupToolGroupNaplo($this->db);
+				$usergrouptoolgroupnaplo->usergroup_toolgroup_id = $object->id;
+				$usergrouptoolgroupnaplo->fk_groupid = $object->fk_groupid;
+				$usergrouptoolgroupnaplo->fk_group_tools_id = $object->fk_group_tools_id;
+				$usergrouptoolgroupnaplo->status = 0;
+				$usergrouptoolgroupnaplo->create($user);
+				break;
+			case 'USERGROUPTOOLGROUP_CREATE':
+				$usergrouptoolgroupnaplo = new UserGroupToolGroupNaplo($this->db);
+				$usergrouptoolgroupnaplo->usergroup_toolgroup_id = $object->id;
+				$usergrouptoolgroupnaplo->fk_groupid = $object->fk_groupid;
+				$usergrouptoolgroupnaplo->fk_group_tools_id = $object->fk_group_tools_id;
+				$usergrouptoolgroupnaplo->status = 1;
+				$usergrouptoolgroupnaplo->create($user);
+				break;
+			case 'GROUP_MODIFY':
+				if ($object->hotelgroup == 1) {
+					$fk_hotel_id = $object->hotel;
+					$group_id = $object->id;
+					$rowid = $object->grouphotels_id;
+					$groupHotels = new GroupHotels($this->db);
+					$groupHotels->updateGroupHotelRow($group_id, $fk_hotel_id, $rowid);
+				}
+				if ($object->single_user_group == 1) {
+					$fk_user = $object->fk_user;
+					$group_id = $object->id;
+					$rowid = $object->group_user_id;
+					$groupusers = new GroupUsers($this->db);
+					$groupusers->updateGroupUserRow($group_id, $fk_user, $rowid);
+				}
+				if ($object->table_element == 'settlements_group') {
+					$sql = "update llx_settlements_grouptools as sgtup SET ref = '{$object->ref}', label = '{$object->ref}' WHERE sgtup.rowid IN (
+						SELECT sgt.rowid FROM public.llx_settlements_group as sg
+						INNER JOIN llx_settlements_usergrouptoolgroup as sugtg ON sugtg.fk_groupid = sg.rowid
+						INNER JOIN llx_settlements_grouptools as sgt ON sgt.rowid = sugtg.fk_group_tools_id
+						WHERE sg.rowid = {$object->id}
+						ORDER BY sg.rowid ASC
+						)";
+					$result = $this->db->query($sql);
+
+				}
+				break;
+			case 'GROUP_DELETE':
+				global $db;
+				$errors = 0;
+				if ($object->table_element == 'settlements_group') {
+					$db->begin();
+					$groupusers = new GroupUsers($this->db);
+					$result = $groupusers->fetchAll('ASC', 'fk_user', 0, 0, array('customsql' => 'fk_settlements_group = ' . ((int) $object->id)));
+					foreach ($result as $row) {
+						$result = $groupusers->deleteLine($user, $row->id);
+						if(!$result){
+							$errors++;
+						}
+					}
+					$usergrouptoolgroupObj = new UserGroupToolGroup($db);
+					$grouptoolsObj = new Grouptools($db);
+					$resultUserGroupToolGroup = $usergrouptoolgroupObj->fetchAll('ASC', 'rowid', 0, 0, array('customsql' => 'fk_groupid = ' . (int) $object->id));
+					foreach ($resultUserGroupToolGroup as $record) {
+						$result1 = $grouptoolsObj->deleteLine($user, $record->fk_group_tools_id);
+						if(!$result1){
+							$errors++;
+						}
+						$result2 = $usergrouptoolgroupObj->deleteLine($user, $object->id);
+						if(!$result2){
+							$errors++;
+						}
+					}
+					if(!$errors){
+						$db->commit();
+					}else{
+						$db->rollback();
+						setEventMessage('Error', 'error');
+					}
+				}
+				break;
+			//case 'USERGROUP_MODIFY':			
+			/* case 'LINEGROUPUSERS_DELETE':
+										   $data['id'] = GETPOST('id', 'int');
+										   $data['action'] = GETPOST('massaction', 'alpha');
+										   $data['toselect'] = GETPOST('toselect', 'array');
+										   $userNaplo = new UserNaplo($this->db);
+										   $userNaplo->createUserNaplo($user, $data);
+										   dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id);
+										   break;
+
+									   case 'GROUPUSERS_CREATE':
+										   $data['id'] = GETPOST('id', 'int');
+										   $data['action'] = GETPOST('massactionadd', 'alpha');
+										   $data['toselect'] = GETPOST('toselectnewuser', 'array');
+										   $userNaplo = new UserNaplo($this->db);
+										   $userNaplo->createUserNaplo($user, $data);
+										   dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id);
+										   break; */
+			/* case 'USER_MODIFY':
+										   global $user;
+										   $userNaplo = new UserNaplo($this->db);
+										   $userNaplo->createUserNaplo($user, $object);
+										   dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id);
+										   break; */
+			// Users
+			//case 'USER_CREATE':
+			//case 'USER_MODIFY':
+			//case 'USER_NEW_PASSWORD':
+			//case 'USER_ENABLEDISABLE':
+			//case 'USER_DELETE':
+
+			// Actions
+			//case 'ACTION_MODIFY':
+			//case 'ACTION_CREATE':
+			//case 'ACTION_DELETE':
+
+			// Groups
+			//case 'USERGROUP_CREATE':
+			//case 'USERGROUP_MODIFY':
+			//case 'USERGROUP_DELETE':
+
+			// Companies
+			//case 'COMPANY_CREATE':
+			//case 'COMPANY_MODIFY':
+			//case 'COMPANY_DELETE':
+
+			// Contacts
+			//case 'CONTACT_CREATE':
+			//case 'CONTACT_MODIFY':
+			//case 'CONTACT_DELETE':
+			//case 'CONTACT_ENABLEDISABLE':
+
+			// Products
+			//case 'PRODUCT_CREATE':
+			//case 'PRODUCT_MODIFY':
+			//case 'PRODUCT_DELETE':
+			//case 'PRODUCT_PRICE_MODIFY':
+			//case 'PRODUCT_SET_MULTILANGS':
+			//case 'PRODUCT_DEL_MULTILANGS':
+
+			//Stock mouvement
+			//case 'STOCK_MOVEMENT':
+
+			//MYECMDIR
+			//case 'MYECMDIR_CREATE':
+			//case 'MYECMDIR_MODIFY':
+			//case 'MYECMDIR_DELETE':
+
+			// Customer orders
+			//case 'ORDER_CREATE':
+			//case 'ORDER_MODIFY':
+			//case 'ORDER_VALIDATE':
+			//case 'ORDER_DELETE':
+			//case 'ORDER_CANCEL':
+			//case 'ORDER_SENTBYMAIL':
+			//case 'ORDER_CLASSIFY_BILLED':
+			//case 'ORDER_SETDRAFT':
+			//case 'LINEORDER_INSERT':
+			//case 'LINEORDER_UPDATE':
+			//case 'LINEORDER_DELETE':
+
+			// Supplier orders
+			//case 'ORDER_SUPPLIER_CREATE':
+			//case 'ORDER_SUPPLIER_MODIFY':
+			//case 'ORDER_SUPPLIER_VALIDATE':
+			//case 'ORDER_SUPPLIER_DELETE':
+			//case 'ORDER_SUPPLIER_APPROVE':
+			//case 'ORDER_SUPPLIER_REFUSE':
+			//case 'ORDER_SUPPLIER_CANCEL':
+			//case 'ORDER_SUPPLIER_SENTBYMAIL':
+			//case 'ORDER_SUPPLIER_DISPATCH':
+			//case 'LINEORDER_SUPPLIER_DISPATCH':
+			//case 'LINEORDER_SUPPLIER_CREATE':
+			//case 'LINEORDER_SUPPLIER_UPDATE':
+			//case 'LINEORDER_SUPPLIER_DELETE':
+
+			// Proposals
+			//case 'PROPAL_CREATE':
+			//case 'PROPAL_MODIFY':
+			//case 'PROPAL_VALIDATE':
+			//case 'PROPAL_SENTBYMAIL':
+			//case 'PROPAL_CLOSE_SIGNED':
+			//case 'PROPAL_CLOSE_REFUSED':
+			//case 'PROPAL_DELETE':
+			//case 'LINEPROPAL_INSERT':
+			//case 'LINEPROPAL_UPDATE':
+			//case 'LINEPROPAL_DELETE':
+
+			// SupplierProposal
+			//case 'SUPPLIER_PROPOSAL_CREATE':
+			//case 'SUPPLIER_PROPOSAL_MODIFY':
+			//case 'SUPPLIER_PROPOSAL_VALIDATE':
+			//case 'SUPPLIER_PROPOSAL_SENTBYMAIL':
+			//case 'SUPPLIER_PROPOSAL_CLOSE_SIGNED':
+			//case 'SUPPLIER_PROPOSAL_CLOSE_REFUSED':
+			//case 'SUPPLIER_PROPOSAL_DELETE':
+			//case 'LINESUPPLIER_PROPOSAL_INSERT':
+			//case 'LINESUPPLIER_PROPOSAL_UPDATE':
+			//case 'LINESUPPLIER_PROPOSAL_DELETE':
+
+			// Contracts
+			//case 'CONTRACT_CREATE':
+			//case 'CONTRACT_MODIFY':
+			//case 'CONTRACT_ACTIVATE':
+			//case 'CONTRACT_CANCEL':
+			//case 'CONTRACT_CLOSE':
+			//case 'CONTRACT_DELETE':
+			//case 'LINECONTRACT_INSERT':
+			//case 'LINECONTRACT_UPDATE':
+			//case 'LINECONTRACT_DELETE':
+
+			// Bills
+			//case 'BILL_CREATE':
+			//case 'BILL_MODIFY':
+			//case 'BILL_VALIDATE':
+			//case 'BILL_UNVALIDATE':
+			//case 'BILL_SENTBYMAIL':
+			//case 'BILL_CANCEL':
+			//case 'BILL_DELETE':
+			//case 'BILL_PAYED':
+			//case 'LINEBILL_INSERT':
+			//case 'LINEBILL_UPDATE':
+			//case 'LINEBILL_DELETE':
+
+			//Supplier Bill
+			//case 'BILL_SUPPLIER_CREATE':
+			//case 'BILL_SUPPLIER_UPDATE':
+			//case 'BILL_SUPPLIER_DELETE':
+			//case 'BILL_SUPPLIER_PAYED':
+			//case 'BILL_SUPPLIER_UNPAYED':
+			//case 'BILL_SUPPLIER_VALIDATE':
+			//case 'BILL_SUPPLIER_UNVALIDATE':
+			//case 'LINEBILL_SUPPLIER_CREATE':
+			//case 'LINEBILL_SUPPLIER_UPDATE':
+			//case 'LINEBILL_SUPPLIER_DELETE':
+
+			// Payments
+			//case 'PAYMENT_CUSTOMER_CREATE':
+			//case 'PAYMENT_SUPPLIER_CREATE':
+			//case 'PAYMENT_ADD_TO_BANK':
+			//case 'PAYMENT_DELETE':
+
+			// Online
+			//case 'PAYMENT_PAYBOX_OK':
+			//case 'PAYMENT_PAYPAL_OK':
+			//case 'PAYMENT_STRIPE_OK':
+
+			// Donation
+			//case 'DON_CREATE':
+			//case 'DON_UPDATE':
+			//case 'DON_DELETE':
+
+			// Interventions
+			//case 'FICHINTER_CREATE':
+			//case 'FICHINTER_MODIFY':
+			//case 'FICHINTER_VALIDATE':
+			//case 'FICHINTER_DELETE':
+			//case 'LINEFICHINTER_CREATE':
+			//case 'LINEFICHINTER_UPDATE':
+			//case 'LINEFICHINTER_DELETE':
+
+			// Members
+			//case 'MEMBER_CREATE':
+			//case 'MEMBER_VALIDATE':
+			//case 'MEMBER_SUBSCRIPTION':
+			//case 'MEMBER_MODIFY':
+			//case 'MEMBER_NEW_PASSWORD':
+			//case 'MEMBER_RESILIATE':
+			//case 'MEMBER_DELETE':
+
+			// Categories
+			//case 'CATEGORY_CREATE':
+			//case 'CATEGORY_MODIFY':
+			//case 'CATEGORY_DELETE':
+			//case 'CATEGORY_SET_MULTILANGS':
+
+			// Projects
+			//case 'PROJECT_CREATE':
+			//case 'PROJECT_MODIFY':
+			//case 'PROJECT_DELETE':
+
+			// Project tasks
+			//case 'TASK_CREATE':
+			//case 'TASK_MODIFY':
+			//case 'TASK_DELETE':
+
+			// Task time spent
+			//case 'TASK_TIMESPENT_CREATE':
+			//case 'TASK_TIMESPENT_MODIFY':
+			//case 'TASK_TIMESPENT_DELETE':
+			//case 'PROJECT_ADD_CONTACT':
+			//case 'PROJECT_DELETE_CONTACT':
+			//case 'PROJECT_DELETE_RESOURCE':
+
+			// Shipping
+			//case 'SHIPPING_CREATE':
+			//case 'SHIPPING_MODIFY':
+			//case 'SHIPPING_VALIDATE':
+			//case 'SHIPPING_SENTBYMAIL':
+			//case 'SHIPPING_BILLED':
+			//case 'SHIPPING_CLOSED':
+			//case 'SHIPPING_REOPEN':
+			//case 'SHIPPING_DELETE':
+
+			// and more...
+
+			default:
+				dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id);
+				break;
+		}
+
+		return 0;
+	}
+}

+ 39 - 22
custom/voucher/core/actions_addupdatedelete.inc.php

@@ -43,21 +43,32 @@ if (!empty($permissionedit) && empty($permissiontoadd)) {
 if ($cancel) {
 if ($cancel) {
 	/*var_dump($cancel);var_dump($backtopage);var_dump($backtopageforcancel);exit;*/
 	/*var_dump($cancel);var_dump($backtopage);var_dump($backtopageforcancel);exit;*/
 	if (!empty($backtopageforcancel)) {
 	if (!empty($backtopageforcancel)) {
-		header("Location: ".$backtopageforcancel);
+		header("Location: " . $backtopageforcancel);
 		exit;
 		exit;
 	} elseif (!empty($backtopage)) {
 	} elseif (!empty($backtopage)) {
-		header("Location: ".$backtopage);
+		header("Location: " . $backtopage);
 		exit;
 		exit;
 	}
 	}
 	$action = '';
 	$action = '';
 }
 }
 
 
 
 
+//print_r($_REQUEST);exit;
+
 // Action to add record
 // Action to add record
 if ($action == 'add' && !empty($permissiontoadd)) {
 if ($action == 'add' && !empty($permissiontoadd)) {
+
+	# PDF creation
+	$html = 'asdsada';
+	$pdf = new SettlementsPDFPrint($html);
+	$pdfforQRCode = pdf_getInstance('');
+	$voucherPDF = $pdf->generateVoucherPDF();
+	$qrcodestring = 'voucher_QRCODE_' . time();
+	$html .= $qrcodestring;
+
 	foreach ($object->fields as $key => $val) {
 	foreach ($object->fields as $key => $val) {
 		if ($object->fields[$key]['type'] == 'duration') {
 		if ($object->fields[$key]['type'] == 'duration') {
-			if (GETPOST($key.'hour') == '' && GETPOST($key.'min') == '') {
+			if (GETPOST($key . 'hour') == '' && GETPOST($key . 'min') == '') {
 				continue; // The field was not submited to be saved
 				continue; // The field was not submited to be saved
 			}
 			}
 		} else {
 		} else {
@@ -79,18 +90,18 @@ if ($action == 'add' && !empty($permissiontoadd)) {
 		if (in_array($object->fields[$key]['type'], array('text', 'html'))) {
 		if (in_array($object->fields[$key]['type'], array('text', 'html'))) {
 			$value = GETPOST($key, 'restricthtml');
 			$value = GETPOST($key, 'restricthtml');
 		} elseif ($object->fields[$key]['type'] == 'date') {
 		} elseif ($object->fields[$key]['type'] == 'date') {
-			$value = dol_mktime(12, 0, 0, GETPOST($key.'month', 'int'), GETPOST($key.'day', 'int'), GETPOST($key.'year', 'int')); // for date without hour, we use gmt
+			$value = dol_mktime(12, 0, 0, GETPOST($key . 'month', 'int'), GETPOST($key . 'day', 'int'), GETPOST($key . 'year', 'int')); // for date without hour, we use gmt
 		} elseif ($object->fields[$key]['type'] == 'datetime') {
 		} elseif ($object->fields[$key]['type'] == 'datetime') {
-			$value = dol_mktime(GETPOST($key.'hour', 'int'), GETPOST($key.'min', 'int'), GETPOST($key.'sec', 'int'), GETPOST($key.'month', 'int'), GETPOST($key.'day', 'int'), GETPOST($key.'year', 'int'), 'tzuserrel');
+			$value = dol_mktime(GETPOST($key . 'hour', 'int'), GETPOST($key . 'min', 'int'), GETPOST($key . 'sec', 'int'), GETPOST($key . 'month', 'int'), GETPOST($key . 'day', 'int'), GETPOST($key . 'year', 'int'), 'tzuserrel');
 		} elseif ($object->fields[$key]['type'] == 'duration') {
 		} elseif ($object->fields[$key]['type'] == 'duration') {
-			$value = 60 * 60 * GETPOST($key.'hour', 'int') + 60 * GETPOST($key.'min', 'int');
+			$value = 60 * 60 * GETPOST($key . 'hour', 'int') + 60 * GETPOST($key . 'min', 'int');
 		} elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) {
 		} elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) {
 			$value = price2num(GETPOST($key, 'alphanohtml')); // To fix decimal separator according to lang setup
 			$value = price2num(GETPOST($key, 'alphanohtml')); // To fix decimal separator according to lang setup
 		} elseif ($object->fields[$key]['type'] == 'boolean') {
 		} elseif ($object->fields[$key]['type'] == 'boolean') {
 			$value = ((GETPOST($key) == '1' || GETPOST($key) == 'on') ? 1 : 0);
 			$value = ((GETPOST($key) == '1' || GETPOST($key) == 'on') ? 1 : 0);
 		} elseif ($object->fields[$key]['type'] == 'reference') {
 		} elseif ($object->fields[$key]['type'] == 'reference') {
 			$tmparraykey = array_keys($object->param_list);
 			$tmparraykey = array_keys($object->param_list);
-			$value = $tmparraykey[GETPOST($key)].','.GETPOST($key.'2');
+			$value = $tmparraykey[GETPOST($key)] . ',' . GETPOST($key . '2');
 		} elseif (preg_match('/^chkbxlst:(.*)/', $object->fields[$key]['type'])) {
 		} elseif (preg_match('/^chkbxlst:(.*)/', $object->fields[$key]['type'])) {
 			$value = '';
 			$value = '';
 			$values_arr = GETPOST($key, 'array');
 			$values_arr = GETPOST($key, 'array');
@@ -99,7 +110,9 @@ if ($action == 'add' && !empty($permissiontoadd)) {
 			}
 			}
 		} else {
 		} else {
 			if ($key == 'lang') {
 			if ($key == 'lang') {
-				$value = GETPOST($key, 'aZ09') ?GETPOST($key, 'aZ09') : "";
+				$value = GETPOST($key, 'aZ09') ? GETPOST($key, 'aZ09') : "";
+			} elseif ($key == 'pdf_path'){
+				$value = $voucherPDF;
 			} else {
 			} else {
 				$value = GETPOST($key, 'alphanohtml');
 				$value = GETPOST($key, 'alphanohtml');
 			}
 			}
@@ -130,7 +143,7 @@ if ($action == 'add' && !empty($permissiontoadd)) {
 			}
 			}
 		}
 		}
 	}
 	}
-
+	$object->pdf_path = $voucherPDF;
 	// Fill array 'array_options' with data from add form
 	// Fill array 'array_options' with data from add form
 	if (!$error) {
 	if (!$error) {
 		$ret = $extrafields->setOptionalsFromPost(null, $object, '', 1);
 		$ret = $extrafields->setOptionalsFromPost(null, $object, '', 1);
@@ -144,6 +157,10 @@ if ($action == 'add' && !empty($permissiontoadd)) {
 
 
 		$result = $object->create($user);
 		$result = $object->create($user);
 		if ($result > 0) {
 		if ($result > 0) {
+
+			# BBTICKET and BBTICKETPRINTING
+			print_r($object);exit;
+
 			// Creation OK
 			// Creation OK
 			if (isModEnabled('categorie') && method_exists($object, 'setCategories')) {
 			if (isModEnabled('categorie') && method_exists($object, 'setCategories')) {
 				$categories = GETPOST('categories', 'array:int');
 				$categories = GETPOST('categories', 'array:int');
@@ -181,7 +198,7 @@ if ($action == 'update' && !empty($permissiontoadd)) {
 	foreach ($object->fields as $key => $val) {
 	foreach ($object->fields as $key => $val) {
 		// Check if field was submited to be edited
 		// Check if field was submited to be edited
 		if ($object->fields[$key]['type'] == 'duration') {
 		if ($object->fields[$key]['type'] == 'duration') {
-			if (!GETPOSTISSET($key.'hour') || !GETPOSTISSET($key.'min')) {
+			if (!GETPOSTISSET($key . 'hour') || !GETPOSTISSET($key . 'min')) {
 				continue; // The field was not submited to be saved
 				continue; // The field was not submited to be saved
 			}
 			}
 		} elseif ($object->fields[$key]['type'] == 'boolean') {
 		} elseif ($object->fields[$key]['type'] == 'boolean') {
@@ -213,12 +230,12 @@ if ($action == 'update' && !empty($permissiontoadd)) {
 				$value = GETPOST($key, 'restricthtml');
 				$value = GETPOST($key, 'restricthtml');
 			}
 			}
 		} elseif ($object->fields[$key]['type'] == 'date') {
 		} elseif ($object->fields[$key]['type'] == 'date') {
-			$value = dol_mktime(12, 0, 0, GETPOST($key.'month', 'int'), GETPOST($key.'day', 'int'), GETPOST($key.'year', 'int')); // for date without hour, we use gmt
+			$value = dol_mktime(12, 0, 0, GETPOST($key . 'month', 'int'), GETPOST($key . 'day', 'int'), GETPOST($key . 'year', 'int')); // for date without hour, we use gmt
 		} elseif ($object->fields[$key]['type'] == 'datetime') {
 		} elseif ($object->fields[$key]['type'] == 'datetime') {
-			$value = dol_mktime(GETPOST($key.'hour', 'int'), GETPOST($key.'min', 'int'), GETPOST($key.'sec', 'int'), GETPOST($key.'month', 'int'), GETPOST($key.'day', 'int'), GETPOST($key.'year', 'int'), 'tzuserrel');
+			$value = dol_mktime(GETPOST($key . 'hour', 'int'), GETPOST($key . 'min', 'int'), GETPOST($key . 'sec', 'int'), GETPOST($key . 'month', 'int'), GETPOST($key . 'day', 'int'), GETPOST($key . 'year', 'int'), 'tzuserrel');
 		} elseif ($object->fields[$key]['type'] == 'duration') {
 		} elseif ($object->fields[$key]['type'] == 'duration') {
-			if (GETPOST($key.'hour', 'int') != '' || GETPOST($key.'min', 'int') != '') {
-				$value = 60 * 60 * GETPOST($key.'hour', 'int') + 60 * GETPOST($key.'min', 'int');
+			if (GETPOST($key . 'hour', 'int') != '' || GETPOST($key . 'min', 'int') != '') {
+				$value = 60 * 60 * GETPOST($key . 'hour', 'int') + 60 * GETPOST($key . 'min', 'int');
 			} else {
 			} else {
 				$value = '';
 				$value = '';
 			}
 			}
@@ -227,7 +244,7 @@ if ($action == 'update' && !empty($permissiontoadd)) {
 		} elseif ($object->fields[$key]['type'] == 'boolean') {
 		} elseif ($object->fields[$key]['type'] == 'boolean') {
 			$value = ((GETPOST($key, 'aZ09') == 'on' || GETPOST($key, 'aZ09') == '1') ? 1 : 0);
 			$value = ((GETPOST($key, 'aZ09') == 'on' || GETPOST($key, 'aZ09') == '1') ? 1 : 0);
 		} elseif ($object->fields[$key]['type'] == 'reference') {
 		} elseif ($object->fields[$key]['type'] == 'reference') {
-			$value = array_keys($object->param_list)[GETPOST($key)].','.GETPOST($key.'2');
+			$value = array_keys($object->param_list)[GETPOST($key)] . ',' . GETPOST($key . '2');
 		} elseif (preg_match('/^chkbxlst:/', $object->fields[$key]['type'])) {
 		} elseif (preg_match('/^chkbxlst:/', $object->fields[$key]['type'])) {
 			$value = '';
 			$value = '';
 			$values_arr = GETPOST($key, 'array');
 			$values_arr = GETPOST($key, 'array');
@@ -308,7 +325,7 @@ if (preg_match('/^set(\w+)$/', $action, $reg) && GETPOST('id', 'int') > 0 && !em
 	$keyforfield = $reg[1];
 	$keyforfield = $reg[1];
 	if (property_exists($object, $keyforfield)) {
 	if (property_exists($object, $keyforfield)) {
 		if (!empty($object->fields[$keyforfield]) && in_array($object->fields[$keyforfield]['type'], array('date', 'datetime', 'timestamp'))) {
 		if (!empty($object->fields[$keyforfield]) && in_array($object->fields[$keyforfield]['type'], array('date', 'datetime', 'timestamp'))) {
-			$object->$keyforfield = dol_mktime(GETPOST($keyforfield.'hour'), GETPOST($keyforfield.'min'), GETPOST($keyforfield.'sec'), GETPOST($keyforfield.'month'), GETPOST($keyforfield.'day'), GETPOST($keyforfield.'year'));
+			$object->$keyforfield = dol_mktime(GETPOST($keyforfield . 'hour'), GETPOST($keyforfield . 'min'), GETPOST($keyforfield . 'sec'), GETPOST($keyforfield . 'month'), GETPOST($keyforfield . 'day'), GETPOST($keyforfield . 'year'));
 		} else {
 		} else {
 			$object->$keyforfield = GETPOST($keyforfield);
 			$object->$keyforfield = GETPOST($keyforfield);
 		}
 		}
@@ -321,7 +338,7 @@ if (preg_match('/^set(\w+)$/', $action, $reg) && GETPOST('id', 'int') > 0 && !em
 		} else {
 		} else {
 			$error++;
 			$error++;
 			setEventMessages($object->error, $object->errors, 'errors');
 			setEventMessages($object->error, $object->errors, 'errors');
-			$action = 'edit'.$reg[1];
+			$action = 'edit' . $reg[1];
 		}
 		}
 	}
 	}
 }
 }
@@ -331,14 +348,14 @@ if ($action == "update_extras" && GETPOST('id', 'int') > 0 && !empty($permission
 	$object->fetch(GETPOST('id', 'int'));
 	$object->fetch(GETPOST('id', 'int'));
 
 
 	$attributekey = GETPOST('attribute', 'alpha');
 	$attributekey = GETPOST('attribute', 'alpha');
-	$attributekeylong = 'options_'.$attributekey;
+	$attributekeylong = 'options_' . $attributekey;
 
 
-	if (GETPOSTISSET($attributekeylong.'day') && GETPOSTISSET($attributekeylong.'month') && GETPOSTISSET($attributekeylong.'year')) {
+	if (GETPOSTISSET($attributekeylong . 'day') && GETPOSTISSET($attributekeylong . 'month') && GETPOSTISSET($attributekeylong . 'year')) {
 		// This is properties of a date
 		// This is properties of a date
-		$object->array_options['options_'.$attributekey] = dol_mktime(GETPOST($attributekeylong.'hour', 'int'), GETPOST($attributekeylong.'min', 'int'), GETPOST($attributekeylong.'sec', 'int'), GETPOST($attributekeylong.'month', 'int'), GETPOST($attributekeylong.'day', 'int'), GETPOST($attributekeylong.'year', 'int'));
+		$object->array_options['options_' . $attributekey] = dol_mktime(GETPOST($attributekeylong . 'hour', 'int'), GETPOST($attributekeylong . 'min', 'int'), GETPOST($attributekeylong . 'sec', 'int'), GETPOST($attributekeylong . 'month', 'int'), GETPOST($attributekeylong . 'day', 'int'), GETPOST($attributekeylong . 'year', 'int'));
 		//var_dump(dol_print_date($object->array_options['options_'.$attributekey]));exit;
 		//var_dump(dol_print_date($object->array_options['options_'.$attributekey]));exit;
 	} else {
 	} else {
-		$object->array_options['options_'.$attributekey] = GETPOST($attributekeylong, 'alpha');
+		$object->array_options['options_' . $attributekey] = GETPOST($attributekeylong, 'alpha');
 	}
 	}
 
 
 	$result = $object->insertExtraFields(empty($triggermodname) ? '' : $triggermodname, $user);
 	$result = $object->insertExtraFields(empty($triggermodname) ? '' : $triggermodname, $user);
@@ -412,7 +429,7 @@ if ($action == 'confirm_deleteline' && $confirm == 'yes' && !empty($permissionto
 		setEventMessages($langs->trans('RecordDeleted'), null, 'mesgs');
 		setEventMessages($langs->trans('RecordDeleted'), null, 'mesgs');
 
 
 		if (empty($noback)) {
 		if (empty($noback)) {
-			header('Location: '.((empty($backtopage)) ? $_SERVER["PHP_SELF"].'?id='.$object->id : $backtopage));
+			header('Location: ' . ((empty($backtopage)) ? $_SERVER["PHP_SELF"] . '?id=' . $object->id : $backtopage));
 			exit;
 			exit;
 		}
 		}
 	} else {
 	} else {

+ 8 - 59
custom/voucher/voucherhistory_card.php

@@ -1,48 +1,4 @@
 <?php
 <?php
-/* Copyright (C) 2017 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2024 László Szollősi
- *
- * 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.
- *
- * This 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *   	\file       voucherhistory_card.php
- *		\ingroup    voucher
- *		\brief      Page to create/edit/view voucherhistory
- */
-
-//if (! defined('NOREQUIREDB'))              define('NOREQUIREDB', '1');				// Do not create database handler $db
-//if (! defined('NOREQUIREUSER'))            define('NOREQUIREUSER', '1');				// Do not load object $user
-//if (! defined('NOREQUIRESOC'))             define('NOREQUIRESOC', '1');				// Do not load object $mysoc
-//if (! defined('NOREQUIRETRAN'))            define('NOREQUIRETRAN', '1');				// Do not load object $langs
-//if (! defined('NOSCANGETFORINJECTION'))    define('NOSCANGETFORINJECTION', '1');		// Do not check injection attack on GET parameters
-//if (! defined('NOSCANPOSTFORINJECTION'))   define('NOSCANPOSTFORINJECTION', '1');		// Do not check injection attack on POST parameters
-//if (! defined('NOTOKENRENEWAL'))           define('NOTOKENRENEWAL', '1');				// Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
-//if (! defined('NOSTYLECHECK'))             define('NOSTYLECHECK', '1');				// Do not check style html tag into posted data
-//if (! defined('NOREQUIREMENU'))            define('NOREQUIREMENU', '1');				// If there is no need to load and show top and left menu
-//if (! defined('NOREQUIREHTML'))            define('NOREQUIREHTML', '1');				// If we don't need to load the html.form.class.php
-//if (! defined('NOREQUIREAJAX'))            define('NOREQUIREAJAX', '1');       	  	// Do not load ajax.lib.php library
-//if (! defined("NOLOGIN"))                  define("NOLOGIN", '1');					// If this page is public (can be called outside logged session). This include the NOIPCHECK too.
-//if (! defined('NOIPCHECK'))                define('NOIPCHECK', '1');					// Do not check IP defined into conf $dolibarr_main_restrict_ip
-//if (! defined("MAIN_LANG_DEFAULT"))        define('MAIN_LANG_DEFAULT', 'auto');					// Force lang to a particular value
-//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule');	// Force authentication handler
-//if (! defined("MAIN_SECURITY_FORCECSP"))   define('MAIN_SECURITY_FORCECSP', 'none');	// Disable all Content Security Policies
-//if (! defined('CSRFCHECK_WITH_TOKEN'))     define('CSRFCHECK_WITH_TOKEN', '1');		// Force use of CSRF protection with tokens even for GET
-//if (! defined('NOBROWSERNOTIF'))     		 define('NOBROWSERNOTIF', '1');				// Disable browser notification
-//if (! defined('NOSESSION'))     		     define('NOSESSION', '1');				    // Disable session
-
-// Load Dolibarr environment
 $res = 0;
 $res = 0;
 // Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
 // Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
 if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
 if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
@@ -83,6 +39,8 @@ require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
 require_once DOL_DOCUMENT_ROOT . '/custom/voucher/class/helper.class.php';
 require_once DOL_DOCUMENT_ROOT . '/custom/voucher/class/helper.class.php';
 require_once DOL_DOCUMENT_ROOT . '/custom/voucher/class/voucherhistory.class.php';
 require_once DOL_DOCUMENT_ROOT . '/custom/voucher/class/voucherhistory.class.php';
 require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
 require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
+require_once DOL_DOCUMENT_ROOT . '/custom/settlements/core/tpl/printPDF_szisz.php';
+require_once DOL_DOCUMENT_ROOT . '/core/lib/pdf.lib.php';
 
 
 dol_include_once('/voucher/class/voucherhistory.class.php');
 dol_include_once('/voucher/class/voucherhistory.class.php');
 dol_include_once('/voucher/lib/voucher_voucherhistory.lib.php');
 dol_include_once('/voucher/lib/voucher_voucherhistory.lib.php');
@@ -155,11 +113,6 @@ if ($enablepermissioncheck) {
 
 
 $upload_dir = $conf->voucher->multidir_output[isset($object->entity) ? $object->entity : 1] . '/voucherhistory';
 $upload_dir = $conf->voucher->multidir_output[isset($object->entity) ? $object->entity : 1] . '/voucherhistory';
 
 
-// Security check (enable the most restrictive one)
-//if ($user->socid > 0) accessforbidden();
-//if ($user->socid > 0) $socid = $user->socid;
-//$isdraft = (isset($object->status) && ($object->status == $object::STATUS_DRAFT) ? 1 : 0);
-//restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
 if (!isModEnabled("voucher")) {
 if (!isModEnabled("voucher")) {
 	accessforbidden();
 	accessforbidden();
 }
 }
@@ -225,8 +178,8 @@ if (empty($reshook)) {
 	} */
 	} */
 
 
 	// Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen
 	// Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen
-	//include DOL_DOCUMENT_ROOT . '/custom/voucher/core/actions_addupdatedelete.inc.php';
-	include DOL_DOCUMENT_ROOT . '/core/actions_addupdatedelete.inc.php';
+	include DOL_DOCUMENT_ROOT . '/custom/voucher/core/actions_addupdatedelete.inc.php';
+	//include DOL_DOCUMENT_ROOT . '/core/actions_addupdatedelete.inc.php';
 
 
 	// Actions when linking object each other
 	// Actions when linking object each other
 	include DOL_DOCUMENT_ROOT . '/core/actions_dellink.inc.php';
 	include DOL_DOCUMENT_ROOT . '/core/actions_dellink.inc.php';
@@ -290,10 +243,6 @@ if ($action == 'create') {
 		print '<input type="hidden" name="backtopageforcancel" value="' . $backtopageforcancel . '">';
 		print '<input type="hidden" name="backtopageforcancel" value="' . $backtopageforcancel . '">';
 	}
 	}
 
 
-	print $_SESSION['token'];
-	print '<br>';
-	print $_SESSION['newtoken'];
-
 	print dol_get_fiche_head(array(), '');
 	print dol_get_fiche_head(array(), '');
 
 
 	// Set some default values
 	// Set some default values
@@ -302,8 +251,8 @@ if ($action == 'create') {
 	print '<table class="border centpercent tableforfieldcreate">' . "\n";
 	print '<table class="border centpercent tableforfieldcreate">' . "\n";
 
 
 	// Common attributes
 	// Common attributes
-	//include DOL_DOCUMENT_ROOT . '/custom/voucher/core/tpl/commonfields_add.tpl.php';
-	include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_add.tpl.php';
+	include DOL_DOCUMENT_ROOT . '/custom/voucher/core/tpl/commonfields_add.tpl.php';
+	//include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_add.tpl.php';
 
 
 	// Other attributes
 	// Other attributes
 	include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_add.tpl.php';
 	include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_add.tpl.php';
@@ -653,5 +602,5 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
 // End of page
 // End of page
 llxFooter();
 llxFooter();
 $db->close();
 $db->close();
-//echo '<link rel="stylesheet" type="text/css" href="' . dol_buildpath('/custom/voucher/css/voucher.css', 1) . '">';
-//echo '<script type="text/javascript" src="' . dol_buildpath('/custom/voucher/scripts/voucher.js', 1) . '"></script>';
+echo '<link rel="stylesheet" type="text/css" href="' . dol_buildpath('/custom/voucher/css/voucher.css', 1) . '">';
+echo '<script type="text/javascript" src="' . dol_buildpath('/custom/voucher/scripts/voucher.js', 1) . '"></script>';