diff --git a/htdocs/blockedlog/admin/blockedlog_archives.php b/htdocs/blockedlog/admin/blockedlog_archives.php
index 02a9725e6ae..d07f0ee1995 100644
--- a/htdocs/blockedlog/admin/blockedlog_archives.php
+++ b/htdocs/blockedlog/admin/blockedlog_archives.php
@@ -505,7 +505,7 @@ if (GETPOST('action') == 'export' && $user->hasRight('blockedlog', 'read')) { /
$sql = "SELECT action, module_source, object_format, MIN(date_creation) as datemin, SUM(amounts_taxexcl) as sumamounts_taxexcl, SUM(amounts) as sumamounts";
$sql .= " FROM ".MAIN_DB_PREFIX."blockedlog";
$sql .= " WHERE entity = ".((int) $conf->entity);
- //$sql .= " AND action IN ('BILL_VALIDATE', 'BILL_SENTBYMAIL', 'PAYMENT_CUSTOMER_CREATE', 'CASHCONTROL_VALIDATE', 'PAYMENT_CUSTOMER_DELETE', 'DOC_DOWNLOAD', 'DOC_PREVIEW')";
+ //$sql .= " AND action IN ('BILL_VALIDATE', 'BILL_SENTBYMAIL', 'PAYMENT_CUSTOMER_CREATE', 'CASHCONTROL_CLOSE', 'PAYMENT_CUSTOMER_DELETE', 'DOC_DOWNLOAD', 'DOC_PREVIEW')";
$sql .= " AND action IN ('BILL_VALIDATE', 'PAYMENT_CUSTOMER_CREATE', 'PAYMENT_CUSTOMER_DELETE')"; // Only event into lifetime total
//$sql .= " AND action IN ('PAYMENT_CUSTOMER_CREATE')";
$sql .= " GROUP BY action, module_source, object_format";
diff --git a/htdocs/blockedlog/class/blockedlog.class.php b/htdocs/blockedlog/class/blockedlog.class.php
index e0cdb511e61..3a321caffae 100644
--- a/htdocs/blockedlog/class/blockedlog.class.php
+++ b/htdocs/blockedlog/class/blockedlog.class.php
@@ -295,8 +295,10 @@ class BlockedLog
$sep++;
$this->trackedevents['separator_'.$sep] = array('id' => 'separator_'.$sep, 'label' => '----------', 'labelhtml' => '----- '.$langs->trans("CashControl").'', 'disabled' => 1);
}
-
- $this->trackedevents['CASHCONTROL_VALIDATE'] = array('id' => 'CASHCONTROL_VALIDATE', 'label' => 'logCASHCONTROL_VALIDATE', 'labelhtml' => img_picto('', 'pos', 'class="pictofixedwidth").').$langs->trans('logCASHCONTROL_VALIDATE'));
+ if (getDolGlobalString('BLOCKEDLOG_ADD_OLD_CASHCONTROL_VALIDATE')) {
+ $this->trackedevents['CASHCONTROL_VALIDATE'] = array('id' => 'CASHCONTROL_VALIDATE', 'label' => 'logCASHCONTROL_VALIDATE', 'labelhtml' => img_picto('', 'pos', 'class="pictofixedwidth").').$langs->trans('logCASHCONTROL_VALIDATE'));
+ }
+ $this->trackedevents['CASHCONTROL_CLOSE'] = array('id' => 'CASHCONTROL_CLOSE', 'label' => 'logCASHCONTROL_CLOSE', 'labelhtml' => img_picto('', 'pos', 'class="pictofixedwidth").').$langs->trans('logCASHCONTROL_CLOSE'));
}
// Add more action to track from a conf variable. For the case we want to track other actions into the unalterable log.
diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php
index 4314858490b..dfbaf1570ac 100644
--- a/htdocs/categories/class/categorie.class.php
+++ b/htdocs/categories/class/categorie.class.php
@@ -1623,7 +1623,7 @@ class Categorie extends CommonObject
$w[] = ''.($addpicto ? img_object('', 'category') : '').$cat->label.'';
}
}
- $newcategwithpath = preg_replace('/colortoreplace/', $forced_color, implode(''.$sep.'', $w));
+ $newcategwithpath = preg_replace('/colortoreplace/', $forced_color, implode(''.$sep.'', $w));
$ways[] = $newcategwithpath;
}
diff --git a/htdocs/compta/cashcontrol/cashcontrol_card.php b/htdocs/compta/cashcontrol/cashcontrol_card.php
index 30d4746be2b..07d93a38546 100644
--- a/htdocs/compta/cashcontrol/cashcontrol_card.php
+++ b/htdocs/compta/cashcontrol/cashcontrol_card.php
@@ -52,13 +52,9 @@ $backtopage = GETPOST('backtopage', 'aZ09');
$id = GETPOSTINT('id');
$ref = GETPOST('ref', 'alpha');
-$categid = GETPOST('categid');
$label = GETPOST("label");
$now = dol_now();
-$syear = (GETPOSTISSET('closeyear') ? GETPOSTINT('closeyear') : dol_print_date($now, "%Y"));
-$smonth = (GETPOSTISSET('closemonth') ? GETPOSTINT('closemonth') : dol_print_date($now, "%m"));
-$sday = (GETPOSTISSET('closeday') ? GETPOSTINT('closeday') : dol_print_date($now, "%d"));
$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'aZ09comma');
@@ -118,6 +114,75 @@ $permissiontoadd = ($user->hasRight("cashdesk", "run") || $user->hasRight("takep
$permissiontodelete = ($user->hasRight("cashdesk", "run") || $user->hasRight("takepos", "run")) || ($permissiontoadd && $object->status == 0);
+// Must be after the fetch
+$datestart = null;
+$dateend = null;
+$syear = (GETPOSTISSET('closeyear') ? GETPOSTINT('closeyear') : dol_print_date($now, "%Y", 'tzuserrel'));
+$smonth = (GETPOSTISSET('closemonth') ? GETPOSTINT('closemonth') : dol_print_date($now, "%m", 'tzuserrel'));
+$sday = (GETPOSTISSET('closeday') ? GETPOSTINT('closeday') : dol_print_date($now, "%d", 'tzuserrel'));
+// TODO Add a global option to define the end hours when doing a cash control
+$shour = 0;
+$smin = 0;
+$ssec = 0;
+
+if ($object->id > 0) {
+ // When object is know, we must define first the end date (stored in database with different components) and deduct the start date
+ if (empty($object->day_close) && !empty($object->month_close)) {
+ $dateend = dol_mktime($object->hour_close, $object->min_close, $object->sec_close, $object->month_close, $object->day_close, $object->year_close, 'gmt');
+ $datestart = dol_time_plus_duree($dateend, -1, 'y', 0);
+ } elseif (empty($object->day_close) && empty($object->month_close)) {
+ $dateend = dol_mktime($object->hour_close, $object->min_close, $object->sec_close, 12, 31, $object->year_close, 'gmt');
+ $datestart = dol_mktime($object->hour_close, $object->min_close, $object->sec_close, 12, 1, $object->year_close, 'gmt');
+ $datestart = dol_time_plus_duree($datestart, -1, 'm', 0);
+ } else {
+ $dateend = dol_mktime($object->hour_close, $object->min_close, $object->sec_close, $object->month_close, $object->day_close, $object->year_close, 'gmt');
+ $datestart = dol_time_plus_duree($dateend, -1, 'd', 0);
+ }
+ $datestart += 1; // Add 1 second
+} else {
+ if ($syear && !$smonth) {
+ $datestart = dol_get_first_day($syear, 1, 'tzuserrel');
+ $dateend = dol_get_last_day($syear, 12, 'tzuserrel');
+ $sql .= " AND dateo < '".$db->idate($datestart)."'";
+ } elseif ($syear && $smonth && !$sday) {
+ $datestart = dol_get_first_day($syear, $smonth, 'tzuserrel');
+ $dateend = dol_get_last_day($syear, $smonth, 'tzuserrel');
+ $sql .= " AND dateo < '".$db->idate($datestart)."'";
+ } elseif ($syear && $smonth && $sday) {
+ $datestart = dol_mktime($shour, $smin, $ssec, $smonth, $sday, $syear, 'tzuserrel');
+ $dateend = dol_mktime(23, 59, 59, $smonth, $sday, $syear, 'tzuserrel');
+ $sql .= " AND dateo < '".$db->idate($datestart)."'";
+ } else {
+ setEventMessages($langs->trans('YearNotDefined'), null, 'errors');
+ }
+}
+//var_dump(dol_print_date($datestart, 'dayhour', 'gmt'), dol_print_date($dateend, 'dayhour', 'gmt'));
+
+
+// Define dates and terminal
+$terminalid = '';
+$terminaltouse = '';
+if ($action == "create" || $action == "start" || $action == 'valid' || $action == 'close') {
+ if ($action == 'valid' || $action == 'close') {
+ $posmodule = $object->posmodule;
+ $terminalid = $object->posnumber;
+ $terminaltouse = $terminalid;
+
+ $syear = $object->year_close;
+ $smonth = $object->month_close;
+ $sday = $object->day_close;
+ } elseif (GETPOST('posnumber', 'alpha') != '' && GETPOST('posnumber', 'alpha') != '-1') {
+ $posmodule = GETPOST('posmodule', 'alpha');
+ $terminalid = GETPOST('posnumber', 'alpha');
+ $terminaltouse = $terminalid;
+
+ if ($terminaltouse == '1' && $posmodule == 'cashdesk') {
+ $terminaltouse = '';
+ }
+ }
+}
+
+
/*
* Actions
*/
@@ -179,13 +244,17 @@ if ($action == "start" && $permissiontoadd) {
}
if (!$error) {
- $dateclosegmt = dol_mktime(GETPOSTISSET('closehour') ? GETPOSTINT('closehour') : 23, GETPOSTISSET('closemin') ? GETPOSTINT('closemin') : 59, GETPOSTISSET('closesec') ? GETPOSTINT('closesec') : 59, GETPOSTINT('closemonth'), GETPOSTINT('closeday'), GETPOSTINT('closeyear'), 'tzuserrel');
- dol_syslog('The closing date must be '.dol_print_date($dateclosegmt, 'standard', 'gmt').' UTC');
+ if (GETPOSTINT('closeday')) {
+ $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');
+ } else {
+ $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');
+ }
+ dol_syslog('The closing date will be '.dol_print_date($dateclosegmt, 'standard', 'gmt').' UTC');
$tmparray = dol_getdate($dateclosegmt, false, 'gmt');
- $object->day_close = $tmparray['mday'];
- $object->month_close = $tmparray['mon'];
+ $object->day_close = GETPOSTINT('closeday') ? $tmparray['mday'] : null;
+ $object->month_close = GETPOSTINT('closemonth') ? $tmparray['mon'] : null;
$object->year_close = $tmparray['year'];
$object->hour_close = $tmparray['hours'];
@@ -222,26 +291,126 @@ if ($action == "valid" && $permissiontoadd) { // validate = close
$db->begin();
- /*
- $object->day_close = GETPOST('closeday', 'int');
- $object->month_close = GETPOST('closemonth', 'int');
- $object->year_close = GETPOST('closeyear', 'int');
- */
+ // Save the calculated amount
+ // It will also be saved automatically into llx_blockedlog by the trigger in valid().
+ $object->cash = (float) price2num(GETPOST('cash_calculated', 'alpha'));
+ $object->card = (float) price2num(GETPOST('card_calculated', 'alpha'));
+ $object->cheque = (float) price2num(GETPOST('cheque_calculated', 'alpha'));
// Save the real amount in llx_pos_cash_fence.
- // It will also be saved automatically into llx_blockedlog by the trigger in valid().
- $object->cash = (float) price2num(GETPOST('cash_amount', 'alpha'));
- $object->card = (float) price2num(GETPOST('card_amount', 'alpha'));
- $object->cheque = (float) price2num(GETPOST('cheque_amount', 'alpha'));
+ $object->cash_declared = (float) price2num(GETPOST('cash_amount', 'alpha'));
+ $object->card_declared = (float) price2num(GETPOST('card_amount', 'alpha'));
+ $object->cheque_declared = (float) price2num(GETPOST('cheque_amount', 'alpha'));
- // TODO Add perpetual amount
+ // Add also perpetual amount into cash_lifetime, card_lifetime, cheque_lifetime
+ $cash_lifetime = $card_lifetime = $cheque_lifetime = 0;
+ //$dates = $datestart;
+ $datee = $dateend;
+ $datefilter = 'p.datep';
+ $modulesourcefilter = 'f.module_source';
+ $amountfield = 'pf.amount';
+ $joinleft = 'LEFT ';
+ if (isALNERunningVersion() && $mysoc->country_code == 'FR') {
+ $datefilter = 'bl.date_creation'; // By using this as a filter, it is like the LEFT JOIN is an INNER JOIN
+ $modulesourcefilter = 'bl.module_source';
+ $amountfield = 'bl.amounts';
+ $joinleft = '';
+ }
+
+ $lifetimeamount = array();
+ $lifetimenb = array();
+
+ // Calculate $theoricalamountforterminal at end of period
+ // Sum of payment + Initial amount in bank
+ foreach ($arrayofpaymentmode as $key => $val) {
+ // NOTE: Must be same request than into report.php, except it does an aggregate and do the request 3 times, once per payment type.
+
+ /*$sql = "SELECT p.rowid, p.datep as datep, cp.code,";
+ $sql .= " f.rowid as facid, f.ref, f.datef as datef, pf.amount as amount,";
+ $sql .= " b.fk_account as bankid,";
+ $sql .= " bl.signature"; */
+ $sql = "SELECT SUM(".$db->sanitize($amountfield).") as total, COUNT(*) as nb";
+ $sql .= " FROM ".MAIN_DB_PREFIX."paiement_facture as pf, ".MAIN_DB_PREFIX."facture as f,";
+ $sql .= " ".MAIN_DB_PREFIX."paiement as p";
+ //$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."blockedlog as bl ON bl.ref_object = p.ref AND bl.entity = ".((int) $conf->entity).",";
+ $sql .= " ".$joinleft." JOIN ".MAIN_DB_PREFIX."blockedlog as bl ON bl.action = 'PAYMENT_CUSTOMER_CREATE'";
+ $sql .= " AND bl.element = 'payment' AND bl.fk_object = p.rowid AND bl.entity = ".((int) $conf->entity).",";
+ //$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."bank as b ON p.fk_bank = b.rowid,";
+ $sql .= " ".MAIN_DB_PREFIX."c_paiement as cp";
+ $sql .= " WHERE pf.fk_facture = f.rowid AND p.rowid = pf.fk_paiement AND cp.id = p.fk_paiement";
+ $sql .= " AND ".$db->sanitize($modulesourcefilter)." = '".$db->escape($posmodule)."'";
+ $sql .= " AND f.pos_source = '".$db->escape($terminalid)."'";
+ $sql .= " AND p.entity = ".((int) $conf->entity); // Never share entities for features related to accountancy
+ $sql .= " AND ".$db->sanitize($datefilter)." <= '".$db->idate($datee)."'";
+ if ($key == 'cash') {
+ $sql .= " AND cp.code = 'LIQ'";
+ } elseif ($key == 'cheque') {
+ $sql .= " AND cp.code = 'CHQ'";
+ } elseif ($key == 'card') {
+ $sql .= " AND cp.code = 'CB'";
+ } else {
+ dol_print_error(null, 'Value for key = '.$key.' not supported');
+ exit;
+ }
+ //print $sql."
\n";
+
+ $resql = $db->query($sql);
+ if ($resql) {
+ $lifetimeamount[$terminalid][$key] = 0;
+ $lifetimenb[$terminalid][$key] = 0;
+
+ $obj = $db->fetch_object($resql);
+ if ($obj) {
+ $lifetimeamount[$terminalid][$key] = price2num($lifetimeamount[$terminalid][$key] + $obj->total);
+ $lifetimenb[$terminalid][$key] = $obj->nb;
+ }
+ } else {
+ dol_print_error($db);
+ }
+ }
+
+ $cash_lifetime = $lifetimeamount[$terminalid]['cash'];
+ $card_lifetime = $lifetimeamount[$terminalid]['card'];
+ $cheque_lifetime = $lifetimeamount[$terminalid]['cheque'];
+
+ $object->cash_lifetime = $cash_lifetime;
+ $object->card_lifetime = $card_lifetime;
+ $object->cheque_lifetime = $cheque_lifetime;
+
+
+ // Get the date of first record for the lifetime calculation
+ $sql = "SELECT action, module_source, object_format, date_creation";
+ $sql .= " FROM ".MAIN_DB_PREFIX."blockedlog";
+ $sql .= " WHERE entity = ".((int) $conf->entity);
+ $sql .= " AND action IN ('PAYMENT_CUSTOMER_CREATE')"; // Only this event
+ $sql .= " AND module_source = '".$db->escape($posmodule)."'";
+ //$sql .= " AND pos_source = '".$db->escape($terminalid)."'";
+ $sql .= $db->order("date_creation", "ASC");
+ $sql .= $db->plimit(1);
+
+ $firstrecorddate = 0;
+ $resql = $db->query($sql);
+ if ($resql) {
+ $obj = $db->fetch_object($resql);
+ if ($obj) {
+ $firstrecorddate = $obj->date_creation;
+ }
+ }
+ if ($firstrecorddate) {
+ $object->lifetime_start = $firstrecorddate;
+ }
$result = $object->update($user);
- $result = $object->valid($user); // This also save data into the Unalterable Log table by the trigger CASHCONTROL_VALIDATE.
+ $result2 = $object->close($user); // This also save data into the Unalterable Log table by the trigger CASHCONTROL_CLOSE.
- if ($result <= 0) {
+
+ // TODO
+ // Add an entry into bank to fix difference between amount and declared and if user ask it with a checkbox ?
+
+
+ if ($result <= 0 || $result2 <= 0) {
setEventMessages($object->error, $object->errors, 'errors');
$db->rollback();
} else {
@@ -294,16 +463,6 @@ $initialbalanceforterminal = array();
$theoricalamountforterminal = array();
$theoricalnbofinvoiceforterminal = array();
-$terminalid = '';
-$terminaltouse = '';
-
-// TODO Ask hours to use for the range date
-$shour = 0;
-$smin = 0;
-$ssec = 0;
-$datestart = null;
-$dateend = null;
-
llxHeader('', $langs->trans("CashControl"));
@@ -351,21 +510,6 @@ if ($action == "create" || $action == "start" || $action == 'close') {
if ($bankid > 0) {
$sql = "SELECT SUM(amount) as total FROM ".MAIN_DB_PREFIX."bank";
$sql .= " WHERE fk_account = ".((int) $bankid);
- if ($syear && !$smonth) {
- $datestart = dol_get_first_day($syear, 1);
- $dateend = dol_get_last_day($syear, 12);
- $sql .= " AND dateo < '".$db->idate($datestart)."'";
- } elseif ($syear && $smonth && !$sday) {
- $datestart = dol_get_first_day($syear, $smonth);
- $dateend = dol_get_last_day($syear, $smonth);
- $sql .= " AND dateo < '".$db->idate($datestart)."'";
- } elseif ($syear && $smonth && $sday) {
- $datestart = dol_mktime($shour, $smin, $ssec, $smonth, $sday, $syear);
- $dateend = dol_mktime(23, 59, 59, $smonth, $sday, $syear);
- $sql .= " AND dateo < '".$db->idate($datestart)."'";
- } else {
- setEventMessages($langs->trans('YearNotDefined'), null, 'errors');
- }
$resql = $db->query($sql);
if ($resql) {
@@ -384,17 +528,6 @@ if ($action == "create" || $action == "start" || $action == 'close') {
$dates = $datestart;
$datee = $dateend;
- /*
- if ($syear && !$smonth) {
- $dates = dol_get_first_day($syear, 1); $datee = dol_get_last_day($syear, 12);
- } elseif ($syear && $smonth && !$sday) {
- $dates = dol_get_first_day($syear, $smonth); $datee = dol_get_last_day($syear, $smonth);
- } elseif ($syear && $smonth && $sday) {
- $dates = dol_mktime(0, 0, 0, $smonth, $sday, $syear); $datee = dol_mktime(23, 59, 59, $smonth, $sday, $syear);
- } else {
- dol_print_error(null, 'Year not defined');
- }
- */
$datefilter = 'p.datep';
$modulesourcefilter = 'f.module_source';
$amountfield = 'pf.amount';
@@ -441,11 +574,9 @@ if ($action == "create" || $action == "start" || $action == 'close') {
$resql = $db->query($sql);
if ($resql) {
- $theoricalamountforterminal[$terminalid][$key] = $initialbalanceforterminal[$terminalid][$key];
-
$obj = $db->fetch_object($resql);
if ($obj) {
- $theoricalamountforterminal[$terminalid][$key] = price2num($theoricalamountforterminal[$terminalid][$key] + $obj->total);
+ $theoricalamountforterminal[$terminalid][$key] = $obj->total;
$theoricalnbofinvoiceforterminal[$terminalid][$key] = $obj->nb;
}
} else {
@@ -659,7 +790,7 @@ if ($action == "create" || $action == "start") {
$object->fetch($id);
print $object->opening;
} else {
- print(GETPOSTISSET('opening') ? price2num(GETPOST('opening', 'alpha')) : price($initialbalanceforterminal[$terminalid]['cash']));
+ print (GETPOSTISSET('opening') ? price2num(GETPOST('opening', 'alpha')) : price($initialbalanceforterminal[$terminalid]['cash']));
}
print '">';
print '';
@@ -692,6 +823,7 @@ if ($action == "create" || $action == "start") {
print '';
}
+// View
if (empty($action) || $action == "view" || $action == "close") {
$result = $object->fetch($id);
@@ -732,22 +864,18 @@ if (empty($action) || $action == "view" || $action == "close") {
print $object->posnumber;
print "";
+ print '
| '; - print $langs->trans("DateCreationShort"); - print ' | '; - print dol_print_date($object->date_creation, 'dayhour'); - print ' | ||||
| '.$langs->trans("InitialBankBalance").' - '.$langs->trans("Cash").' | '; - print ''.price($object->opening, 0, $langs, 1, -1, -1, $conf->currency).''; - print " |
| '.$langs->trans("Summary").' | '; + print ''.$langs->trans("InitialBankBalance").' | '; + print ''.$langs->trans("Sales").' | '; + print ''.$langs->trans("EndBankBalance").' | '; + print "||
| '.$langs->trans($val).' | '; - if ($realamountforpaymentmode) { - print ''.price($realamountforpaymentmode, 0, $langs, 1, -1, -1, $conf->currency).''; + $newkey = $key.'_declared'; + if (!property_exists($object, $key)) { + continue; } - print " | ||||
| '.$langs->trans($val).' | '; + print ''; + if ($key == 'cash') { + print ''.price($object->opening, 0, $langs, 1, -1, -1, $conf->currency).''; + } + print ' | '; + print ''; + if ($realamountforpaymentmode) { + print ''.($realamountforpaymentmode >= 0 ? '+' : '').price($realamountforpaymentmode, 0, $langs, 1, -1, -1, $conf->currency).''; + } + print ' | '; + print ''; + print ''; + print price($declaredamountforpaymentmode, 0, $langs, 1, -1, -1, $conf->currency).''; + print ' | '; + print '
| '.$langs->trans("NbOfInvoices").' | '; + print ''.$langs->trans("NbOfPayments").' | '; print ''; print ' | '; // Amount per payment type @@ -896,25 +1053,30 @@ if (empty($action) || $action == "view" || $action == "close") { print '';
print price($initialbalanceforterminal[$terminalid]['cash']).' '; print ' | ';
- // Amount per payment type
+
+ // Amount calculated per payment type
$i = 0;
foreach ($arrayofpaymentmode as $key => $val) {
- print ''; + print ' | '; $i++; } + // Save print ''; print ' |
| '.$langs->trans("RealAmount").' | '; + // Initial amount print ''; print ''; print ' | '; + // Amount per payment type $i = 0; foreach ($arrayofpaymentmode as $key => $val) { - print ''; + print ' | ';
print '';
diff --git a/htdocs/compta/cashcontrol/class/cashcontrol.class.php b/htdocs/compta/cashcontrol/class/cashcontrol.class.php
index 7a54274527e..62062d82aac 100644
--- a/htdocs/compta/cashcontrol/class/cashcontrol.class.php
+++ b/htdocs/compta/cashcontrol/class/cashcontrol.class.php
@@ -82,6 +82,13 @@ class CashControl extends CommonObject
'cash' => array('type' => 'price', 'label' => 'Cash', 'enabled' => 1, 'visible' => 1, 'position' => 30, 'csslist' => 'amount'),
'cheque' => array('type' => 'price', 'label' => 'Cheque', 'enabled' => 1, 'visible' => 1, 'position' => 33, 'csslist' => 'amount'),
'card' => array('type' => 'price', 'label' => 'CreditCard', 'enabled' => 1, 'visible' => 1, 'position' => 36, 'csslist' => 'amount'),
+ 'cash_declared' => array('type' => 'price', 'label' => 'CashDeclared', 'enabled' => 1, 'visible' => 1, 'position' => 40, 'csslist' => 'amount'),
+ 'cheque_declared' => array('type' => 'price', 'label' => 'ChequeDeclared', 'enabled' => 1, 'visible' => 1, 'position' => 41, 'csslist' => 'amount'),
+ 'card_declared' => array('type' => 'price', 'label' => 'CreditCardDeclared', 'enabled' => 1, 'visible' => 1, 'position' => 42, 'csslist' => 'amount'),
+ 'cash_lifetime' => array('type' => 'price', 'label' => 'CashLifetime', 'enabled' => 1, 'visible' => 0, 'position' => 45, 'csslist' => 'amount'),
+ 'cheque_lifetime' => array('type' => 'price', 'label' => 'ChequeLifetime', 'enabled' => 1, 'visible' => 0, 'position' => 46, 'csslist' => 'amount'),
+ 'card_lifetime' => array('type' => 'price', 'label' => 'CreditCardLifetime', 'enabled' => 1, 'visible' => 0, 'position' => 47, 'csslist' => 'amount'),
+ 'lifetime_start' => array('type' => 'datetime', 'label' => 'LifetimeStartDate', 'enabled' => 1, 'visible' => 0, 'position' => 48, 'csslist' => 'center'),
'year_close' => array('type' => 'integer', 'label' => 'Year', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 50, 'css' => 'center'),
'month_close' => array('type' => 'integer', 'label' => 'Month', 'enabled' => 1, 'visible' => 1, 'position' => 55, 'css' => 'center'),
'day_close' => array('type' => 'integer', 'label' => 'Day', 'enabled' => 1, 'visible' => 1, 'position' => 60, 'css' => 'center'),
@@ -158,20 +165,55 @@ class CashControl extends CommonObject
public $posnumber;
/**
- * @var float Cash amount
+ * @var float Cash amount earned during period (calculated)
*/
public $cash;
/**
- * @var float cheque amount
+ * @var float Cheque amount earned during period (calculated)
*/
public $cheque;
/**
- * @var float Card amountS
+ * @var float Card amount earned during period (calculated)
*/
public $card;
+ /**
+ * @var ?float Cash found/declared in account (is the
+ */
+ public $cash_declared;
+
+ /**
+ * @var ?float Cheque found/declared in account
+ */
+ public $cheque_declared;
+
+ /**
+ * @var ?float Card found/declared in account
+ */
+ public $card_declared;
+
+ /**
+ * @var ?float Lifetime cash earned
+ */
+ public $cash_lifetime;
+
+ /**
+ * @var ?float Lifetime cheque amount
+ */
+ public $cheque_lifetime;
+
+ /**
+ * @var ?float Lifetime card amountS
+ */
+ public $card_lifetime;
+
+ /**
+ * @var ?int Date when lifetime value start
+ */
+ public $lifetime_start;
+
/**
* @var int User ID create
*/
@@ -301,7 +343,7 @@ class CashControl extends CommonObject
}
/**
- * Validate cash fence
+ * Validate a cash register control
*
* @param User $user User
* @param int $notrigger No trigger
@@ -309,7 +351,6 @@ class CashControl extends CommonObject
*/
public function valid(User $user, $notrigger = 0)
{
- global $conf, $langs;
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
$error = 0;
@@ -324,7 +365,7 @@ class CashControl extends CommonObject
// Update request
$sql = "UPDATE ".MAIN_DB_PREFIX."pos_cash_fence";
- $sql .= " SET status = ".self::STATUS_VALIDATED.",";
+ $sql .= " SET status = ".((int) self::STATUS_VALIDATED).",";
$sql .= " date_valid='".$this->db->idate($now)."',";
$sql .= " fk_user_valid = ".((int) $user->id);
$sql .= " WHERE rowid=".((int) $this->id);
@@ -368,6 +409,73 @@ class CashControl extends CommonObject
}
+ /**
+ * Close a cash register control
+ *
+ * @param User $user User
+ * @param int $notrigger No trigger
+ * @return int Return integer <0 if KO, >0 if OK
+ */
+ public function close(User $user, $notrigger = 0)
+ {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+
+ $error = 0;
+
+ // Protection
+ if ($this->status == self::STATUS_CLOSED) {
+ $this->error = get_class($this)."::valid action abandoned: already validated";
+ dol_syslog($this->error, LOG_WARNING);
+ return 0;
+ }
+
+ $now = dol_now();
+
+ // Update request
+ $sql = "UPDATE ".MAIN_DB_PREFIX."pos_cash_fence";
+ $sql .= " SET status = ".((int) self::STATUS_CLOSED).",";
+ $sql .= " date_valid = '".$this->db->idate($now)."',";
+ $sql .= " fk_user_valid = ".((int) $user->id);
+ $sql .= " WHERE rowid=".((int) $this->id);
+
+ $this->db->begin();
+
+ dol_syslog(get_class($this)."::close", LOG_DEBUG);
+ $resql = $this->db->query($sql);
+ if (!$resql) {
+ $error++;
+ $this->errors[] = "Error ".$this->db->lasterror();
+ }
+
+ if (!$error) {
+ $this->status = self::STATUS_CLOSED;
+ $this->date_valid = $now;
+ $this->fk_user_valid = $user->id;
+ }
+
+ if (!$error && !$notrigger) {
+ // Call trigger
+ $result = $this->call_trigger('CASHCONTROL_CLOSE', $user);
+ if ($result < 0) {
+ $error++;
+ }
+ // End call triggers
+ }
+
+ // Commit or rollback
+ if ($error) {
+ foreach ($this->errors as $errmsg) {
+ dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
+ $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
+ }
+ $this->db->rollback();
+ return -1 * $error;
+ } else {
+ $this->db->commit();
+ return $this->id;
+ }
+ }
+
/**
* Load object in memory from the database
*
diff --git a/htdocs/compta/cashcontrol/report.php b/htdocs/compta/cashcontrol/report.php
index b2c0cbf5a27..f6bd1240e9a 100644
--- a/htdocs/compta/cashcontrol/report.php
+++ b/htdocs/compta/cashcontrol/report.php
@@ -392,8 +392,8 @@ if ($resql) {
print '';
print ' '.price($cash).' ';
}
- if (!$summaryonly && $object->status == $object::STATUS_VALIDATED && price2num($newcash) != price2num($object->cash)) {
- print ' <> '.$langs->trans("Declared").': '.price($object->cash).' ';
+ if (!$summaryonly && $object->status == $object::STATUS_CLOSED && price2num($newcash) != price2num((float) $object->cash_declared)) {
+ print ' <> '.$langs->trans("Declared").': '.price($object->cash_declared).' ';
}
print ""; @@ -401,8 +401,8 @@ if ($resql) { print $langs->trans("PaymentTypeCHQ").(!empty($transactionspertype['CHQ']) ? ' ('.$transactionspertype['CHQ'].' '.$langs->trans("Articles").')' : '').' : '; print ''; print ' '.price($cheque).' ';
- if (!$summaryonly && $object->status == $object::STATUS_VALIDATED && price2num($cheque) != price2num($object->cheque)) {
- print ' <> '.$langs->trans("Declared").' : '.price($object->cheque).' ';
+ if (!$summaryonly && $object->status == $object::STATUS_CLOSED && price2num($cheque) != price2num((float) $object->cheque_declared)) {
+ print ' <> '.$langs->trans("Declared").' : '.price($object->cheque_declared).' ';
}
print ""; @@ -410,8 +410,8 @@ if ($resql) { print $langs->trans("PaymentTypeCB").(!empty($transactionspertype['CB']) ? ' ('.$transactionspertype['CB'].' '.$langs->trans("Articles").')' : '').' : '; print ''; print ' '.price($bank).' ';
- if (!$summaryonly && $object->status == $object::STATUS_VALIDATED && price2num($bank) != price2num($object->card)) {
- print ' <> '.$langs->trans("Declared").': '.price($object->card).' ';
+ if (!$summaryonly && $object->status == $object::STATUS_CLOSED && price2num($bank) != price2num((float) $object->card_declared)) {
+ print ' <> '.$langs->trans("Declared").': '.price($object->card_declared).' ';
}
print ""; diff --git a/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php b/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php index 621ae8d5bb7..df703ce0bc4 100644 --- a/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php +++ b/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php @@ -107,7 +107,7 @@ class InterfaceActionsBlockedLog extends DolibarrTriggers || $action === 'BILL_SUPPLIER_VALIDATE' || (($action === 'BILL_SUPPLIER_DELETE' || $action === 'BILL_SUPPLIER_SENTBYMAIL') && ($object->statut != 0 || $object->status != 0)) || $action === 'MEMBER_SUBSCRIPTION_CREATE' || $action === 'MEMBER_SUBSCRIPTION_MODIFY' || $action === 'MEMBER_SUBSCRIPTION_DELETE' || $action === 'DON_VALIDATE' || (($action === 'DON_MODIFY' || $action === 'DON_DELETE') && ($object->statut != 0 || $object->status != 0)) - || $action === 'CASHCONTROL_VALIDATE' + || $action === 'CASHCONTROL_CLOSE' || (in_array($object->element, array('facture', 'supplier_invoice')) && $action === 'DOC_DOWNLOAD' && ($object->statut != 0 || $object->status != 0)) || (in_array($object->element, array('facture', 'supplier_invoice')) && $action === 'DOC_PREVIEW' && ($object->statut != 0 || $object->status != 0)) || (getDolGlobalString('BLOCKEDLOG_ADD_ACTIONS_SUPPORTED') && in_array($action, explode(',', getDolGlobalString('BLOCKEDLOG_ADD_ACTIONS_SUPPORTED')))) @@ -119,7 +119,7 @@ class InterfaceActionsBlockedLog extends DolibarrTriggers 'DON_VALIDATE', 'DON_MODIFY', 'DON_DELETE'))) { /** @var Don|Subscription $object */ $amounts = (float) $object->amount; - } elseif ($action == 'CASHCONTROL_VALIDATE') { + } elseif ($action == 'CASHCONTROL_CLOSE') { /** @var CashControl $object */ $amounts = (float) $object->cash + (float) $object->cheque + (float) $object->card; } else { diff --git a/htdocs/install/mysql/migration/22.0.0-23.0.0.sql b/htdocs/install/mysql/migration/22.0.0-23.0.0.sql index 74f44d2bc1e..64842a39f6d 100644 --- a/htdocs/install/mysql/migration/22.0.0-23.0.0.sql +++ b/htdocs/install/mysql/migration/22.0.0-23.0.0.sql @@ -404,12 +404,14 @@ ALTER TABLE llx_pos_cash_fence ADD COLUMN hour_close INTEGER DEFAULT null after ALTER TABLE llx_pos_cash_fence ADD COLUMN min_close INTEGER DEFAULT null after hour_close; ALTER TABLE llx_pos_cash_fence ADD COLUMN sec_close INTEGER DEFAULT null after min_close; -ALTER TABLE llx_pos_cash_fence ADD COLUMN cash_calculated double(24,8) DEFAULT null; -ALTER TABLE llx_pos_cash_fence ADD COLUMN card_calculated double(24,8) DEFAULT null; -ALTER TABLE llx_pos_cash_fence ADD COLUMN cheque_calculated double(24,8) DEFAULT null; +ALTER TABLE llx_pos_cash_fence ADD COLUMN cash_declared double(24,8) DEFAULT null; +ALTER TABLE llx_pos_cash_fence ADD COLUMN card_declared double(24,8) DEFAULT null; +ALTER TABLE llx_pos_cash_fence ADD COLUMN cheque_declared double(24,8) DEFAULT null; ALTER TABLE llx_pos_cash_fence ADD COLUMN cash_lifetime double(24,8) DEFAULT null; ALTER TABLE llx_pos_cash_fence ADD COLUMN card_lifetime double(24,8) DEFAULT null; ALTER TABLE llx_pos_cash_fence ADD COLUMN cheque_lifetime double(24,8) DEFAULT null; +ALTER TABLE llx_pos_cash_fence ADD COLUMN lifetime_start datetime DEFAULT NULL; + -- end of migration diff --git a/htdocs/install/mysql/tables/llx_pos_cash_fence.sql b/htdocs/install/mysql/tables/llx_pos_cash_fence.sql index e3bb0625994..66796d11fbf 100644 --- a/htdocs/install/mysql/tables/llx_pos_cash_fence.sql +++ b/htdocs/install/mysql/tables/llx_pos_cash_fence.sql @@ -20,18 +20,19 @@ CREATE TABLE llx_pos_cash_fence( ref VARCHAR(64), label VARCHAR(255), opening double(24,8) default 0, - -- amount calculated - cash_calculated double(24,8) default NULL, - card_calculated double(24,8) default NULL, - cheque_calculated double(24,8) default NULL, - -- amount declared + -- amount cash double(24,8) default 0, card double(24,8) default 0, cheque double(24,8) default 0, + -- amount declared + cash_declared double(24,8) default NULL, + card_declared double(24,8) default NULL, + cheque_declared double(24,8) default NULL, -- lifetime amount (not used) cash_lifetime double(24,8) default NULL, card_lifetime double(24,8) default NULL, cheque_lifetime double(24,8) default NULL, + lifetime_start datetime default NULL, status INTEGER, date_creation DATETIME NOT NULL, date_valid DATETIME, diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index b98f2532cb3..57681119360 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -706,3 +706,4 @@ TypeAmountOfEachNewDiscountSplit=Input amount for each part SplitDiscountTitle=Split discount into several parts DisputeStatus=Dispute status DisputeOpen=Dispute open +Sales=Sales diff --git a/htdocs/langs/en_US/blockedlog.lang b/htdocs/langs/en_US/blockedlog.lang index 5a28f7faabd..0ac71fd6bb8 100644 --- a/htdocs/langs/en_US/blockedlog.lang +++ b/htdocs/langs/en_US/blockedlog.lang @@ -63,7 +63,8 @@ logBILL_PAYED=Customer invoice paid logBILL_SENTBYMAIL=Customer invoice send by mail logBILL_UNPAYED=Customer invoice set unpaid logBILL_VALIDATE=Customer invoice validated -logCASHCONTROL_VALIDATE=Cash register closing +logCASHCONTROL_VALIDATE=Cash register validation +logCASHCONTROL_CLOSE=Cash register closing logDOC_DOWNLOAD=Download of a validated document in order to print or send logDOC_PREVIEW=Preview of a validated document in order to print or download logDONATION_PAYMENT_CREATE=Donation payment created diff --git a/htdocs/langs/en_US/cashdesk.lang b/htdocs/langs/en_US/cashdesk.lang index 831b8463a39..4a996848dee 100644 --- a/htdocs/langs/en_US/cashdesk.lang +++ b/htdocs/langs/en_US/cashdesk.lang @@ -180,3 +180,5 @@ CashControlEndDateMustBeBeforeNow=It is not possible to make a monthly or yearly CashControlEndDayMustNotBeInPast=It is not possible to make a daily cash control on a day in the future. TheoricalView=Theorical view SentOrderToKitchen=Send order to kitchen +LifetimeAmount=Lifetime amount +AllTerminals=All terminals diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 3b4222173e8..75cb6ec1c63 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -1408,3 +1408,4 @@ KO=KO AddThisPageToBookmarks = Add current page to bookmarks EditBookmarks = List/edit bookmarks Why=Why +since=since |