api_booking.class.php 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480
  1. <?php
  2. /* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
  3. * Copyright (C) 2023 Deák Ferenc
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use Luracast\Restler\RestException;
  19. // dol_include_once('/booking/class/bookinglog.class.php');
  20. require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/api_bbus.class.php';
  21. require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/api_bbus_log.class.php';
  22. require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/apiinvoicehelper.class.php';
  23. require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/apiproductlisthelper.class.php';
  24. require_once DOL_DOCUMENT_ROOT . '/custom/booking/class/eventhelper.class.php';
  25. require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
  26. require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
  27. require_once DOL_DOCUMENT_ROOT . '/comm/action/class/actioncomm.class.php';
  28. require_once DOL_DOCUMENT_ROOT . '/custom/booking/class/preorder.class.php';
  29. require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/api_curl.class.php';
  30. require_once DOL_DOCUMENT_ROOT . '/custom/bbus/class/basicservices.class.php';
  31. /**
  32. * \file booking/class/api_booking.class.php
  33. * \ingroup booking
  34. * \brief File for API management of bookinglog.
  35. */
  36. /**
  37. * API class for booking bookinglog
  38. *
  39. * @class DolibarrApiAccess {@requires user,external}
  40. */
  41. class BookingApi extends DolibarrApi
  42. {
  43. use CurlApi;
  44. /**
  45. * @var BookingLog $bookinglog {@type BookingLog}
  46. */
  47. public $bookinglog;
  48. private User $user;
  49. /**
  50. * Constructor
  51. *
  52. * @url GET /
  53. *
  54. */
  55. public function __construct()
  56. {
  57. global $db, $user;
  58. $this->db = $db;
  59. $this->user = $user;
  60. // $this->bookinglog = new BookingLog($this->db);
  61. }
  62. #-------------------------------------------------
  63. # Vásárlási folyamat részei
  64. #-------------------------------------------------
  65. /**
  66. * Get all free spaces on a selected date
  67. *
  68. * Return an array with details
  69. *
  70. * @return array|mixed data without useless information
  71. *
  72. * @param string date_from
  73. * @param string date_to
  74. * @param int product_id
  75. * @param int participant_number
  76. *
  77. * @url POST getavailablespaces
  78. *
  79. * @throws RestException 401 Not allowed
  80. * @throws RestException 404 Not found
  81. */
  82. public function getAvailableSpaces(string $date_from, string $date_to, int $product_id, int $participant_number, string $type_id = null)
  83. {
  84. ApiBbusLog::appLog("getAvailableSpaces");
  85. /* ApiBbusLog::appLog("type_id: {$type_id}");
  86. ApiBbusLog::appLog("date_from: {$date_from}");
  87. ApiBbusLog::appLog("date_to: {$date_to}");
  88. ApiBbusLog::appLog("product_id: {$product_id}");
  89. ApiBbusLog::appLog("participant_number: {$participant_number}"); */
  90. $basicServices = new BasicServices($this->db);
  91. $resultBS = $basicServices->fetch($type_id);
  92. if ($basicServices->server_host == 'excelia') {
  93. return $this->localAvailablePlaces($date_from, $date_to, $product_id, $participant_number);
  94. } else {
  95. return $this->curlAvailablePlaces($date_from, $date_to, $product_id, $participant_number);
  96. }
  97. }
  98. /**
  99. * First step of the eventhandling
  100. * {"fk_event":669,"reservations":1,"product_id":2,"sendId":"12121212"}
  101. *
  102. * Return an array with details
  103. *
  104. * @return array|mixed data without useless information
  105. *
  106. * @param int $fk_event //selected evet from llx_event
  107. * @param int $reservations //numbers of reservations
  108. * @param int $product_id //Product
  109. * @param string $sendId //ID
  110. *
  111. * @url POST firsteventstep
  112. * @access protected
  113. * @throws RestException 401 Not allowed
  114. * @throws RestException 404 Not found
  115. * @throws RestException 506 No available spaces
  116. *
  117. */
  118. public function firstEventStep(int $fk_event, int $reservations, int $product_id, string $sendId)
  119. {
  120. ApiBbusLog::eventLog("fk_event: {$fk_event}");
  121. ApiBbusLog::eventLog("reservations: {$reservations}");
  122. ApiBbusLog::eventLog("product_id: {$product_id}");
  123. ApiBbusLog::eventLog("sendId: {$sendId}");
  124. $eventHelper = new EventHelper;
  125. if ($eventHelper->noEmptySpaces($fk_event, $reservations)) {
  126. throw new RestException(506, 'No available spaces');
  127. }
  128. if (!DolibarrApiAccess::$user->rights->facture->creer) {
  129. ApiBbusLog::eventLog("{$sendId} Insufficient rights");
  130. throw new RestException(401, 'Insufficient rights');
  131. }
  132. /**
  133. * LOG SECTION
  134. */
  135. ApiBbusLog::eventLog("{$sendId} === NEW INVOICE ===");
  136. dol_syslog("{$sendId} === NEW INVOICE ===", LOG_INFO, 0);
  137. ApiBbusLog::eventLog("{$sendId} REQUEST: {$sendId}");
  138. dol_syslog("{$sendId} REQUEST: {$sendId}", LOG_INFO, 0);
  139. ApiBbusLog::eventLog("{$sendId} User: {$this->user->firstname} {$this->user->lastname} (ID: {$this->user->id})");
  140. dol_syslog("{$sendId} User: {$this->user->firstname} {$this->user->lastname} (ID: {$this->user->id})", LOG_INFO, 0);
  141. ApiBbusLog::eventLog("{$sendId} " . json_encode([
  142. 'fk_event' => $fk_event,
  143. 'reservations' => $reservations,
  144. 'product_id' => $product_id,
  145. 'sendId' => $sendId,
  146. ]));
  147. $apiInvoiceHelper = new ApiInvoiceHelper;
  148. $createdPreOrderOBJ = [];
  149. for ($i = 1; $i <= $reservations; $i++) {
  150. dol_include_once('/comm/action/class/actioncomm.class.php');
  151. dol_include_once('/custom/booking/class/preorder.class.php');
  152. $apiInvoiceHelper->increaseParticipant($fk_event);
  153. $lines = $apiInvoiceHelper->getProductLines($product_id);
  154. foreach ($lines as $line) {
  155. $preOrderObj = new PreOrder($this->db);
  156. $preOrderObj->ref = $this->generateRandomString();
  157. $preOrderObj->fk_event = $fk_event;
  158. $preOrderObj->fk_product = $product_id;
  159. $result = $preOrderObj->create($this->user);
  160. if ($result > 0) {
  161. $createdPreOrderOBJ[] = [
  162. 'id' => $preOrderObj->id,
  163. 'ref' => $preOrderObj->ref,
  164. ];
  165. } else {
  166. ApiBbusLog::eventLog(json_encode(['error' => $preOrderObj->errors]));
  167. ApiBbusLog::eventLog("Unsaved event: " . $fk_event);
  168. throw new RestException(401, 'Unsaved event: ' . $fk_event);
  169. }
  170. }
  171. }
  172. return $createdPreOrderOBJ;
  173. }
  174. /**
  175. * Validate and save invoice
  176. * {"cardPaymentLog": "","sendId": "Xune5nQb","payment": {"datepaye": 1720005853,"paymentid": 4,"accountid": 2,"closepaidinvoices": "yes"},"preorder": [23]}
  177. *
  178. * Return an array with details
  179. *
  180. * @return array|mixed data without useless information
  181. *
  182. * @param string $sendId sendID
  183. * @param array $payment Invoice payment
  184. * @param array $preorder preorder
  185. * @param array $invoice Invoice
  186. * @param string $cardPaymentLog Card payment log data
  187. *
  188. * @url POST validateandsaveinvoice
  189. * @access protected
  190. * @throws RestException 401 Not allowed
  191. * @throws RestException 404 Not found
  192. * @throws RestException 506 No available spaces
  193. *
  194. */
  195. public function validateandsaveinvoice(string $sendId, array $payment, array $preorder, array $invoice, string $cardPaymentLog = '')
  196. {
  197. global $user, $db;
  198. $createdInvoiceData = [];
  199. $apiInvoiceHelper = new ApiInvoiceHelper;
  200. $bbusApi = new BBus();
  201. foreach ($preorder as $order) {
  202. $sql = "SELECT fk_product, fk_event FROM llx_booking_preorder WHERE rowid = {$order}";
  203. //print $sql . "\r\n";
  204. $data = $db->query($sql);
  205. if ($db->num_rows($data) > 0) {
  206. while ($row = $db->fetch_object($data)) {
  207. //print_r($row);
  208. $lines = $apiInvoiceHelper->getProductLines($row->fk_product);
  209. $createdInvoiceArray = $bbusApi->invoice($invoice, $lines, $payment, $cardPaymentLog = '', $sendId = '');
  210. $createdInvoiceData[] = $createdInvoiceArray;
  211. $bookingHistory = $this->saveEventData((int)$row->fk_event, $createdInvoiceArray['invoice']['ref'], $createdInvoiceArray['invoice']['id']);
  212. $this->updateBbticket($bookingHistory, $createdInvoiceArray['invoice']);
  213. $this->deletePreorder($preorder);
  214. }
  215. }
  216. }
  217. return $createdInvoiceData;
  218. }
  219. //P4NR6zhWHage
  220. //!!!types:
  221. /**
  222. * Get types of a bookable events
  223. *
  224. * Return an array with bookable events type list
  225. *
  226. * @return array|mixed data without useless information
  227. *
  228. * @url GET types
  229. *
  230. * @throws RestException 401 Not allowed
  231. * @throws RestException 404 Not found
  232. */
  233. public function types()
  234. {
  235. dol_include_once('/eventwizard/class/eventdetails.class.php');
  236. $EventDetails = new EventDetails($this->db);
  237. return $EventDetails->fields['type']['arrayofkeyval'];
  238. if (!DolibarrApiAccess::$user->rights->booking->types->read) {
  239. throw new RestException(401);
  240. }
  241. // dol_include_once('/booking/class/bookinglog.class.php');
  242. // $result = $this->bookinglog->fetch($id);
  243. // if (!$result) {
  244. // throw new RestException(404, 'BookingLog not found');
  245. // }
  246. // if (!DolibarrApi::_checkAccessToResource('bookinglog', $this->bookinglog->id, 'booking_bookinglog')) {
  247. // throw new RestException(401, 'Access to instance id='.$this->bookinglog->id.' of object not allowed for login '.DolibarrApiAccess::$user->login);
  248. // }
  249. // return $this->_cleanObjectDatas($this->bookinglog);
  250. }
  251. /**
  252. * Get bookable events
  253. *
  254. * Return an array with bookable events list
  255. *
  256. * @return array|mixed data without useless information
  257. *
  258. * @param int $onlyBookable
  259. * @param int $withDetails
  260. * @param int $withDates
  261. * @param int $withAviability
  262. * @url GET events
  263. *
  264. * @throws RestException 401 Not allowed
  265. * @throws RestException 404 Not found
  266. */
  267. public function events($onlyBookable = 1, $withDetails = 0, $withDates = 0, $withAviability = 0)
  268. {
  269. global $db, $conf;
  270. // if (!DolibarrApiAccess::$user->rights->booking->events->read) {
  271. // throw new RestException(401);
  272. // }
  273. $obj_ret = [];
  274. // if (!DolibarrApiAccess::$user->rights->agenda->myactions->read) {
  275. // throw new RestException(401, "Insufficient rights to read events");
  276. // }
  277. $sql = "SELECT DISTINCT ed.rowid as id";
  278. if (!empty($conf->societe->enabled)) {
  279. // if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
  280. // $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects)
  281. // }
  282. }
  283. $sql .= " ,ed.label ";
  284. $sql .= " ,eld.label as from"; //... ??
  285. $sql .= " ,ela.label as to"; //...
  286. $sql .= " FROM " . MAIN_DB_PREFIX . "actioncomm as t";
  287. $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "eventwizard_eventdetails ed ON ed.rowid = t.fk_element";
  288. $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "eventwizard_eventlocation eld ON eld.rowid = ed.fk_elventlocation_departure";
  289. $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "eventwizard_eventlocation ela ON ela.rowid = ed.fk_elventlocation_arrival";
  290. $sql .= " WHERE code = 'AC_EVENT' ";
  291. $sql .= " AND t.elementtype = 'eventdetails@eventwizard'";
  292. if ($onlyBookable) {
  293. $sql .= " AND t.datep > CURRENT_TIMESTAMP";
  294. }
  295. $result = $this->db->query($sql);
  296. if ($result) {
  297. $i = 0;
  298. // $num = $this->db->num_rows($result);
  299. // $min = min($num, ($limit <= 0 ? $num : $limit));
  300. while ($event = $this->db->fetch_object($result)) {
  301. if ($withDetails) {
  302. $event->details = $this->details($event->id);
  303. }
  304. if ($withDates) {
  305. //... $withAviability
  306. $event->dates = $this->dates($event->id);
  307. }
  308. $obj_ret[] = $event;
  309. }
  310. } else {
  311. throw new RestException(503, 'Error when retrieve Agenda Event list : ' . $this->db->lasterror());
  312. }
  313. if (!count($obj_ret)) {
  314. throw new RestException(404, 'No Agenda Event found');
  315. }
  316. return $obj_ret;
  317. }
  318. /**
  319. * Get event dates
  320. *
  321. * Return an array with event dates list
  322. *
  323. * @return array|mixed data without useless information
  324. *
  325. * @param int $id
  326. * @param int $onlyBookable
  327. * @param string $json
  328. * @url GET dates
  329. *
  330. * @throws RestException 401 Not allowed
  331. * @throws RestException 404 Not found
  332. */
  333. public function dates($id, $onlyBookable = 1, $json = null)
  334. {
  335. global $db, $conf;
  336. // if (!DolibarrApiAccess::$user->rights->booking->events->read) {
  337. // throw new RestException(401);
  338. // }
  339. $obj_ret = [];
  340. // if (!DolibarrApiAccess::$user->rights->agenda->myactions->read) {
  341. // throw new RestException(401, "Insufficient rights to read events");
  342. // }
  343. $sql = "SELECT t.id ";
  344. if (!empty($conf->societe->enabled)) {
  345. // if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
  346. // $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects)
  347. // }
  348. }
  349. $sql .= " ,ed.label, t.note ";
  350. $sql .= " ,t.datep as start, t.datep2 as end";
  351. $sql .= " ,eld.label as from"; //... ??
  352. $sql .= " ,ela.label as to"; //...
  353. $sql .= " FROM " . MAIN_DB_PREFIX . "actioncomm as t";
  354. // if (!empty($conf->societe->enabled)) {
  355. // if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
  356. // $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
  357. // }
  358. // }
  359. $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "eventwizard_eventdetails ed ON ed.rowid = t.fk_element";
  360. $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "eventwizard_eventlocation eld ON eld.rowid = ed.fk_elventlocation_departure";
  361. $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "eventwizard_eventlocation ela ON ela.rowid = ed.fk_elventlocation_arrival";
  362. // $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."eventwizard_eventoption eo ON el.rowid = ed.fk_element";
  363. // $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."eventwizard_eventproduct eo ON el.rowid = ed.fk_element";
  364. // $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."eventwizard_ eo ON el.rowid = ed.fk_element";
  365. // $sql .= ' WHERE t.entity IN ('.getEntity('agenda').')';
  366. $sql .= " WHERE code = 'AC_EVENT' ";
  367. $sql .= " AND t.fk_element = " . (int) $this->db->escape($id);
  368. $sql .= " AND t.elementtype = 'eventdetails@eventwizard'";
  369. $sql .= " AND t.datep > CURRENT_TIMESTAMP";
  370. // if (!empty($conf->societe->enabled)) {
  371. // if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
  372. // $sql .= " AND t.fk_soc = sc.fk_soc";
  373. // }
  374. // }
  375. // if ($user_ids) {
  376. // $sql .= " AND t.fk_user_action IN (".$this->db->sanitize($user_ids).")";
  377. // }
  378. // if ($socid > 0) {
  379. // $sql .= " AND t.fk_soc = ".((int) $socid);
  380. // }
  381. // Insert sale filter
  382. // if ($search_sale > 0) {
  383. // $sql .= " AND sc.fk_user = ".((int) $search_sale);
  384. // }
  385. // Add sql filters
  386. // if ($sqlfilters) {
  387. // $errormessage = '';
  388. // if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
  389. // throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage);
  390. // }
  391. // $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
  392. // $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
  393. // }
  394. // $sql .= $this->db->order($sortfield, $sortorder);
  395. // if ($limit) {
  396. // if ($page < 0) {
  397. // $page = 0;
  398. // }
  399. // $offset = $limit * $page;
  400. // $sql .= $this->db->plimit($limit + 1, $offset);
  401. // }
  402. $result = $this->db->query($sql);
  403. if ($result) {
  404. $i = 0;
  405. $num = $this->db->num_rows($result);
  406. // $min = min($num, ($limit <= 0 ? $num : $limit));
  407. while ($i < $num) {
  408. $obj_ret[] = $this->db->fetch_object($result);
  409. $i++;
  410. }
  411. } else {
  412. throw new RestException(503, 'Error when retrieve Agenda Event list : ' . $this->db->lasterror());
  413. }
  414. if (!count($obj_ret)) {
  415. throw new RestException(404, 'No Agenda Event found');
  416. }
  417. return $obj_ret;
  418. }
  419. /**
  420. * Post booking (draft)
  421. *
  422. * Return an array with draft bookings list
  423. *
  424. * @return array|mixed data without useless information
  425. *
  426. * @param int $event
  427. * @param array $details
  428. * @url POST set
  429. *
  430. * @access protected
  431. * @throws RestException 401 Not allowed
  432. * @throws RestException 404 Not found
  433. */
  434. public function set($event, $details)
  435. {
  436. if (!DolibarrApiAccess::$user->rights->booking->events->write) {
  437. throw new RestException(401);
  438. }
  439. }
  440. /**
  441. * Post booking validation
  442. *
  443. * Return an array with bookings list
  444. *
  445. * @return array|mixed data without useless information
  446. *
  447. * @param int $event
  448. * @param array $drafts
  449. * @url POST validate
  450. *
  451. * @access protected
  452. * @throws RestException 401 Not allowed
  453. * @throws RestException 404 Not found
  454. */
  455. public function validate($event, $drafts)
  456. {
  457. if (!DolibarrApiAccess::$user->rights->booking->events->write) {
  458. throw new RestException(401);
  459. }
  460. }
  461. /**
  462. * Get bookings list
  463. *
  464. * Return an array with the user's bookings list
  465. *
  466. * @return array|mixed data without useless information
  467. *
  468. * @url POST bookings
  469. *
  470. * @access protected
  471. * @throws RestException 401 Not allowed
  472. * @throws RestException 404 Not found
  473. */
  474. public function bookings()
  475. {
  476. if (!DolibarrApiAccess::$user->rights->booking->events->write) {
  477. throw new RestException(401);
  478. }
  479. }
  480. /**
  481. * Get cron to clean booking draftInvoices
  482. *
  483. * Return an array with cleaned list
  484. *
  485. * @return array|mixed data without useless information
  486. *
  487. * @url GET cron
  488. *
  489. * @access protected
  490. * @throws RestException 401 Not allowed
  491. * @throws RestException 404 Not found
  492. */
  493. public function cron()
  494. {
  495. if (!DolibarrApiAccess::$user->rights->booking->events->write) {
  496. throw new RestException(401);
  497. }
  498. }
  499. /**
  500. * Get details of a bookable event
  501. *
  502. * Return an array with details
  503. *
  504. * @return array|mixed data without useless information
  505. *
  506. * @param int $id
  507. * @url GET details
  508. *
  509. * @access protected
  510. * @throws RestException 401 Not allowed
  511. * @throws RestException 404 Not found
  512. */
  513. public function details($id)
  514. {
  515. $details = [
  516. 'tmp' => [],
  517. 'product' => [],
  518. 'min' => 0,
  519. 'id_event' => $id,
  520. // 'variants' => []
  521. ];
  522. $variants = [];
  523. dol_include_once('/eventwizard/class/eventdetails.class.php');
  524. $EventDetails = new EventDetails($this->db);
  525. if ($EventDetails->fetch($id)) {
  526. $sql = "SELECT ep.rowid ,ep.fk_eventdetails, ep.fk_product, ep.type, ep.amount, ep.qty ";
  527. $sql .= " , p.label, p.price "; //price price_ttc price_min price_min_ttc
  528. $sql .= " FROM " . MAIN_DB_PREFIX . "eventwizard_eventproduct ep ";
  529. $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product p ON p.rowid = ep.fk_product ";
  530. // $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination ac ON ac.fk_product_parent = ep.fk_product ";
  531. // $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."eventwizard_eventoption eo ON eo.rowid = ep.fk_eventoption ";
  532. // $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."eventwizard_eventdetails ed ON ed.rowid = ep.fk_eventdetails ";
  533. $sql .= " WHERE ep.fk_eventdetails = " . (int) $this->db->escape($id);
  534. // return $sql;
  535. $result = $this->db->query($sql);
  536. if ($result) {
  537. $variants_ids = [];
  538. while ($d = $this->db->fetch_object($result)) {
  539. $variants_ids[] = $d->fk_product;
  540. // if(is_null($d->fk_product_child)){}
  541. $d->variants = [];
  542. // $d->minP = (is_null($d->amount))?(float)$d->price:(float)$d->amount;
  543. $details['tmp']['' . $d->fk_product] = $d;
  544. }
  545. $sql2 = "SELECT p.rowid, p.label, p.price ";
  546. $sql2 .= ", ac.fk_product_parent, ac.fk_product_child, ac.variation_price, ac.variation_price_percentage "; // variation_price variation_price_percentage variation_weight variation_ref_ext entity
  547. $sql2 .= "FROM " . MAIN_DB_PREFIX . "product_attribute_combination ac ";
  548. $sql2 .= " LEFT JOIN " . MAIN_DB_PREFIX . "product p ON ac.fk_product_child = p.rowid ";
  549. $sql2 .= " WHERE ac.fk_product_parent IN (" . implode(",", $variants_ids) . ") ";
  550. $result2 = $this->db->query($sql2);
  551. if ($result2) {
  552. while ($v = $this->db->fetch_object($result2)) {
  553. $d = $details['tmp']['' . $v->fk_product_parent];
  554. $d->variants[] = $this->product2out($v);
  555. if (!is_null($d->amount)) { //... - ??? %?
  556. $d->minP = (float) $d->amount;
  557. } elseif (!isset($d->minP)) {
  558. $d->minP = $v->price;
  559. } elseif ($d->minP > $v->price) {
  560. $d->minP = $v->price;
  561. }
  562. $details['tmp']['' . $v->fk_product_parent] = $d;
  563. }
  564. }
  565. foreach ($details['tmp'] as $k => $v) {
  566. $p = $this->product2out($v);
  567. $p["minP"] = (is_null($v->amount)) ? (!isset($d->minP)) ? (float) $v->price : (float) $v->minP : (float) $v->amount;
  568. $p["variants"] = $v->variants;
  569. $details['product'][] = $p;
  570. if ($p["type"] == 1) {
  571. $details['min'] += $p["minP"];
  572. }
  573. }
  574. unset($details['tmp']);
  575. } else {
  576. throw new RestException(503, 'Error when retrieve Agenda Event list : ' . $this->db->lasterror());
  577. }
  578. // $EventDetails->getLinesArray();
  579. // print_r($EventDetails->lines);
  580. return $details;
  581. //$variations
  582. // $variations =
  583. }
  584. }
  585. protected function product2out($product)
  586. {
  587. return [
  588. "id" => $product->fk_product,
  589. "type" => $product->type, //1,2,3
  590. "fixed_price" => $product->amount,
  591. "max" => $product->qty,
  592. "label" => $product->label,
  593. "price" => $product->price,
  594. ];
  595. }
  596. /**
  597. * Get all products by type
  598. *
  599. * Return an array with details
  600. *
  601. * @return array|mixed data without useless information
  602. *
  603. * @param int $type_id
  604. * @param string $from_date
  605. * @param string $to_date
  606. *
  607. * @url POST getallavailableproducts
  608. *
  609. * @throws RestException 401 Not allowed
  610. * @throws RestException 404 Not found
  611. */
  612. public function getAllAvailableProducts(int $type_id, string $from_date, string $to_date)
  613. {
  614. $date = new DateTime($to_date);
  615. $date->modify('+1 day');
  616. $to_date = $date->format('Y-m-d');
  617. $TMPArray = [];
  618. $productsArray = [];
  619. $sql = "SELECT
  620. pr.rowid
  621. from llx_actioncomm as ac
  622. LEFT JOIN llx_actioncomm_extrafields as ace ON ace.fk_object = ac.id
  623. INNER JOIN llx_eventwizard_eventdetails as ed ON ed.rowid = ac.fk_element
  624. INNER JOIN llx_eventwizard_eventproduct as ep ON ep.fk_eventdetails = ed.rowid
  625. INNER JOIN llx_product as pr ON pr.rowid = ep.fk_product
  626. where ac.datep > '{$from_date} 00:00:00' AND ac.datep2 < '{$to_date} 00:00:00'
  627. AND ac.code = 'AC_EVENT'
  628. AND ed.type = {$type_id}
  629. AND ace.max_num - COALESCE(ace.participants, 0) > 1
  630. GROUP BY pr.rowid";
  631. $result = $this->db->query($sql);
  632. if ($this->db->num_rows($result) > 0) {
  633. while ($row = $this->db->fetch_object($result)) {
  634. $TMPArray[] = $row->rowid;
  635. }
  636. foreach ($TMPArray as $productItem) {
  637. $ApiProductListHelper = new ApiProductListHelper();
  638. $array = $ApiProductListHelper->list('t.ref', 'ASC', '', '', '', '', "(t.rowid:=:{$productItem})");
  639. $productsArray[] = $array[0];
  640. }
  641. }
  642. return $productsArray;
  643. }
  644. function generateRandomString($length = 10)
  645. {
  646. $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  647. $charactersLength = strlen($characters);
  648. $randomString = '';
  649. for ($i = 0; $i < $length; $i++) {
  650. $randomString .= $characters[rand(0, $charactersLength - 1)];
  651. }
  652. return $randomString;
  653. }
  654. /**
  655. * Save event data in Bookinghistory
  656. *
  657. * Return an array with details
  658. *
  659. * @return array|mixed data without useless information
  660. *
  661. * @param string $fk_event //selected evet from llx_event
  662. * @param string $fk_facture //facture rowid from llx_facture
  663. * @param string $fk_eventproduct //eventproduct rowid from llx_eventwizard_eventproduct
  664. * @param string $ref
  665. *
  666. * @url POST saveeventdata
  667. * @access protected
  668. * @throws RestException 401 Not allowed
  669. * @throws RestException 404 Not found
  670. */
  671. public function saveEventData(string $fk_event, string $ref, string $fk_facture = null, string $fk_eventproduct = null)
  672. {
  673. dol_include_once('/custom/booking/class/bookinghistory.class.php');
  674. dol_include_once('/comm/action/class/actioncomm.class.php');
  675. $actionCommObj = new ActionComm($this->db);
  676. $sql = "SELECT fk_element, datep, datep2 FROM " . MAIN_DB_PREFIX . $actionCommObj->table_element . " WHERE id = {$fk_event}";
  677. $result = $this->db->query($sql);
  678. if ($this->db->num_rows($result) > 0) {
  679. $row = $this->db->fetch_object($result);
  680. $BookingHistory = new BookingHistory($this->db);
  681. $BookingHistory->fk_event = (int)$fk_event;
  682. $BookingHistory->fk_facture = (int)$fk_facture;
  683. $BookingHistory->fk_event_detail = $row->fk_element;
  684. $BookingHistory->fk_eventproduct = (int)$fk_eventproduct;
  685. $BookingHistory->date_start = strtotime($row->datep);
  686. $BookingHistory->date_end = strtotime($row->datep2);
  687. $BookingHistory->invoice_number = $ref;
  688. $result = $BookingHistory->create($this->user);
  689. if ($result > 0) {
  690. return $BookingHistory->id;
  691. } else {
  692. throw new RestException(401, 'Unsaved');
  693. }
  694. } else {
  695. throw new RestException(401, 'No Event record');
  696. }
  697. }
  698. public function updateBbticket($fk_booking_history, $invoice)
  699. {
  700. global $user;
  701. $sql = "SELECT rowid FROM llx_bbus_bbticket WHERE fk_facture = {$invoice['id']}";
  702. $data = $this->db->query($sql);
  703. if ($this->db->num_rows($data) > 0) {
  704. while ($row = $this->db->fetch_object($data)) {
  705. $sql = "UPDATE llx_bbus_bbticket
  706. SET booking_history_id = {$fk_booking_history}, invoice_number = '{$invoice['ref']}'
  707. WHERE rowid = {$row->rowid}";
  708. $this->db->query($sql);
  709. }
  710. }
  711. }
  712. public function deletePreorder($preorder)
  713. {
  714. foreach ($preorder as $item) {
  715. $sql = "DELETE FROM llx_booking_preorder WHERE rowid = {$item}";
  716. $this->db->query($sql);
  717. }
  718. }
  719. public function eventErasuer()
  720. {
  721. global $user;
  722. $limitDate = date("Y-m-d H:i:s", dol_now() - 1200);
  723. $sql = "SELECT * FROM llx_booking_preorder WHERE date_creation < '{$limitDate}'";
  724. //print $sql;exit;
  725. $data = $this->db->query($sql);
  726. if ($this->db->num_rows($data) > 0) {
  727. while ($row = $this->db->fetch_object($data)) {
  728. //print_r($row);
  729. $actioncommObj = new ActionComm($this->db);
  730. $resultActionComm = $actioncommObj->fetch($row->fk_event);
  731. $actioncommObj->array_options['options_participants'] = $actioncommObj->array_options['options_participants'] - 1;
  732. $actioncommObj->update($user);
  733. }
  734. //exit;
  735. $sqlDelete = "DELETE FROM llx_booking_preorder WHERE date_creation < '{$limitDate}'";
  736. $dataDelete = $this->db->query($sqlDelete);
  737. }
  738. }
  739. /**
  740. * Increase Participants
  741. *
  742. * Return an array with details
  743. *
  744. * @return array|mixed data without useless information
  745. *
  746. * @param int $event_id //rowid of evet from llx_event
  747. *
  748. * @url POST increaseparticipant
  749. *
  750. * @throws RestException 401 Not allowed
  751. * @throws RestException 404 Not found
  752. */
  753. public function increaseParticipant(int $event_id)
  754. {
  755. dol_include_once('/comm/action/class/actioncomm.class.php');
  756. global $user;
  757. $actionComObj = new ActionComm($this->db);
  758. $actionComObj->fetch($event_id);
  759. $max_num = (int) $actionComObj->array_options['options_max_num'];
  760. $buffer = (int) $actionComObj->array_options['options_buffer'];
  761. $participants = (int) $actionComObj->array_options['options_participants'];
  762. $increasedParticipants = $participants + 1;
  763. if ($increasedParticipants > ($max_num + $buffer)) {
  764. return 'full';
  765. } elseif (($increasedParticipants > $max_num) && ($increasedParticipants <= ($max_num + $buffer))) {
  766. $actionComObj->array_options['options_participants'] = $increasedParticipants;
  767. $actionComObj->update($user);
  768. return 'Buffer';
  769. } else {
  770. $actionComObj->array_options['options_participants'] = $increasedParticipants;
  771. $actionComObj->update($user);
  772. return 'OK';
  773. }
  774. }
  775. /**
  776. * Reduce Participants
  777. *
  778. * Return an array with details
  779. *
  780. * @return array|mixed data without useless information
  781. *
  782. * @param int $event_id //rowid of evet from llx_event
  783. *
  784. * @url POST reduceparticipant
  785. *
  786. *
  787. * @throws RestException 401 Not allowed
  788. * @throws RestException 404 Not found
  789. */
  790. public function reduceParticipant(int $event_id)
  791. {
  792. global $user;
  793. dol_include_once('/comm/action/class/actioncomm.class.php');
  794. $actionComObj = new ActionComm($this->db);
  795. $actionComObj->fetch($event_id);
  796. $participants = (int) $actionComObj->array_options['options_participants'];
  797. $reducedParticipants = $participants - 1;
  798. $actionComObj->array_options['options_participants'] = $reducedParticipants < 0 ? 0 : $reducedParticipants;
  799. $actionComObj->update($user);
  800. return 'OK';
  801. }
  802. /**
  803. * Create invoice
  804. *
  805. * @param array $invoice Invoice data
  806. * @param array $lines Invoice lines
  807. * @param array $payment Invoice payment
  808. * @param string $eventid Event ID
  809. * @param string $cardPaymentLog Card payment log data
  810. *
  811. * @access protected
  812. * @return array|mixed Data without useless information
  813. *
  814. * @url POST /invoice
  815. */
  816. public function invoice(array $invoice, array $lines, array $payment, string $cardPaymentLog = '', string $eventid = '', string $sendId = '')
  817. {
  818. if (empty($sendId)) {
  819. $sendId = substr(md5(rand()), 0, 8);
  820. }
  821. /**
  822. * LOG SECTION
  823. */
  824. ApiBbusLog::appLog("{$sendId} === NEW INVOICE ===");
  825. dol_syslog("{$sendId} === NEW INVOICE ===", LOG_INFO, 0);
  826. ApiBbusLog::appLog("{$sendId} REQUEST: {$sendId}");
  827. dol_syslog("{$sendId} REQUEST: {$sendId}", LOG_INFO, 0);
  828. ApiBbusLog::appLog("{$sendId} User: {$this->user->firstname} {$this->user->lastname} (ID: {$this->user->id})");
  829. dol_syslog("{$sendId} User: {$this->user->firstname} {$this->user->lastname} (ID: {$this->user->id})", LOG_INFO, 0);
  830. ApiBbusLog::appLog("{$sendId} " . json_encode([
  831. 'invoice' => $invoice,
  832. 'lines' => $lines,
  833. 'payment' => $payment,
  834. 'eventid' => $eventid,
  835. 'cardPaymentLog' => $cardPaymentLog
  836. ]));
  837. /**
  838. * CHECK RIGHTS
  839. */
  840. if (!DolibarrApiAccess::$user->rights->facture->creer) {
  841. ApiBbusLog::appLog("{$sendId} Insufficient rights");
  842. throw new RestException(401, 'Insufficient rights');
  843. }
  844. $apiInvoiceHelper = new ApiInvoiceHelper;
  845. /**
  846. * handle invoice basic data
  847. */
  848. $invoiceObj = $apiInvoiceHelper->createInvoice($invoice, $sendId);
  849. /**
  850. * handle invoice line(s)
  851. */
  852. $products = [];
  853. //print $eventid;exit;
  854. foreach ($lines as $line) {
  855. $invoiceObj = $apiInvoiceHelper->addLineToInvoice($invoiceObj, $line, $sendId);
  856. $this->increaseParticipant((int) $eventid);
  857. $product = $apiInvoiceHelper->loadProductToResult($line);
  858. if (!empty($product)) {
  859. $products[] = $product;
  860. }
  861. }
  862. $invoiceObj->fetch_lines();
  863. foreach ($products as &$row) {
  864. foreach ($invoiceObj->lines as $line) {
  865. if ($line->product_ref == $row['ref']) {
  866. //$row['price'] = $line->total_ttc;
  867. $row['price'] = $line->multicurrency_total_ttc;
  868. $row['total_tva'] = $line->total_tva;
  869. //$row['total_tva'] = $line->multicurrency_total_tva;
  870. }
  871. }
  872. }
  873. return [
  874. 'sendId' => $sendId,
  875. 'invoice' => [
  876. 'id' => $invoiceObj->id,
  877. 'ref' => $invoiceObj->ref,
  878. 'total' => $invoiceObj->multicurrency_total_ttc
  879. ],
  880. 'products' => $products,
  881. ];
  882. }
  883. /**
  884. * Get all free spaces on a selected date
  885. *
  886. * Return an array with details
  887. *
  888. * @return array|mixed data without useless information
  889. *
  890. * @param string date_from
  891. * @param string date_to
  892. * @param int product_id
  893. * @param int participant_number
  894. *
  895. * @url POST localavailableplaces
  896. *
  897. * @throws RestException 401 Not allowed
  898. * @throws RestException 404 Not found
  899. */
  900. public function localAvailablePlaces($date_from, $date_to, $product_id, $participant_number)
  901. {
  902. $array = [];
  903. $date = new DateTime($date_to);
  904. $date->modify('+1 day');
  905. $date_to = $date->format('Y-m-d');
  906. $sql = "SELECT
  907. ac.id,
  908. ac.datep,
  909. ace.max_num,
  910. ace.participants,
  911. ace.buffer
  912. FROM llx_actioncomm as ac
  913. LEFT JOIN llx_actioncomm_extrafields as ace ON ace.fk_object = ac.id
  914. INNER JOIN llx_eventwizard_eventdetails as ed ON ac.fk_element = ed.rowid
  915. INNER JOIN llx_eventwizard_eventproduct as ep ON ep.fk_eventdetails = ac.fk_element
  916. WHERE ac.code = 'AC_EVENT'
  917. AND ep.fk_product = {$product_id}
  918. AND ac.datep > '{$date_from} 00:00:00'
  919. AND ac.datep2 < '{$date_to} 00:00:00'
  920. ORDER BY ac.datep ASC";
  921. $result = $this->db->query($sql);
  922. while ($row = $this->db->fetch_object($result)) {
  923. $max_num = $row->max_num;
  924. $buffer = $row->buffer;
  925. $participants = $row->participants;
  926. $date = strtotime($row->datep);
  927. $element['event_id'] = $row->id;
  928. //$element['date'] = date("Y-m-d", $date);
  929. //$element['time'] = date("H:i", $date);
  930. $element['participants'] = is_null($participants) ? 0 : (int) $participants;
  931. $element['max_num'] = $max_num;
  932. $element['buffer'] = $buffer;
  933. if ($max_num > $participants) {
  934. if ($max_num + $buffer > $participants + $participant_number) {
  935. $array[date("Y-m-d", $date)][date("H:i", $date)] = $element;
  936. }
  937. }
  938. }
  939. return $array;
  940. }
  941. /**
  942. * Get all free spaces on a selected date
  943. *
  944. * Return an array with details
  945. *
  946. * @return array|mixed data without useless information
  947. *
  948. * @param string sendId
  949. * @param int fk_event
  950. * @param int reservations
  951. * @param int product_id
  952. *
  953. * @url POST localcreatedpreorderobj
  954. * @access protected
  955. * @throws RestException 401 Not allowed
  956. * @throws RestException 404 Not found
  957. */
  958. public function localcreatedpreorderobj($sendId, $fk_event, $reservations, $product_id)
  959. {
  960. $apiInvoiceHelper = new ApiInvoiceHelper;
  961. $createdPreOrderOBJ = [];
  962. for ($i = 1; $i <= $reservations; $i++) {
  963. dol_include_once('/comm/action/class/actioncomm.class.php');
  964. dol_include_once('/custom/booking/class/preorder.class.php');
  965. $apiInvoiceHelper->increaseParticipant($fk_event);
  966. $lines = $apiInvoiceHelper->getProductLines($product_id);
  967. foreach ($lines as $line) {
  968. $preOrderObj = new PreOrder($this->db);
  969. $preOrderObj->ref = $this->generateRandomString();
  970. $preOrderObj->fk_event = $fk_event;
  971. $preOrderObj->fk_product = $product_id;
  972. $result = $preOrderObj->create($this->user);
  973. if ($result > 0) {
  974. $createdPreOrderOBJ[] = [
  975. 'id' => $preOrderObj->id,
  976. 'ref' => $preOrderObj->ref,
  977. ];
  978. } else {
  979. ApiBbusLog::eventLog(json_encode(['error' => $preOrderObj->errors]));
  980. ApiBbusLog::eventLog("Unsaved event: " . $fk_event);
  981. throw new RestException(401, 'Unsaved event: ' . $fk_event);
  982. }
  983. }
  984. }
  985. return $createdPreOrderOBJ;
  986. }
  987. /**
  988. * Get all free spaces on a selected date
  989. *
  990. * Return an array with details
  991. *
  992. * @return array|mixed data without useless information
  993. *
  994. * @param int fk_event
  995. * @param int reservations
  996. *
  997. * @url POST nolocalemptyspaces
  998. *
  999. * @throws RestException 401 Not allowed
  1000. * @throws RestException 404 Not found
  1001. */
  1002. public function nolocalemptyspaces($fk_event, $reservations)
  1003. {
  1004. $sql = "SELECT ace.max_num, ace.buffer, ace.participants FROM llx_actioncomm as ac
  1005. INNER JOIN llx_actioncomm_extrafields as ace ON ace.fk_object = ac.id
  1006. WHERE ac.id = {$fk_event}";
  1007. $result = $this->db->query($sql);
  1008. if ($this->db->num_rows($result) == 0) {
  1009. return '{"result":1}';
  1010. }
  1011. while ($row = $this->db->fetch_object($result)) {
  1012. if ($row->participants >= $row->max_num) {
  1013. return '{"result":1}';
  1014. }
  1015. if ($row->participants + $reservations > $row->max_num + $row->buffer) {
  1016. return '{"result":1}';
  1017. }
  1018. }
  1019. return '{"result":0}';
  1020. }
  1021. /**
  1022. * Validate and save invoice
  1023. *
  1024. * Return an array with details
  1025. *
  1026. * @return array|mixed data without useless information
  1027. *
  1028. * @param string $sendId sendID
  1029. * @param array $payment Invoice payment
  1030. * @param array $preorder preorder
  1031. * @param array $invoice Invoice
  1032. * @param string $cardPaymentLog Card payment log data
  1033. *
  1034. * @url POST localvalidateandsaveinvoice
  1035. * @access protected
  1036. * @throws RestException 401 Not allowed
  1037. * @throws RestException 404 Not found
  1038. * @throws RestException 506 No available spaces
  1039. *
  1040. */
  1041. public function localValidateAndSaveInvoice($invoice, $preorder, $payment, $cardPaymentLog, $sendId)
  1042. {
  1043. global $user, $db;
  1044. $createdInvoiceData = [];
  1045. $apiInvoiceHelper = new ApiInvoiceHelper;
  1046. $bbusApi = new BBus();
  1047. foreach ($preorder as $order) {
  1048. $sql = "SELECT fk_product, fk_event FROM llx_booking_preorder WHERE rowid = {$order}";
  1049. //print $sql . "\r\n";
  1050. $data = $db->query($sql);
  1051. if ($db->num_rows($data) > 0) {
  1052. while ($row = $db->fetch_object($data)) {
  1053. //print_r($row);
  1054. $lines = $apiInvoiceHelper->getProductLines($row->fk_product);
  1055. $createdInvoiceArray = $bbusApi->invoice($invoice, $lines, $payment, $cardPaymentLog = '', $sendId = '');
  1056. $createdInvoiceData[] = $createdInvoiceArray;
  1057. $bookingHistory = $this->saveEventData((int)$row->fk_event, $createdInvoiceArray['invoice']['id']);
  1058. $this->updateBbticket($bookingHistory, $createdInvoiceArray['invoice']);
  1059. $this->deletePreorder($preorder);
  1060. }
  1061. }
  1062. }
  1063. return $createdInvoiceData;
  1064. }
  1065. /**
  1066. * Get back the product_id and event_id from llx_booking_preorder
  1067. *
  1068. * Return an array with details
  1069. *
  1070. * @return array|mixed data without useless information
  1071. *
  1072. * @param int $rowid preorder->rowid
  1073. *
  1074. * @url POST localpreorderarray
  1075. * @access protected
  1076. * @throws RestException 401 Not allowed
  1077. * @throws RestException 404 Not found
  1078. * @throws RestException 506 No available spaces
  1079. *
  1080. */
  1081. public function localpreorderarray(int $rowid)
  1082. {
  1083. global $user, $db;
  1084. $result = [];
  1085. $sql = "SELECT fk_product, fk_event FROM llx_booking_preorder WHERE rowid = {$rowid}";
  1086. $data = $db->query($sql);
  1087. if ($db->num_rows($data) > 0) {
  1088. while ($row = $db->fetch_object($data)) {
  1089. $result = $row;
  1090. }
  1091. }
  1092. return $result;
  1093. }
  1094. /**
  1095. * Create BBticket record
  1096. *
  1097. * Return an array with details
  1098. *
  1099. * @return array|mixed data without useless information
  1100. *
  1101. * @param string $product_id
  1102. * @param string $datec
  1103. * @param string $facture_id
  1104. *
  1105. * @url POST createbbticket
  1106. * @access protected
  1107. * @throws RestException 401 Not allowed
  1108. * @throws RestException 404 Not found
  1109. * @throws RestException 506 No available spaces
  1110. *
  1111. */
  1112. public function createbbticket(string $product_id, string $datec, string $facture_id)
  1113. {
  1114. global $db;
  1115. $sql = "SELECT validperiod, occasions FROM " . $this->db->prefix() . "product_extrafields WHERE fk_object = " . $product_id;
  1116. $result = $db->query($sql);
  1117. while ($sqlDataResult = $db->fetch_array($result)) {
  1118. $validperiod = $sqlDataResult['validperiod'] ? $sqlDataResult['validperiod'] : 366;
  1119. $occasions = $sqlDataResult['occasions'];
  1120. }
  1121. $curlGroup = 10000;
  1122. $ticket = new BbTicket($db);
  1123. $ticket->fk_facture = null;
  1124. $ticket->bundle_id = $product_id;
  1125. $ticket->usable_occasions = $occasions;
  1126. $ticket->usage = '0';
  1127. $ticket->available_at = $this->getAvailableAtDate($datec, $validperiod);
  1128. $ticket->ticket_id = $product_id;
  1129. $ticket->fk_settlements_group_id = $curlGroup;
  1130. $ticket->invoice_number = $facture_id;
  1131. if ($ticket->create($this->user) == -1) {
  1132. dol_syslog("Nem sikerult a ticketek mentese");
  1133. }
  1134. return true;
  1135. }
  1136. private function getAvailableAtDate($date, $validperiod)
  1137. {
  1138. $available_at = date('Y-m-d H:i:s', strtotime($date . ' +' . $validperiod . ' days'));
  1139. return $available_at;
  1140. }
  1141. #-------------------------------------------------
  1142. # CURL
  1143. #-------------------------------------------------
  1144. /**
  1145. * Update data in BBticket
  1146. *
  1147. * Return an array with details
  1148. *
  1149. * @return array|mixed data without useless information
  1150. *
  1151. * @param string $fk_booking_history //selected evet from llx_event
  1152. * @param array $invoice //facture rowid from llx_facture
  1153. *
  1154. * @url POST curlUpdateBbticket
  1155. * @throws RestException 401 Not allowed
  1156. * @throws RestException 404 Not found
  1157. */
  1158. public function curlUpdateBbticket($fk_booking_history, $invoice)
  1159. {
  1160. global $user;
  1161. $sql = "SELECT rowid FROM llx_bbus_bbticket WHERE invoice_number = '{$invoice['id']}'";
  1162. ApiBbusLog::appLog("curlUpdateBbticket SELECT: {$sql}");
  1163. $data = $this->db->query($sql);
  1164. if ($this->db->num_rows($data) > 0) {
  1165. while ($row = $this->db->fetch_object($data)) {
  1166. $sql = "UPDATE llx_bbus_bbticket
  1167. SET booking_history_id = {$fk_booking_history}, invoice_number = '{$invoice['ref']}'
  1168. WHERE rowid = {$row->rowid}";
  1169. ApiBbusLog::appLog("curlUpdateBbticket UPDATE: {$sql}");
  1170. $this->db->query($sql);
  1171. }
  1172. }
  1173. }
  1174. /**
  1175. * delete preorderrecord
  1176. *
  1177. * Return an array with details
  1178. *
  1179. * @return array|mixed data without useless information
  1180. *
  1181. * @param string $preorder_id //selected evet from llx_event
  1182. *
  1183. * @url POST curlDeletePreorder
  1184. * @throws RestException 401 Not allowed
  1185. * @throws RestException 404 Not found
  1186. */
  1187. public function curlDeletePreorder($rowid)
  1188. {
  1189. $sql = "DELETE FROM llx_booking_preorder WHERE rowid = {$rowid}";
  1190. ApiBbusLog::appLog("{$sql}");
  1191. $this->db->query($sql);
  1192. }
  1193. /**
  1194. * Create BBticket record
  1195. *
  1196. * Return an array with details
  1197. *
  1198. * @return array|mixed data without useless information
  1199. *
  1200. * @param string $product_id
  1201. * @param string $datec
  1202. * @param string $ref
  1203. *
  1204. * @url POST createbbticketmultiprinting
  1205. * @access protected
  1206. * @throws RestException 401 Not allowed
  1207. * @throws RestException 404 Not found
  1208. * @throws RestException 506 No available spaces
  1209. *
  1210. */
  1211. public function createbbticketmultiprinting(string $product_id, string $datec, string $ref)
  1212. {
  1213. global $db;
  1214. $sql = "SELECT validperiod, occasions FROM " . $this->db->prefix() . "product_extrafields WHERE fk_object = " . $product_id;
  1215. $result = $db->query($sql);
  1216. while ($sqlDataResult = $db->fetch_array($result)) {
  1217. $validperiod = $sqlDataResult['validperiod'] ? $sqlDataResult['validperiod'] : 366;
  1218. $occasions = $sqlDataResult['occasions'];
  1219. }
  1220. $curlGroup = 10000;
  1221. $ticket = new BbTicket($db);
  1222. $ticket->fk_facture = null;
  1223. $ticket->bundle_id = $product_id;
  1224. $ticket->usable_occasions = $occasions;
  1225. $ticket->usage = '0';
  1226. $ticket->available_at = $this->getAvailableAtDate($datec, $validperiod);
  1227. $ticket->ticket_id = $product_id;
  1228. $ticket->fk_settlements_group_id = $curlGroup;
  1229. $ticket->invoice_number = $ref;
  1230. if ($ticket->create($this->user) == -1) {
  1231. dol_syslog("Nem sikerult a ticketek mentese");
  1232. }
  1233. $array['id'] = $ticket->id;
  1234. $array['ticket_id'] = $ticket->ticket_id;
  1235. return $array;
  1236. }
  1237. #-------------------------------------------------
  1238. # OLD functions
  1239. #-------------------------------------------------
  1240. /**
  1241. * Validate and save invoice
  1242. * {"facture_id":41968,"cardPaymentLog":"","sendId":"K1pfFPlT","payment":{"datepaye":1716388707,"paymentid":14,"accountid":4,"closepaidinvoices":"yes"}}
  1243. *
  1244. * Return an array with details
  1245. *
  1246. * @return array|mixed data without useless information
  1247. *
  1248. * @param int $facture_id //facture_id
  1249. * @param array $payment Invoice payment
  1250. * @param string $cardPaymentLog Card payment log data
  1251. * @param string $sendId //ID
  1252. *
  1253. * @url POST validateandsaveinvoiceold
  1254. * @access protected
  1255. * @throws RestException 401 Not allowed
  1256. * @throws RestException 404 Not found
  1257. * @throws RestException 506 No available spaces
  1258. *
  1259. */
  1260. public function validateandsaveinvoiceOld(int $facture_id, array $payment, string $cardPaymentLog = '', string $sendId = '')
  1261. {
  1262. global $user;
  1263. ApiBbusLog::eventLog("{$sendId} === VALIDATE INVOICE ===");
  1264. dol_syslog("{$sendId} === VALIDATE INVOICE ===", LOG_INFO, 0);
  1265. ApiBbusLog::eventLog("{$sendId} REQUEST: {$sendId}");
  1266. dol_syslog("{$sendId} REQUEST: {$sendId}", LOG_INFO, 0);
  1267. ApiBbusLog::eventLog("{$sendId} User: {$this->user->firstname} {$this->user->lastname} (ID: {$this->user->id})");
  1268. dol_syslog("{$sendId} User: {$this->user->firstname} {$this->user->lastname} (ID: {$this->user->id})", LOG_INFO, 0);
  1269. ApiBbusLog::eventLog("{$sendId} " . json_encode([
  1270. 'facture_id' => $facture_id,
  1271. 'payement' => $payment,
  1272. 'cardPayementLog' => $cardPaymentLog,
  1273. 'sendId' => $sendId,
  1274. ]));
  1275. $products = [];
  1276. $invoiceObj = new Facture($this->db);
  1277. $apiInvoiceHelper = new ApiInvoiceHelper;
  1278. $invoiceObj->fetch($facture_id);
  1279. foreach ($invoiceObj->lines as $line) {
  1280. $product = $apiInvoiceHelper->loadProductToResult(get_object_vars($line));
  1281. if (!empty($product)) {
  1282. $products[] = $product;
  1283. }
  1284. }
  1285. foreach ($products as &$row) {
  1286. foreach ($invoiceObj->lines as $line) {
  1287. if ($line->product_ref == $row['ref']) {
  1288. //$row['price'] = $line->total_ttc;
  1289. $row['price'] = $line->multicurrency_total_ttc;
  1290. $row['total_tva'] = $line->total_tva;
  1291. //$row['total_tva'] = $line->multicurrency_total_tva;
  1292. }
  1293. }
  1294. }
  1295. $invoiceObj = $apiInvoiceHelper->validateInvoiceFromPROV($invoiceObj, $sendId, $facture_id);
  1296. $apiInvoiceHelper->setPaymentFromPROV($invoiceObj, $payment, $sendId);
  1297. if (!empty($cardPaymentLog)) {
  1298. $invoiceObj = $apiInvoiceHelper->saveCardPaymentLog($invoiceObj, $cardPaymentLog, $sendId);
  1299. }
  1300. ApiBbusLog::eventLog("{$sendId} Invoice created. ID: {$invoiceObj->id} REF: {$invoiceObj->ref} REQ: {$sendId}");
  1301. dol_syslog("{$sendId} Invoice created. ID: {$invoiceObj->id} REF: {$invoiceObj->ref} REQ: {$sendId}", LOG_INFO, 0);
  1302. //$bbApiLock->delete($user);
  1303. ApiBbusLog::eventLog("{$sendId}####################################################################");
  1304. dol_syslog("{$sendId}####################################################################", LOG_INFO, 0);
  1305. return [
  1306. 'sendId' => $sendId,
  1307. 'invoice' => [
  1308. 'id' => $invoiceObj->id,
  1309. 'ref' => $invoiceObj->ref,
  1310. 'total' => $invoiceObj->multicurrency_total_ttc
  1311. ],
  1312. 'products' => $products,
  1313. ];
  1314. }
  1315. /**
  1316. * First step of the eventhandling
  1317. * {"invoice":{"array_options_app_facture":1,"array_options_customer_data_zip":6782,"multicurrency_code":"HUF","fk_multicurrency":3,"mode_reglement_id":14,"cond_reglement_id":14,"fk_account":4},"fk_event":82586,"reservations":1,"sendId":12121212,"product_id":155}
  1318. *
  1319. * Return an array with details
  1320. *
  1321. * @return array|mixed data without useless information
  1322. *
  1323. * @param array $invoice Invoice data
  1324. * @param int $fk_event //selected evet from llx_event
  1325. * @param int $reservations //numbers of reservations
  1326. * @param int $product_id //Product
  1327. * @param string $sendId //ID
  1328. *
  1329. * @url POST firsteventstepold
  1330. * @access protected
  1331. * @throws RestException 401 Not allowed
  1332. * @throws RestException 404 Not found
  1333. * @throws RestException 506 No available spaces
  1334. *
  1335. */
  1336. public function firstEventStepOld(array $invoice, int $fk_event, int $reservations, int $product_id, string $sendId)
  1337. {
  1338. $eventHelper = new EventHelper;
  1339. if ($eventHelper->noEmptySpaces($fk_event, $reservations)) {
  1340. throw new RestException(506, 'No available spaces');
  1341. }
  1342. if (!DolibarrApiAccess::$user->rights->facture->creer) {
  1343. ApiBbusLog::eventLog("{$sendId} Insufficient rights");
  1344. throw new RestException(401, 'Insufficient rights');
  1345. }
  1346. /**
  1347. * LOG SECTION
  1348. */
  1349. ApiBbusLog::eventLog("{$sendId} === NEW INVOICE ===");
  1350. dol_syslog("{$sendId} === NEW INVOICE ===", LOG_INFO, 0);
  1351. ApiBbusLog::eventLog("{$sendId} REQUEST: {$sendId}");
  1352. dol_syslog("{$sendId} REQUEST: {$sendId}", LOG_INFO, 0);
  1353. ApiBbusLog::eventLog("{$sendId} User: {$this->user->firstname} {$this->user->lastname} (ID: {$this->user->id})");
  1354. dol_syslog("{$sendId} User: {$this->user->firstname} {$this->user->lastname} (ID: {$this->user->id})", LOG_INFO, 0);
  1355. ApiBbusLog::eventLog("{$sendId} " . json_encode([
  1356. 'invoice' => $invoice,
  1357. 'fk_event' => $fk_event,
  1358. 'reservations' => $reservations,
  1359. 'product_id' => $product_id,
  1360. 'sendId' => $sendId,
  1361. ]));
  1362. $apiInvoiceHelper = new ApiInvoiceHelper;
  1363. $createdInvoicePROVs = [];
  1364. for ($i = 1; $i <= $reservations; $i++) {
  1365. dol_include_once('/comm/action/class/actioncomm.class.php');
  1366. $apiInvoiceHelper->increaseParticipant($fk_event);
  1367. $invoiceObj = $apiInvoiceHelper->createInvoicePROV($invoice, $sendId);
  1368. $createdInvoicePROVs[] = [
  1369. 'id' => $invoiceObj->id,
  1370. 'ref' => $invoiceObj->ref,
  1371. ];
  1372. ApiBbusLog::eventLog("{$sendId} - Invoice PROV created - " . $invoiceObj->id . ' - ' . $invoiceObj->ref);
  1373. $lines = $apiInvoiceHelper->getProductLines($product_id);
  1374. foreach ($lines as $line) {
  1375. $invoiceLineObj = $apiInvoiceHelper->addLineToInvoice($invoiceObj, $line, $sendId);
  1376. $this->saveEventData($fk_event, $invoiceObj->id, $fk_eventproduct = 1);
  1377. }
  1378. $invoiceLineObj->fetch_lines();
  1379. }
  1380. print_r($createdInvoicePROVs);
  1381. exit;
  1382. return $createdInvoicePROVs;
  1383. }
  1384. }