api_booking.class_old.php 48 KB

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