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