dolibarr 25.0.0-alpha
cashcontrol_card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2013 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@capnetworks.com>
5 * Copyright (C) 2013 Charles-Fr BENKE <charles.fr@benke.fr>
6 * Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
7 * Copyright (C) 2016 Marcos García <marcosgdf@gmail.com>
8 * Copyright (C) 2018 Andreu Bisquerra <jove@bisquerra.com>
9 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
10 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 */
25
32// Load Dolibarr environment
33require '../../main.inc.php';
42require_once DOL_DOCUMENT_ROOT.'/blockedlog/lib/blockedlog.lib.php';
43require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
44require_once DOL_DOCUMENT_ROOT.'/compta/cashcontrol/class/cashcontrol.class.php';
45require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
46require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
47require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
48
49$langs->loadLangs(array("install", "cashdesk", "admin", "banks", "blockedlog"));
50
51$action = GETPOST('action', 'aZ09');
52$backtopage = GETPOST('backtopage', 'aZ09');
53
54$id = GETPOSTINT('id');
55$ref = GETPOST('ref', 'alpha');
56$label = GETPOST("label");
57
58$now = dol_now();
59
60$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
61$sortfield = GETPOST('sortfield', 'aZ09comma');
62$sortorder = GETPOST('sortorder', 'aZ09comma');
63$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
64if (empty($page) || $page == -1) {
65 $page = 0;
66} // If $page is not defined, or '' or -1
67$offset = $limit * $page;
68$pageprev = $page - 1;
69$pagenext = $page + 1;
70if (!$sortfield) {
71 $sortfield = 'rowid';
72}
73if (!$sortorder) {
74 $sortorder = 'ASC';
75}
76$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'thirdpartylist';
77
78if ($contextpage == 'takepos') {
79 $optioncss = 'print';
80}
81
82$arrayofpaymentmode = array('cash' => 'Cash', 'cheque' => 'Cheque', 'card' => 'CreditCard');
83
84$arrayofposavailable = array();
85if (isModEnabled('cashdesk')) {
86 $arrayofposavailable['cashdesk'] = $langs->trans('CashDesk').' (cashdesk)';
87}
88if (isModEnabled('takepos')) {
89 $arrayofposavailable['takepos'] = $langs->trans('TakePOS').' (takepos)';
90}
91// TODO Add hook here to allow other POS to add themself
92
93$object = new CashControl($db);
94$extrafields = new ExtraFields($db);
95
96// fetch optionals attributes and labels
97$extrafields->fetch_name_optionals_label($object->table_element);
98
99// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
100$hookmanager->initHooks(array('cashcontrolcard', 'globalcard'));
101
102// Load object
103include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'.
104
105// Security check
106if ($user->socid > 0) { // Protection if external user
107 //$socid = $user->socid;
109}
110if (!$user->hasRight("cashdesk", "run") && !$user->hasRight("takepos", "run")) {
112}
113
114$permissiontoadd = $user->hasRight("takepos", "run");
115$permissiontodelete = $user->hasRight("takepos", "run") || ($permissiontoadd && $object->status == 0);
116$permissiontoeditextra = $permissiontoadd;
117if (GETPOST('attribute', 'aZ09') && isset($extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')])) {
118 // For action 'update_extras', is there a specific permission set for the attribute to update
119 $permissiontoeditextra = dol_eval((string) $extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')]);
120}
121$permissiontoreopen = $user->hasRight("takepos", "run");
122
123
124$sqlfilteronopdate = '';
125
126// Must be after the fetch
127$datestart = null;
128$dateend = null;
129$syear = (GETPOSTISSET('closeyear') ? GETPOSTINT('closeyear') : dol_print_date($now, "%Y", 'tzuserrel'));
130$smonth = (GETPOSTISSET('closemonth') ? GETPOSTINT('closemonth') : dol_print_date($now, "%m", 'tzuserrel'));
131$sday = (GETPOSTISSET('closeday') ? GETPOSTINT('closeday') : dol_print_date($now, "%d", 'tzuserrel'));
132// TODO Add a global option to allow to enter the end hours when doing a cash control (currently only end of hours 23:59:59 for local hour so :xx::xx for UTC is supported)
133$shour = 0;
134$smin = 0;
135$ssec = 0;
136
137if ($object->id > 0) {
138 // When object is known, we must define first the end date (stored in database with different components) and deduct the start date
139 if (empty($object->day_close) && !empty($object->month_close)) { // Full day
140 $dateend = dol_mktime((int) $object->hour_close, (int) $object->min_close, (int) $object->sec_close, $object->month_close, 1, $object->year_close, 'gmt');
141 $dateend = dol_time_plus_duree($dateend, +1, 'm', 0);
142 $dateend = dol_time_plus_duree($dateend, -1, 'd', 0);
143
144 $datestart = dol_time_plus_duree($dateend, -1, 'm', 0);
145 } elseif (empty($object->day_close) && empty($object->month_close)) { // Full year
146 $dateend = dol_mktime((int) $object->hour_close, (int) $object->min_close, (int) $object->sec_close, 12, 31, $object->year_close, 'gmt');
147 $datestart = dol_time_plus_duree($dateend, -1, 'y', 0);
148 } else {
149 $dateend = dol_mktime((int) $object->hour_close, (int) $object->min_close, (int) $object->sec_close, $object->month_close, $object->day_close, $object->year_close, 'gmt');
150 $datestart = dol_time_plus_duree($dateend, -1, 'd', 0);
151 }
152 $datestart += 1; // Add 1 second
153} else {
154 if ($syear && !$smonth) {
155 $datestart = dol_get_first_day($syear, 1, 'tzuserrel');
156 $dateend = dol_get_last_day($syear, 12, 'tzuserrel');
157 } elseif ($syear && $smonth && !$sday) {
158 $datestart = dol_get_first_day($syear, $smonth, 'tzuserrel');
159 $dateend = dol_get_last_day($syear, $smonth, 'tzuserrel');
160 } elseif ($syear && $smonth && $sday) {
161 $datestart = dol_mktime($shour, $smin, $ssec, $smonth, $sday, $syear, 'tzuserrel');
162 $dateend = dol_mktime(23, 59, 59, $smonth, $sday, $syear, 'tzuserrel');
163 } else {
164 setEventMessages($langs->trans('YearNotDefined'), null, 'errors');
165 }
166}
167$sqlfilteronopdate .= " AND dateo < '".$db->idate((int) $datestart)."'";
168//var_dump(dol_print_date($datestart, 'dayhour', 'gmt'), dol_print_date($dateend, 'dayhour', 'gmt'));
169
170
171// Define dates and terminal
172$posmodule = '';
173$terminalid = '';
174$terminaltouse = '';
175if ($action == "create" || $action == "start" || $action == 'valid' || $action == 'close') {
176 if ($action == 'valid' || $action == 'close') {
177 $posmodule = $object->posmodule;
178 $terminalid = $object->posnumber;
179 $terminaltouse = $terminalid;
180
181 $syear = $object->year_close;
182 $smonth = $object->month_close;
183 $sday = $object->day_close;
184 } elseif (GETPOST('posnumber', 'alpha') != '' && GETPOST('posnumber', 'alpha') != '-1') {
185 $posmodule = GETPOST('posmodule', 'alpha');
186 $terminalid = GETPOST('posnumber', 'alpha');
187 $terminaltouse = $terminalid;
188
189 if ($terminaltouse == '1' && $posmodule == 'cashdesk') { // for compatibility with an old module
190 $terminaltouse = '';
191 }
192 }
193}
194
195
196/*
197 * Actions
198 */
199
200$error = 0;
201
202if (empty($backtopage)) {
203 $backtopage = DOL_URL_ROOT.'/compta/cashcontrol/cashcontrol_card.php?id='.(!empty($id) && $id > 0 ? $id : '__ID__');
204}
205$backurlforlist = DOL_URL_ROOT.'/compta/cashcontrol/cashcontrol_list.php';
206$triggermodname = 'CACHCONTROL_MODIFY'; // Name of trigger action code to execute when we modify record
207
208if (!getDolGlobalString('CASHDESK_ID_BANKACCOUNT_CASH') && !getDolGlobalString('CASHDESK_ID_BANKACCOUNT_CASH1')) {
209 setEventMessages($langs->trans("CashDesk")." - ".$langs->trans("NotConfigured"), null, 'errors');
210}
211
212
213if (GETPOST('cancel', 'alpha')) {
214 if ($action == 'valid') { // Test on permission not required here
215 $action = 'view';
216 } else {
217 $action = 'create';
218 }
219}
220
221if ($action == "reopen" && $permissiontoreopen) {
222 $result = $object->setStatut($object::STATUS_DRAFT, null, '', 'CASHFENCE_MODIFY');
223 if ($result < 0) {
224 setEventMessages($object->error, $object->errors, 'errors');
225 }
226
227 $action = 'view';
228}
229
230if ($action == "start" && $permissiontoadd) {
231 if (!GETPOST('posmodule', 'alpha') || GETPOST('posmodule', 'alpha') == '-1') {
232 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Module")), null, 'errors');
233 $action = 'create';
234 $error++;
235 }
236 if (GETPOST('posnumber', 'alpha') == '') {
237 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CashDesk")), null, 'errors');
238 $action = 'create';
239 $error++;
240 }
241 if (!GETPOST('closeyear', 'alpha') || GETPOST('closeyear', 'alpha') == '-1') {
242 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Year")), null, 'errors');
243 $action = 'create';
244 $error++;
245 }
246} elseif ($action == "add" && $permissiontoadd) {
247 if (GETPOST('opening', 'alpha') == '') {
248 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("InitialBankBalance")), null, 'errors');
249 $action = 'start';
250 $error++;
251 }
252 foreach ($arrayofpaymentmode as $key => $val) {
253 $object->$key = (float) price2num(GETPOST($key.'_amount', 'alpha'));
254 }
255
256 if (!$error) {
257 if (GETPOSTINT('closeday')) {
258 $dateclosegmt = dol_mktime(GETPOSTISSET('closehour') ? GETPOSTINT('closehour') : 23, GETPOSTISSET('closemin') ? GETPOSTINT('closemin') : 59, GETPOSTISSET('closesec') ? GETPOSTINT('closesec') : 59, GETPOSTINT('closemonth') ? GETPOSTINT('closemonth') : 12, GETPOSTINT('closeday'), GETPOSTINT('closeyear'), 'tzuserrel');
259 } else {
260 $dateclosegmt = dol_mktime(GETPOSTISSET('closehour') ? GETPOSTINT('closehour') : 23, GETPOSTISSET('closemin') ? GETPOSTINT('closemin') : 59, GETPOSTISSET('closesec') ? GETPOSTINT('closesec') : 59, GETPOSTINT('closemonth') ? GETPOSTINT('closemonth') : 12, 15, GETPOSTINT('closeyear'), 'tzuserrel');
261 }
262 dol_syslog('The closing date will be '.dol_print_date($dateclosegmt, 'standard', 'gmt').' UTC');
263
264 $tmparray = dol_getdate($dateclosegmt, false, 'gmt');
265
266 $object->day_close = GETPOSTINT('closeday') ? $tmparray['mday'] : null;
267 $object->month_close = GETPOSTINT('closemonth') ? $tmparray['mon'] : null;
268 $object->year_close = $tmparray['year'];
269
270 $object->hour_close = $tmparray['hours'];
271 $object->min_close = $tmparray['minutes'];
272 $object->sec_close = $tmparray['seconds'];
273
274 $object->opening = (float) price2num(GETPOST('opening', 'alpha'));
275 $object->posmodule = GETPOST('posmodule', 'alpha');
276 $object->posnumber = GETPOST('posnumber', 'alpha');
277
278 $db->begin();
279
280 $id = $object->create($user);
281
282 if ($id > 0) {
283 $db->commit();
284 $action = "view";
285 } else {
286 $db->rollback();
287 $action = "view";
288 }
289 }
290 if ($contextpage == 'takepos') {
291 print "
292 <script>
293 parent.location.href='../../takepos/index.php?place='+parent.place;
294 </script>";
295 exit;
296 }
297}
298
299if ($action == "valid" && $permissiontoadd) { // validate = close
300 $object->fetch($id);
301
302 $db->begin();
303
304 // Save the calculated amount
305 // It will also be saved automatically into llx_blockedlog by the trigger in valid().
306 $object->cash = (float) price2num(GETPOST('cash_calculated', 'alpha'));
307 $object->card = (float) price2num(GETPOST('card_calculated', 'alpha'));
308 $object->cheque = (float) price2num(GETPOST('cheque_calculated', 'alpha'));
309
310 // Save the real amount in llx_pos_cash_fence.
311 $object->cash_declared = (float) price2num(GETPOST('cash_amount', 'alpha'));
312 $object->card_declared = (float) price2num(GETPOST('card_amount', 'alpha'));
313 $object->cheque_declared = (float) price2num(GETPOST('cheque_amount', 'alpha'));
314
315 // Add also perpetual amount into cash_lifetime, card_lifetime, cheque_lifetime
316 $cash_lifetime = $card_lifetime = $cheque_lifetime = 0;
317
318 //$dates = $datestart;
319 $datee = $dateend;
320 $datefilter = 'p.datep';
321 $modulesourcefilter = 'f.module_source';
322 $amountfield = 'pf.amount';
323 $possource = 'f.pos_source';
324 $fieldentity = 'p.entity';
325 $joinleft = 'LEFT ';
326 if (isALNERunningVersion() && $mysoc->country_code == 'FR') {
327 $datefilter = 'bl.date_creation'; // By using this as a filter, it is like the LEFT JOIN is an INNER JOIN
328 $modulesourcefilter = 'bl.module_source';
329 $amountfield = 'bl.amounts';
330 $possource = 'bl.pos_source';
331 $fieldentity = 'bl.entity';
332 $joinleft = '';
333 }
334
335 $lifetimeamount = array();
336 $lifetimenb = array();
337
338 // Calculate $theoricalamountforterminal at end of period
339 // Sum of payment + Initial amount in bank
340 foreach ($arrayofpaymentmode as $key => $val) {
341 // NOTE: Must be same request than into report.php, except it does an aggregate and do the request 3 times, once per payment type.
342
343 /*$sql = "SELECT p.rowid, p.ref as pref, p.datep as datep, cp.code,";
344 $sql .= " f.rowid as facid, f.ref, f.datef as datef, pf.amount as amount,";
345 $sql .= " b.fk_account as bankid,";
346 $sql .= " bl.signature"; */
347 $sql = "SELECT SUM(".$db->sanitize($amountfield).") as total, COUNT(*) as nb";
348 $sql .= " FROM ".MAIN_DB_PREFIX."paiement_facture as pf, ".MAIN_DB_PREFIX."facture as f,";
349 $sql .= " ".MAIN_DB_PREFIX."paiement as p";
350 $sql .= " ".$db->sanitize($joinleft)." JOIN ".MAIN_DB_PREFIX."blockedlog as bl ON bl.action = 'PAYMENT_CUSTOMER_CREATE'";
351 $sql .= " AND bl.element = 'payment' AND bl.fk_object = p.rowid AND bl.entity = ".((int) $conf->entity).",";
352 $sql .= " ".MAIN_DB_PREFIX."c_paiement as cp";
353 $sql .= " WHERE pf.fk_facture = f.rowid AND p.rowid = pf.fk_paiement AND cp.id = p.fk_paiement";
354 $sql .= " AND ".$db->sanitize($modulesourcefilter)." = '".$db->escape($posmodule)."'";
355 $sql .= " AND ".$db->sanitize($possource)." = '".$db->escape($terminalid)."'";
356 $sql .= " AND ".$db->sanitize($fieldentity)." = ".((int) $conf->entity); // Never share entities for features related to accountancy
357 $sql .= " AND ".$db->sanitize($datefilter)." <= '".$db->idate((int) $datee)."'";
358 if ($key == 'cash') {
359 $sql .= " AND cp.code = 'LIQ'";
360 } elseif ($key == 'cheque') {
361 $sql .= " AND cp.code = 'CHQ'";
362 } elseif ($key == 'card') {
363 $sql .= " AND cp.code = 'CB'";
364 } else {
365 dol_print_error(null, 'Value for key = '.$key.' not supported');
366 exit;
367 }
368 //print $sql."<br>\n";
369
370 $resql = $db->query($sql);
371 if ($resql) {
372 $lifetimeamount[$terminalid][$key] = 0;
373 $lifetimenb[$terminalid][$key] = 0;
374
375 $obj = $db->fetch_object($resql);
376 if ($obj) {
377 $lifetimeamount[$terminalid][$key] = price2num($lifetimeamount[$terminalid][$key] + $obj->total);
378 $lifetimenb[$terminalid][$key] = $obj->nb;
379 }
380 } else {
381 dol_print_error($db);
382 }
383 }
384
385 $cash_lifetime = $lifetimeamount[$terminalid]['cash'];
386 $card_lifetime = $lifetimeamount[$terminalid]['card'];
387 $cheque_lifetime = $lifetimeamount[$terminalid]['cheque'];
388
389 $object->cash_lifetime = $cash_lifetime;
390 $object->card_lifetime = $card_lifetime;
391 $object->cheque_lifetime = $cheque_lifetime;
392
393
394 // Get the date of first record for the lifetime calculation
395 $sql = "SELECT action, module_source, object_format, date_creation";
396 $sql .= " FROM ".MAIN_DB_PREFIX."blockedlog";
397 $sql .= " WHERE entity = ".((int) $conf->entity);
398 $sql .= " AND action IN ('PAYMENT_CUSTOMER_CREATE')"; // Only this event
399 $sql .= " AND module_source = '".$db->escape($posmodule)."'";
400 //$sql .= " AND pos_source = '".$db->escape($terminalid)."'";
401 $sql .= $db->order("date_creation", "ASC");
402 $sql .= $db->plimit(1);
403
404 $firstrecorddate = 0;
405 $resql = $db->query($sql);
406 if ($resql) {
407 $obj = $db->fetch_object($resql);
408 if ($obj) {
409 $firstrecorddate = $db->jdate($obj->date_creation);
410 }
411 }
412 if ($firstrecorddate) {
413 $object->lifetime_start = $firstrecorddate;
414 }
415
416 $result = $object->update($user);
417
418 $result2 = $object->close($user); // This also save data into the Unalterable Log table by the trigger CASHCONTROL_CLOSE.
419
420
421 // TODO
422 // Add an entry into bank to fix difference between amount and declared and if user ask it with a checkbox ?
423
424
425 if ($result <= 0 || $result2 <= 0) {
426 setEventMessages($object->error, $object->errors, 'errors');
427 $db->rollback();
428 } else {
429 setEventMessages($langs->trans("CashFenceDone"), null);
430 $db->commit();
431 }
432
433 if ($contextpage == 'takepos') {
434 print "
435 <script>
436 location.href='cashcontrol_card.php?id=".$id."&contextpage=takepos';
437 </script>";
438 exit;
439 }
440 $action = "view";
441}
442
443// Action to delete
444if ($action == 'confirm_delete' && !empty($permissiontodelete)) {
445 $object->fetch($id);
446
447 if (!($object->id > 0)) {
448 dol_print_error(null, 'Error, object must be fetched before being deleted');
449 exit;
450 }
451
452 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
453 $result = $object->delete($user);
454 if ($result > 0) {
455 // Delete OK
456 setEventMessages("RecordDeleted", null, 'mesgs');
457 header("Location: ".$backurlforlist);
458 exit;
459 } else {
460 if (!empty($object->errors)) {
461 setEventMessages(null, $object->errors, 'errors');
462 } else {
463 setEventMessages($object->error, null, 'errors');
464 }
465 }
466}
467
468if ($action == 'update_extras' && $permissiontoeditextra) {
469 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
470
471 $attribute_name = GETPOST('attribute', 'aZ09');
472
473 // Fill array 'array_options' with data from add form
474 $ret = $extrafields->setOptionalsFromPost(null, $object, $attribute_name);
475 if ($ret < 0) {
476 $error++;
477 }
478
479 if (!$error) {
480 // Actions on extra fields
481 $result = $object->updateExtraField($attribute_name, 'CASHCONTROL_MODIFY');
482 if ($result < 0) {
483 setEventMessages($object->error, $object->errors, 'errors');
484 $error++;
485 }
486 }
487
488 if ($error) {
489 $action = 'edit_extras';
490 }
491}
492
493
494/*
495 * View
496 */
497
498$form = new Form($db);
499
500$initialbalanceforterminal = array();
501$theoricalamountforterminal = array();
502$theoricalnbofinvoiceforterminal = array();
503
504
505llxHeader('', $langs->trans("CashControl"));
506
507
508// Calculate initial amount estimation and final amount
509if ($action == "create" || $action == "start" || $action == 'close') {
510 if ($action == 'close') {
511 $posmodule = $object->posmodule;
512 $terminalid = $object->posnumber;
513 $terminaltouse = $terminalid;
514
515 $syear = $object->year_close;
516 $smonth = $object->month_close;
517 $sday = $object->day_close;
518 } elseif (GETPOST('posnumber', 'alpha') != '' && GETPOST('posnumber', 'alpha') != '-1') {
519 $posmodule = GETPOST('posmodule', 'alpha');
520 $terminalid = GETPOST('posnumber', 'alpha');
521 $terminaltouse = $terminalid;
522
523 if ($terminaltouse == '1' && $posmodule == 'cashdesk') {
524 $terminaltouse = '';
525 }
526
527 if ($posmodule == 'cashdesk' && $terminaltouse != '' && $terminaltouse != '1') {
528 $terminaltouse = '';
529 setEventMessages($langs->trans("OnlyTerminal1IsAvailableForCashDeskModule"), null, 'errors');
530 $error++;
531 }
532 }
533
534 if (isset($terminalid) && $terminalid != '' && isset($posmodule)) {
535 // Calculate $initialbalanceforterminal for terminal 0
536 foreach ($arrayofpaymentmode as $key => $val) {
537 if ($key != 'cash') {
538 $initialbalanceforterminal[$terminalid][$key] = 0;
539 continue;
540 }
541
542 // Get the bank account dedicated to this point of sale module/terminal
543 $vartouse = 'CASHDESK_ID_BANKACCOUNT_CASH'.$terminaltouse;
544 $bankid = getDolGlobalInt($vartouse);
545
546 // Get the amount in bank before the period date to pre-fill the suggested "initial amount".
547 // The user is still free to prefill with the correct value. This is just to save time to user.
548 if ($bankid > 0) {
549 $sql = "SELECT SUM(amount) as total FROM ".MAIN_DB_PREFIX."bank";
550 $sql .= " WHERE fk_account = ".((int) $bankid);
551 $sql .= $sqlfilteronopdate;
552
553 $resql = $db->query($sql);
554 if ($resql) {
555 $obj = $db->fetch_object($resql);
556 if ($obj) {
557 $initialbalanceforterminal[$terminalid][$key] = $obj->total;
558 }
559 } else {
560 dol_print_error($db);
561 }
562 } else {
563 setEventMessages($langs->trans("SetupOfTerminalNotComplete", $terminaltouse), null, 'errors');
564 $error++;
565 }
566 }
567
568 $dates = $datestart;
569 $datee = $dateend;
570 $datefilter = 'p.datep';
571 $modulesourcefilter = 'f.module_source';
572 $amountfield = 'pf.amount';
573 $joinleft = 'LEFT ';
574 if (isALNERunningVersion() && $mysoc->country_code == 'FR') {
575 $datefilter = 'bl.date_creation'; // By using this as a filter, it is like the LEFT JOIN is an INNER JOIN
576 $modulesourcefilter = 'bl.module_source';
577 $amountfield = 'bl.amounts';
578 $joinleft = '';
579 }
580
581 // Calculate $theoricalamountforterminal at end of period
582 // Sum of payment + Initial amount in bank
583 foreach ($arrayofpaymentmode as $key => $val) {
584 // NOTE: Must be same request than into report.php, except it does an aggregate and do the request 3 times, once per payment type.
585
586 // TODO
587 /*$sql = "SELECT p.rowid, p.datep as datep, cp.code,";
588 $sql .= " f.rowid as facid, f.ref, f.datef as datef, pf.amount as amount,";
589 $sql .= " b.fk_account as bankid,";
590 $sql .= " bl.signature"; */
591 $sql = "SELECT SUM(".$db->sanitize($amountfield).") as total, COUNT(*) as nb";
592 $sql .= " FROM ".MAIN_DB_PREFIX."paiement_facture as pf, ".MAIN_DB_PREFIX."facture as f,";
593 $sql .= " ".MAIN_DB_PREFIX."paiement as p";
594 //$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."blockedlog as bl ON bl.ref_object = p.ref AND bl.entity = ".((int) $conf->entity).",";
595 $sql .= " ".$db->sanitize($joinleft)." JOIN ".MAIN_DB_PREFIX."blockedlog as bl ON bl.action = 'PAYMENT_CUSTOMER_CREATE'";
596 $sql .= " AND bl.element = 'payment' AND bl.fk_object = p.rowid AND bl.entity = ".((int) $conf->entity).",";
597 //$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."bank as b ON p.fk_bank = b.rowid,";
598 $sql .= " ".MAIN_DB_PREFIX."c_paiement as cp";
599 $sql .= " WHERE pf.fk_facture = f.rowid AND p.rowid = pf.fk_paiement AND cp.id = p.fk_paiement";
600 $sql .= " AND ".$db->sanitize($modulesourcefilter)." = '".$db->escape($posmodule)."'";
601 $sql .= " AND f.pos_source = '".$db->escape($terminalid)."'";
602 $sql .= " AND p.entity = ".((int) $conf->entity); // Never share entities for features related to accountancy
603 $sql .= " AND ".$db->sanitize($datefilter)." BETWEEN '".$db->idate((int) $dates)."' AND '".$db->idate((int) $datee)."'";
604 if ($key == 'cash') {
605 $sql .= " AND cp.code = 'LIQ'";
606 } elseif ($key == 'cheque') {
607 $sql .= " AND cp.code = 'CHQ'";
608 } elseif ($key == 'card') {
609 $sql .= " AND cp.code = 'CB'";
610 } else {
611 dol_print_error(null, 'Value for key = '.$key.' not supported');
612 exit;
613 }
614
615 $resql = $db->query($sql);
616 if ($resql) {
617 $obj = $db->fetch_object($resql);
618 if ($obj) {
619 // $theoricalamountforterminal and $theoricalnbofinvoiceforterminal will be used to get the amount for period (cash_calculated, cheque_calculated and card_calculated)
620 $theoricalamountforterminal[$terminalid][$key] = $obj->total;
621 $theoricalnbofinvoiceforterminal[$terminalid][$key] = $obj->nb;
622 }
623 } else {
624 dol_print_error($db);
625 }
626 }
627 }
628}
629
630if ($action == "create" || $action == "start") {
631 print load_fiche_titre($langs->trans("CashControl")." - ".$langs->trans("New"), '', 'cash-register');
632
633 if ($action == 'start') {
634 if (empty(GETPOSTINT('closeday'))) {
635 $endperiod = dol_get_last_day(GETPOSTINT('closeyear'), GETPOSTINT('closemonth') ? GETPOSTINT('closemonth') : 12, 'gmt');
636 if ($endperiod >= dol_now()) {
637 setEventMessages($langs->trans("CashControlEndDateMustBeBeforeNow"), null, 'errors');
638 $action = 'create';
639 }
640 } else {
641 $endperiod = dol_get_first_hour(GETPOSTDATE('close', 'getpostend'));
642 if ($endperiod >= dol_now() && $mysoc->country_code == 'FR') { // For other countries we may need to make 2 cash control in the same day (one at opening and one at closing)
643 setEventMessages($langs->trans("CashControlEndDayMustNotBeInPast"), null, 'errors');
644 $action = 'create';
645 }
646 }
647 }
648
649 print '<form method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
650 print '<input type="hidden" name="token" value="'.newToken().'">';
651 if ($contextpage == 'takepos') {
652 print '<input type="hidden" name="contextpage" value="takepos">';
653 }
654 if ($action == 'start' && GETPOST('posnumber') != '' && GETPOSTINT('posnumber') != 0 && GETPOSTINT('posnumber') != -1) {
655 print '<input type="hidden" name="action" value="add">';
656 } elseif ($action == 'close') {
657 print '<input type="hidden" name="action" value="valid">';
658 print '<input type="hidden" name="id" value="'.$id.'">';
659 } else {
660 print '<input type="hidden" name="action" value="start">';
661 }
662
663 print '<!-- Table to start cash control -->'."\n";
664 print '<div class="div-table-responsive-no-min">'."\n";
665 print '<table class="noborder centpercent">'."\n";
666 print '<tr class="liste_titre">';
667 print '<td>'.$langs->trans("Module").'</td>';
668 print '<td>'.$langs->trans("Terminal").'</td>';
669 print '<td>'.$langs->trans("Year").'</td>';
670 print '<td>'.$langs->trans("Month").'</td>';
671 print '<td>'.$langs->trans("Day").'</td>';
672 print '<td></td>';
673 print "</tr>\n";
674
675 $disabled = 0;
676 $prefix = 'close';
677
678 print '<tr class="oddeven nohover">';
679 print '<td>'.$form->selectarray('posmodule', $arrayofposavailable, GETPOST('posmodule', 'alpha'), (count($arrayofposavailable) > 1 ? 1 : 0)).'</td>';
680 print '<td>';
681
682 $arrayofpos = array();
683 $numterminals = max(1, getDolGlobalString('TAKEPOS_NUM_TERMINALS'));
684 for ($i = 1; $i <= $numterminals; $i++) {
685 $nameofterminal = getDolGlobalString("TAKEPOS_TERMINAL_NAME_".$i);
686 $arrayofpos[$i] = array('id' => $i, 'label' => (($nameofterminal != "TAKEPOS_TERMINAL_NAME_".$i) ? '#'.$i.' '.$nameofterminal : $i), 'data-html' => (($nameofterminal != "TAKEPOS_TERMINAL_NAME_".$i) ? '#'.$i.' - '.$nameofterminal : $i));
687 }
688 $selectedposnumber = 0;
689 $showempty = 1;
690 if (getDolGlobalString('TAKEPOS_NUM_TERMINALS') == '1') {
691 $selectedposnumber = 1;
692 $showempty = 0;
693 }
694 print $form->selectarray('posnumber', $arrayofpos, GETPOSTISSET('posnumber') ? GETPOSTINT('posnumber') : $selectedposnumber, $showempty);
695 //print '<input name="posnumber" type="text" class="maxwidth50" value="'.(GETPOSTISSET('posnumber')?GETPOST('posnumber', 'alpha'):'0').'">';
696 print '</td>';
697
698 // Year
699 print '<td>';
700 $retstring = '<select'.($disabled ? ' disabled' : '').' class="flat valignmiddle maxwidth75imp" id="'.$prefix.'year" name="'.$prefix.'year">';
701 for ($year = $syear - 10; $year < $syear + 10; $year++) {
702 $retstring .= '<option value="'.$year.'"'.($year == $syear ? ' selected' : '').'>'.$year.'</option>';
703 }
704 $retstring .= "</select>\n";
705 print $retstring;
706 print '</td>';
707
708 // Month
709 print '<td>';
710 $retstring = '<select'.($disabled ? ' disabled' : '').' class="flat valignmiddle maxwidth75imp" id="'.$prefix.'month" name="'.$prefix.'month">';
711 $retstring .= '<option value="0"></option>';
712 for ($month = 1; $month <= 12; $month++) {
713 $retstring .= '<option value="'.$month.'"'.($month == $smonth ? ' selected' : '').'>';
714 $retstring .= dol_print_date(mktime(12, 0, 0, $month, 1, 2000), "%b");
715 $retstring .= "</option>";
716 }
717 $retstring .= "</select>";
718 print $retstring;
719 print ' '.$form->textwithpicto('', $langs->trans("KeepEmptyForAYearlyControl"));
720 print '</td>';
721
722 // Day
723 print '<td>';
724 $retstring = '<select'.($disabled ? ' disabled' : '').' class="flat valignmiddle maxwidth50imp" id="'.$prefix.'day" name="'.$prefix.'day">';
725 $retstring .= '<option value="0" selected>&nbsp;</option>';
726 for ($day = 1; $day <= 31; $day++) {
727 $retstring .= '<option value="'.$day.'"'.($day == $sday ? ' selected' : '').'>'.$day.'</option>';
728 }
729 $retstring .= "</select>";
730 print $retstring;
731 print ' '.$form->textwithpicto('', $langs->trans("KeepEmptyForAMonthlyControl"));
732 print '</td>';
733
734 // Button Start
735 print '<td>';
736 if ($action == 'start' && GETPOST('posnumber') != '' && GETPOSTINT('posnumber') != 0 && GETPOSTINT('posnumber') != -1) {
737 print '';
738 } else {
739 print '<input type="submit" name="add" class="button" value="'.$langs->trans("Start").'">';
740 }
741 print '</td>';
742 print '</table>';
743 print '</div>';
744
745
746 // Table to see/enter balance
747 if ($action == 'start' && GETPOST('posnumber') != '' && GETPOSTINT('posnumber') != 0 && GETPOSTINT('posnumber') != -1) {
748 $posmodule = GETPOST('posmodule', 'alpha');
749 $terminalid = GETPOST('posnumber', 'alpha');
750
751 print '<br>';
752
753 print '<div class="div-table-responsive-no-min">';
754 print '<table class="noborder centpercent">';
755
756 print '<tr class="liste_titre">';
757 print '<td></td>';
758 print '<td class="center">'.$langs->trans("InitialBankBalance");
759 print '<br>';
760 print '<span class="small opacitymedium">'.$langs->trans("at").' '.dol_print_date($datestart, 'standard', 'gmt').' UTC</span>';
761 //print '<br>'.$langs->trans("TheoricalAmount").'<br>'.$langs->trans("RealAmount");
762 print '</td>';
763
764 /*
765 print '<td align="center" class="hide0" colspan="'.count($arrayofpaymentmode).'">';
766 print $langs->trans("AmountAtEndOfPeriod");
767 print '</td>';
768 */
769 print '<td></td>';
770 print '</tr>';
771
772 print '<tr class="liste_titre">';
773 print '<td></td>';
774 print '<td class="center">'.$langs->trans("Cash");
775 //print '<br>'.$langs->trans("TheoricalAmount").'<br>'.$langs->trans("RealAmount");
776 print '</td>';
777 /*
778 $i = 0;
779 foreach ($arrayofpaymentmode as $key => $val)
780 {
781 print '<td align="center"'.($i == 0 ? ' class="hide0"' : '').'>'.$langs->trans($val);
782 //print '<br>'.$langs->trans("TheoricalAmount").'<br>'.$langs->trans("RealAmount");
783 print '</td>';
784 $i++;
785 }*/
786 print '<td></td>';
787 print '</tr>';
788
789 /*print '<tr>';
790 // Initial amount
791 print '<td>'.$langs->trans("NbOfInvoices").'</td>';
792 print '<td class="center">';
793 print '</td>';
794 // Amount per payment type
795 $i = 0;
796 foreach ($arrayofpaymentmode as $key => $val)
797 {
798 print '<td align="center"'.($i == 0 ? ' class="hide0"' : '').'>';
799 print $theoricalnbofinvoiceforterminal[$terminalid][$key];
800 print '</td>';
801 $i++;
802 }
803 // Save
804 print '<td align="center"></td>';
805 print '</tr>';
806 */
807
808 print '<tr>';
809 // Initial amount
810 print '<td>';
811 print $form->textwithpicto($langs->trans("TheoricalAmount"), $langs->trans("TheoricalAmountAtOpening"));
812 print '</td>';
813 print '<td class="center">';
814 print price($initialbalanceforterminal[$terminalid]['cash']).'<br>';
815 print '</td>';
816 // Amount per payment type
817 /*$i = 0;
818 foreach ($arrayofpaymentmode as $key => $val)
819 {
820 print '<td align="center"'.($i == 0 ? ' class="hide0"' : '').'>';
821 print price($theoricalamountforterminal[$terminalid][$key]).'<br>';
822 print '</td>';
823 $i++;
824 }*/
825 // Save
826 print '<td></td>';
827 print '</tr>';
828
829 print '<tr>';
830 print '<td>'.$langs->trans("RealAmount").'</td>';
831 // Initial amount
832 print '<td class="center">';
833 print '<input ';
834 if ($action == 'close') {
835 print 'disabled '; // To close cash user can't set opening cash
836 }
837 print 'name="opening" type="text" class="maxwidth100 center" value="';
838 if ($action == 'close') {
839 $object->fetch($id);
840 print $object->opening;
841 } else {
842 print(GETPOSTISSET('opening') ? price2num(GETPOST('opening', 'alpha')) : price($initialbalanceforterminal[$terminalid]['cash']));
843 }
844 print '">';
845 print '</td>';
846 // Amount per payment type
847 /*$i = 0;
848 foreach ($arrayofpaymentmode as $key => $val)
849 {
850 print '<td align="center"'.($i == 0 ? ' class="hide0"' : '').'>';
851 print '<input ';
852 if ($action == 'start') print 'disabled '; // To start cash user only can set opening cash
853 print 'name="'.$key.'_amount" type="text"'.($key == 'cash' ? ' autofocus' : '').' class="maxwidth100 center" value="'.GETPOST($key.'_amount', 'alpha').'">';
854 print '</td>';
855 $i++;
856 }*/
857 // Save
858 print '<td class="center">';
859 print '<input type="submit" name="cancel" class="button button-cancel" value="'.$langs->trans("Cancel").'">';
860 if ($action == 'start') {
861 print '<input type="submit" name="add" class="button button-save" value="'.$langs->trans("Start").'">';
862 } elseif ($action == 'close') {
863 print '<input type="submit" name="valid" class="button" value="'.$langs->trans("Validate").'">';
864 }
865 print '</td>';
866 print '</tr>';
867
868 print '</table>';
869 print '</div>';
870 }
871
872 print '</form>';
873}
874
875// View
876if (empty($action) || $action == "view" || $action == "close") {
877 $result = $object->fetch($id);
878
879 if ($result <= 0) {
880 print $langs->trans("ErrorRecordNotFound");
881 } else {
882 $head = array();
883 $head[0][0] = DOL_URL_ROOT.'/compta/cashcontrol/cashcontrol_card.php?id='.$object->id;
884 $head[0][1] = $langs->trans("CashControl");
885 $head[0][2] = 'cashcontrol';
886
887 print dol_get_fiche_head($head, 'cashcontrol', $langs->trans("CashControl"), -1, 'account');
888
889 $linkback = '<a href="'.DOL_URL_ROOT.'/compta/cashcontrol/cashcontrol_list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
890
891 $morehtmlref = '<div class="refidno">';
892 $morehtmlref .= '</div>';
893
894
895 dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $morehtmlref);
896
897 print '<div class="fichecenter">';
898 print '<div class="fichehalfleft">';
899 print '<div class="underbanner clearboth"></div>';
900 print '<table class="border tableforfield centpercent">';
901
902 print '<tr><td class="titlefield nowrap">';
903 print $langs->trans("Ref");
904 print '</td><td>';
905 print $id;
906 print '</td></tr>';
907
908 print '<tr><td valign="middle">'.$langs->trans("Module").'</td><td>';
909 print $object->posmodule;
910 print "</td></tr>";
911
912 print '<tr><td valign="middle">'.$langs->trans("Terminal").'</td><td>';
913 print $object->posnumber;
914 print "</td></tr>";
915
916 print '<tr><td class="titlefield nowrap">';
917 print $langs->trans("DateCreationShort");
918 print '</td><td colspan="3">';
919 print dol_print_date($object->date_creation, 'dayhour');
920 print '</td></tr>';
921
922 print '<tr><td class="nowrap">';
923 print $langs->trans("Period");
924 print '</td><td>';
925 $period = $object->year_close;
926 $period .= ($object->month_close ? "-".sprintf("%02d", $object->month_close) : "");
927 $period .= ($object->day_close ? "-".sprintf("%02d", $object->day_close) : "");
928 print $period;
929
930 //print ' &nbsp; &nbsp; ';
931 $htmltooltip = '';
932 $htmltooltip .= dol_print_date($datestart, 'standard', 'tzuserrel').' - ';
933 $htmltooltip .= dol_print_date($dateend, 'standard', 'tzuserrel');
934 $htmltooltip .= '<br><span class="small opacitymedium">UTC : ';
935 $htmltooltip .= dol_print_date($datestart, 'standard', 'gmt').' - ';
936 $htmltooltip .= dol_print_date($dateend, 'standard', 'gmt');
937 $htmltooltip .= '</span>';
938 $htmltooltip .= '<br><br>';
939 if (isALNERunningVersion() && $mysoc->country_code == 'FR') {
940 $htmltooltip .= $langs->trans("UsedToSeletRecordOn", $langs->transnoentitiesnoconv("BlockedLog"), MAIN_DB_PREFIX."blockedlog", $langs->transnoentitiesnoconv("DateCreation"), "date_creation");
941 } else {
942 $htmltooltip .= $langs->trans("UsedToSeletRecordOn", $langs->transnoentitiesnoconv("Payment"), MAIN_DB_PREFIX."paiement", $langs->transnoentitiesnoconv("DatePayment"), "datep");
943 }
944
945 print $form->textwithpicto('', $htmltooltip);
946 print '</td></tr>';
947
948 // Other attributes
949 $parameters = array('colspan' => ' colspan="2"', 'cols' => '2');
950 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
951 print $hookmanager->resPrint;
952 if (empty($reshook)) {
953 print $object->showOptionals($extrafields, 'create', $parameters);
954 }
955
956 if ($object->lifetime_start) {
957 print '<tr><td class="titlefield nowrap">';
958 print $langs->trans("LifetimeAmount", $langs->transnoentities("AllPaymentModes"));
959 print '</td><td colspan="3">';
960 print '<span class="amount">'.price($object->card_lifetime + $object->cheque_lifetime + $object->cash_lifetime, 0, $langs, 1, -1, -1, $conf->currency).'</span>';
961 print ' &nbsp; <span class="opacitymedium">'.$langs->trans("since").' '.dol_print_date($object->lifetime_start, 'dayhour').' ('.$langs->trans("AllTerminals").')</span>';
962 print '</td></tr>';
963 }
964
965 print '</table>';
966 print '</div>';
967
968 print '<div class="fichehalfright">';
969 print '<div class="underbanner clearboth"></div>';
970
971 print '<table class="noborder paymenttable centpercent">';
972
973 if ($object->status == $object::STATUS_CLOSED) {
974 print '<tr class="liste_titre"><td class="liste_titre">'.$langs->trans("Summary").'</td>';
975 print '<td class="liste_titre right">'.$langs->trans("InitialBankBalance").'</td>';
976 print '<td class="liste_titre right">'.$langs->trans("Sales").'</td>';
977 print '<td class="liste_titre right">'.$langs->trans("EndBankBalance").'</td>';
978 print "</tr>";
979
980 foreach ($arrayofpaymentmode as $key => $val) {
981 $newkey = $key.'_declared';
982 if (!property_exists($object, $key)) {
983 continue;
984 }
985
986 $realamountforpaymentmode = $object->$key;
987 $declaredamountforpaymentmode = $object->$newkey;
988
989 print '<tr>';
990 print '<td class="">'.$langs->trans($val).'</td>';
991 print '<td class="right">';
992 if ($key == 'cash') {
993 print '<span class="amount">'.price($object->opening, 0, $langs, 1, -1, -1, $conf->currency).'</span>';
994 }
995 print '</td>';
996 print '<td class="right">';
997 if ($realamountforpaymentmode) {
998 print '<span class="amount">'.($realamountforpaymentmode >= 0 ? '+' : '').price($realamountforpaymentmode, 0, $langs, 1, -1, -1, $conf->currency).'</span>';
999 }
1000 print '</td>';
1001 print '<td class="right">';
1002 $calcamount = (($key == 'cash' ? $object->opening : 0) + $realamountforpaymentmode);
1003 print '<span class="amount">'.price($calcamount, 0, $langs, 1, -1, -1, $conf->currency).'</span>';
1004 //print '</span>';
1005 //print '<span class="amount';
1006 if ($calcamount != $declaredamountforpaymentmode) {
1007 //print ' error';
1008 print img_picto($langs->trans("Declared").': '.$declaredamountforpaymentmode, 'warning');
1009 }
1010 //print '">';
1011
1012
1013 print '</td>';
1014 print '</tr>';
1015 }
1016 }
1017
1018 print "</table>\n";
1019
1020 print '</div></div>';
1021 print '<div class="clearboth"></div>';
1022
1023 print dol_get_fiche_end();
1024
1025 if ($action != 'close') {
1026 print '<div class="tabsAction">';
1027
1028 // Print ticket
1029 print '<div class="inline-block divButAction"><a target="_blank" rel="noopener noreferrer" class="butAction" href="report.php?id='.((int) $id).'">'.$langs->trans('PrintReport').'</a></div>';
1030
1031 // Print ticket (no detail)
1032 print '<div class="inline-block divButAction"><a target="_blank" rel="noopener noreferrer" class="butAction" href="report.php?id='.((int) $id).'&summaryonly=1">'.$langs->trans('PrintReportNoDetail').'</a></div>';
1033
1034 // Close or logical deletion
1035 if ($object->status == CashControl::STATUS_DRAFT) {
1036 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.((int) $id).'&action=close&token='.newToken().'&contextpage='.$contextpage.'">'.$langs->trans('Close').'</a></div>';
1037
1038 print '<div class="inline-block divButAction">'.dolGetButtonAction($langs->trans('Delete'), $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"].'?id='.((int) $id).'&action=confirm_delete&token='.newToken(), '', true, array('attr' => array('class' => 'reposition'))).'</div>'."\n";
1039 } else {
1040 if (!isALNERunningVersion()) {
1041 if ($permissiontoreopen) {
1042 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.((int) $id).'&action=reopen&token='.newToken().'">'.$langs->trans('ReOpen').'</a></div>';
1043 } else {
1044 print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dolPrintHTMLForAttribute($langs->trans("NotEnoughPermissions")).'">'.$langs->trans('ReOpen').'</a></div>';
1045 }
1046 }
1047 }
1048
1049 print '</div>';
1050
1051 if ($contextpage != 'takepos') {
1052 // Add ifram of report
1053 print '<center><iframe src="'.DOL_URL_ROOT.'/compta/cashcontrol/report.php?id='.$id.'" width="60%" height="800"></iframe></center>';
1054 }
1055 } else {
1056 print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'" name="formclose">';
1057 print '<input type="hidden" name="token" value="'.newToken().'">';
1058 if ($contextpage == 'takepos') {
1059 print '<input type="hidden" name="contextpage" value="takepos">';
1060 }
1061 if ($action == 'start' && GETPOST('posnumber') != '' && GETPOSTINT('posnumber') != 0 && GETPOSTINT('posnumber') != -1) {
1062 print '<input type="hidden" name="action" value="add">';
1063 } elseif ($action == 'close') {
1064 print '<input type="hidden" name="action" value="valid">';
1065 print '<input type="hidden" name="id" value="'.$id.'">';
1066 } else {
1067 print '<input type="hidden" name="action" value="start">';
1068 }
1069
1070 // Table to see/enter balance
1071 if (($action == 'start' && GETPOST('posnumber') != '' && GETPOST('posnumber') != '' && GETPOST('posnumber') != '-1') || $action == 'close') {
1072 $posmodule = $object->posmodule;
1073 $terminalid = $object->posnumber;
1074
1075 print '<br>';
1076
1077 print '<!-- section to enter declared mount -->';
1078 print '<div class="div-table-responsive-no-min">';
1079 print '<table class="noborder centpercent">';
1080
1081 print '<tr class="liste_titre">';
1082 print '<td></td>';
1083 print '<td class="center">'.$langs->trans("InitialBankBalance");
1084 print '<br>';
1085 print '<span class="small opacitymedium">'.$langs->trans("at").' '.dol_print_date($datestart, 'standard', 'gmt').' UTC</span>';
1086 print '</td>';
1087
1088 print '<td align="center" class="hide0" colspan="'.count($arrayofpaymentmode).'">';
1089 print $langs->trans("AmountAtEndOfPeriod");
1090 print '<br>';
1091 print '<span class="small opacitymedium">'.$langs->trans("at").' '.dol_print_date($dateend, 'standard', 'gmt').' UTC</span>';
1092 print '</td>';
1093 print '<td></td>';
1094 print '</tr>';
1095
1096 print '<tr class="liste_titre">';
1097 print '<td></td>';
1098 print '<td class="center">'.$langs->trans("Cash");
1099 //print '<br>'.$langs->trans("TheoricalAmount").'<br>'.$langs->trans("RealAmount");
1100 print '</td>';
1101 $i = 0;
1102 foreach ($arrayofpaymentmode as $key => $val) {
1103 print '<td class="center'.($i == 0 ? ' hide0' : '').'">'.$langs->trans($val);
1104 //print '<br>'.$langs->trans("TheoricalAmount").'<br>'.$langs->trans("RealAmount");
1105 print '</td>';
1106 $i++;
1107 }
1108 print '<td></td>';
1109 print '</tr>';
1110
1111 print '<tr>';
1112 // Initial amount
1113 print '<td>'.$langs->trans("NbOfPayments").'</td>';
1114 print '<td class="center">';
1115 print '</td>';
1116 // Amount per payment type
1117 $i = 0;
1118 foreach ($arrayofpaymentmode as $key => $val) {
1119 print '<td class="center'.($i == 0 ? ' hide0' : '').'">';
1120 print $theoricalnbofinvoiceforterminal[$terminalid][$key];
1121 print '</td>';
1122 $i++;
1123 }
1124 // Save
1125 print '<td align="center"></td>';
1126 print '</tr>';
1127
1128 print '<tr>';
1129 // Initial amount
1130 print '<td>'.$langs->trans("TheoricalAmount").'</td>';
1131 print '<td class="center">';
1132 print price($initialbalanceforterminal[$terminalid]['cash']).'<br>';
1133 print '</td>';
1134
1135 // Amount calculated per payment type (field cash_calculated, cheque_calculated, card_calculated)
1136 $i = 0;
1137 foreach ($arrayofpaymentmode as $key => $val) {
1138 print '<td class="smallheight center'.($i == 0 ? ' hide0' : '').'">';
1139 if ($key == 'cash') {
1140 print price($object->opening + $theoricalamountforterminal[$terminalid][$key]).'<br>';
1141 print '<span class="opacitymedium small">('.price($object->opening).' + '.price($theoricalamountforterminal[$terminalid][$key]).')</span>';
1142 } else {
1143 print price($theoricalamountforterminal[$terminalid][$key]).'<br>';
1144 }
1145 print '<input type="hidden" name="'.$key.'_calculated" value="'.$theoricalamountforterminal[$terminalid][$key].'">';
1146 print '</td>';
1147 $i++;
1148 }
1149
1150 // Save
1151 print '<td align="center"></td>';
1152 print '</tr>';
1153
1154
1155 print '<tr>';
1156 print '<td>'.$langs->trans("RealAmount").'</td>';
1157
1158 // Initial amount
1159 print '<td class="center">';
1160 print '<input ';
1161 if ($action == 'close') {
1162 print 'disabled '; // To close cash user can't set opening cash
1163 }
1164 print 'name="opening" type="text" class="maxwidth100 center" value="';
1165 if ($action == 'close') {
1166 $object->fetch($id);
1167 print $object->opening;
1168 } else {
1169 print(GETPOSTISSET('opening') ? price2num(GETPOST('opening', 'alpha')) : price($initialbalanceforterminal[$terminalid]['cash']));
1170 }
1171 print '">';
1172 print '</td>';
1173
1174 // Amount per payment type
1175 $i = 0;
1176 foreach ($arrayofpaymentmode as $key => $val) {
1177 print '<td class="center '.($i == 0 ? ' hide0' : '').'">';
1178 print '<input ';
1179 if ($action == 'start') {
1180 print 'disabled '; // To start cash user only can set opening cash
1181 }
1182 print 'name="'.$key.'_amount" type="text"'.($key == 'cash' ? ' autofocus' : '').' class="maxwidth100 center" value="';
1183 $suggestedvalue = '';
1184 if ($key == 'cash') {
1185 $suggestedvalue = price($object->opening + $theoricalamountforterminal[$terminalid][$key]);
1186 } else {
1187 $suggestedvalue = price($theoricalamountforterminal[$terminalid][$key]);
1188 }
1189 print GETPOSTISSET($key.'_amount') ? GETPOST($key.'_amount', 'alpha') : $suggestedvalue;
1190 print '">';
1191 print '</td>';
1192 $i++;
1193 }
1194
1195 // Save
1196 print '<td class="center">';
1197 print '<input type="submit" name="cancel" class="button button-cancel" value="'.$langs->trans("Cancel").'">';
1198 if ($action == 'start') {
1199 print '<input type="submit" name="add" class="button button-save" value="'.$langs->trans("Save").'">';
1200 } elseif ($action == 'close') {
1201 print '<input type="submit" name="valid" class="button" value="'.$langs->trans("Close").'">';
1202 }
1203 print '</td>';
1204 print '</tr>';
1205
1206 print '</table>';
1207 print '</div>';
1208 }
1209
1210 print '</form>';
1211 }
1212 }
1213}
1214
1215// End of page
1216llxFooter();
1217$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
isALNERunningVersion($blockedlogusagealreadychecked=0, $blockedlogmoduleonalreadychecked=0)
Return if the application is executed with the LNE requirements on.
Class to manage cash fence.
Class to manage standard extra fields.
Class to manage generation of HTML components Only common components must be here.
global $mysoc
dol_get_first_hour($date, $gm='tzserver')
Return GMT time for first hour of a given GMT date (it removes hours, min and second part)
Definition date.lib.php:676
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition date.lib.php:616
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:126
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:635
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
GETPOSTDATE($prefix, $hourTime='', $gm='auto', $saverestore='')
Helper function that combines values of a dolibarr DatePicker (such as Form\selectDate) for year,...
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
Definition html.lib.php:540
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Definition html.lib.php:738
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.