diff --git a/htdocs/blockedlog/admin/blockedlog_archives.php b/htdocs/blockedlog/admin/blockedlog_archives.php index e1acde18816..ef0c1d01203 100644 --- a/htdocs/blockedlog/admin/blockedlog_archives.php +++ b/htdocs/blockedlog/admin/blockedlog_archives.php @@ -280,7 +280,7 @@ if (GETPOST('action') == 'export' && $user->hasRight('blockedlog', 'read')) { / $fh = fopen($tmpfile, 'w'); // Print line with title - fwrite($fh, "BEGIN - date=".$yearmonthdateofexport." - period=".$yearmonthtoexport." - format=V1" + fwrite($fh, "BEGIN - date=".$yearmonthdateofexport." - period=".$yearmonthtoexport." - format=V1 - user=".$user->getFullName($langs) .';'.$langs->transnoentities('Id') .';'.$langs->transnoentities('DateCreation') .';'.$langs->transnoentities('Action') diff --git a/htdocs/blockedlog/class/blockedlog.class.php b/htdocs/blockedlog/class/blockedlog.class.php index 71a19dfa656..e51c46c73bc 100644 --- a/htdocs/blockedlog/class/blockedlog.class.php +++ b/htdocs/blockedlog/class/blockedlog.class.php @@ -1288,7 +1288,8 @@ class BlockedLog } elseif ($this->object_format == 'V1') { // Note: $this->amounts can be '0', '1.1', '1.123'; // All 0 at end should have been removed already return $this->date_creation.'|'.$this->action.'|'.$this->amounts.'|'.$this->ref_object.'|'.$this->date_object.'|'.$this->user_fullname; } elseif ($this->object_format == 'V2') { - $s = $this->date_creation.'|'.$this->action.'|'.$this->amounts.'|'.$this->ref_object.'|'.$this->date_object.'|'.$this->user_fullname; + $s = $this->entity; + $s .= '|'.$this->date_creation.'|'.$this->action.'|'.$this->amounts.'|'.$this->ref_object.'|'.$this->date_object.'|'.$this->user_fullname; $s .= '|'.(string) $this->linktoref; $s .= '|'.(string) $this->linktype; return $s; diff --git a/htdocs/compta/cashcontrol/cashcontrol_card.php b/htdocs/compta/cashcontrol/cashcontrol_card.php index 344a52b71da..aaa4c61f139 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_card.php +++ b/htdocs/compta/cashcontrol/cashcontrol_card.php @@ -31,11 +31,6 @@ // Load Dolibarr environment require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; -require_once DOL_DOCUMENT_ROOT.'/compta/cashcontrol/class/cashcontrol.class.php'; -require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; - /** * @var Conf $conf * @var DoliDB $db @@ -43,6 +38,10 @@ require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; * @var Translate $langs * @var User $user */ +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/cashcontrol/class/cashcontrol.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; $langs->loadLangs(array("install", "cashdesk", "admin", "banks")); @@ -175,9 +174,18 @@ if ($action == "start" && $permissiontoadd) { } if (!$error) { - $object->day_close = GETPOSTINT('closeday'); - $object->month_close = GETPOSTINT('closemonth'); - $object->year_close = GETPOSTINT('closeyear'); + $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'); + + $tmparray = dol_getdate($dateclosegmt, false, 'gmt'); + + $object->day_close = $tmparray['mday']; + $object->month_close = $tmparray['mon']; + $object->year_close = $tmparray['year']; + + $object->hour_close = $tmparray['hours']; + $object->min_close = $tmparray['minutes']; + $object->sec_close = $tmparray['seconds']; $object->opening = (float) price2num(GETPOST('opening', 'alpha')); $object->posmodule = GETPOST('posmodule', 'alpha'); @@ -284,6 +292,7 @@ llxHeader('', $langs->trans("CashControl")); $terminalid = ''; $terminaltouse = ''; +// Calculate initial amount estimation and final amount if ($action == "create" || $action == "start" || $action == 'close') { if ($action == 'close') { $posmodule = $object->posmodule; @@ -309,6 +318,12 @@ if ($action == "create" || $action == "start" || $action == 'close') { } } + // TODO Ask hours to use for initial amount estimation + $shour = 0; + $smin = 0; + $ssec = 0; + $datestart = null; + if (isset($terminalid) && $terminalid != '' && isset($posmodule)) { // Calculate $initialbalanceforterminal for terminal 0 foreach ($arrayofpaymentmode as $key => $val) { @@ -321,15 +336,23 @@ if ($action == "create" || $action == "start" || $action == 'close') { $vartouse = 'CASHDESK_ID_BANKACCOUNT_CASH'.$terminaltouse; $bankid = getDolGlobalInt($vartouse); + // Get the amount in bank before the period date to pre-fill the "initial amount". + // The user is still free to prefill with the correct value if ($bankid > 0) { $sql = "SELECT SUM(amount) as total FROM ".MAIN_DB_PREFIX."bank"; $sql .= " WHERE fk_account = ".((int) $bankid); if ($syear && !$smonth) { - $sql .= " AND dateo < '".$db->idate(dol_get_first_day($syear, 1))."'"; + $datestart = dol_get_first_day($syear, 1); + $dateend = dol_get_last_day($syear, 12); + $sql .= " AND dateo < '".$db->idate($datestart)."'"; } elseif ($syear && $smonth && !$sday) { - $sql .= " AND dateo < '".$db->idate(dol_get_first_day($syear, $smonth))."'"; + $datestart = dol_get_first_day($syear, $smonth); + $dateend = dol_get_last_day($syear, $smonth); + $sql .= " AND dateo < '".$db->idate($datestart)."'"; } elseif ($syear && $smonth && $sday) { - $sql .= " AND dateo < '".$db->idate(dol_mktime(0, 0, 0, $smonth, $sday, $syear))."'"; + $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'); } @@ -349,7 +372,7 @@ if ($action == "create" || $action == "start" || $action == 'close') { } } - // Calculate $theoricalamountforterminal + // Calculate $theoricalamountforterminal at end of period foreach ($arrayofpaymentmode as $key => $val) { $sql = "SELECT SUM(pf.amount) as total, COUNT(*) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."paiement_facture as pf, ".MAIN_DB_PREFIX."facture as f, ".MAIN_DB_PREFIX."paiement as p, ".MAIN_DB_PREFIX."c_paiement as cp"; @@ -368,15 +391,7 @@ if ($action == "create" || $action == "start" || $action == 'close') { dol_print_error(null, 'Value for key = '.$key.' not supported'); exit; } - if ($syear && !$smonth) { - $sql .= " AND datep BETWEEN '".$db->idate(dol_get_first_day($syear, 1))."' AND '".$db->idate(dol_get_last_day($syear, 12))."'"; - } elseif ($syear && $smonth && !$sday) { - $sql .= " AND datep BETWEEN '".$db->idate(dol_get_first_day($syear, $smonth))."' AND '".$db->idate(dol_get_last_day($syear, $smonth))."'"; - } elseif ($syear && $smonth && $sday) { - $sql .= " AND datep BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $smonth, $sday, $syear))."' AND '".$db->idate(dol_mktime(23, 59, 59, $smonth, $sday, $syear))."'"; - } else { - setEventMessages($langs->trans('YearNotDefined'), null, 'errors'); - } + $sql .= " AND datep BETWEEN '".$db->idate($datestart)."' AND '".$db->idate($dateend)."'"; $resql = $db->query($sql); if ($resql) { @@ -392,7 +407,9 @@ if ($action == "create" || $action == "start" || $action == 'close') { } } } +} +if ($action == "create" || $action == "start") { //var_dump($theoricalamountforterminal); var_dump($theoricalnbofinvoiceforterminal); if ($action != 'close') { print load_fiche_titre($langs->trans("CashControl")." - ".$langs->trans("New"), '', 'cash-register'); @@ -499,6 +516,8 @@ if ($action == "create" || $action == "start" || $action == 'close') { print ''; print ''; print ''.$langs->trans("InitialBankBalance"); + print '
'; + print ''.$langs->trans("at").' '.dol_print_date($datestart, 'standard', 'gmt').' UTC'; //print '
'.$langs->trans("TheoricalAmount").'
'.$langs->trans("RealAmount"); print ''; @@ -597,7 +616,7 @@ if ($action == "create" || $action == "start" || $action == 'close') { print ''; print ''; if ($action == 'start') { - print ''; + print ''; } elseif ($action == 'close') { print ''; } @@ -658,6 +677,26 @@ if (empty($action) || $action == "view" || $action == "close") { print $object->year_close; print($object->month_close ? "-" : "").$object->month_close; print($object->day_close ? "-" : "").$object->day_close; + + $dateend = dol_mktime($object->hour_close, $object->min_close, $object->sec_close, $object->month_close, $object->day_close, $object->year_close, 'gmt'); + if (empty($object->day_close) && !empty($object->month_close)) { + $datestart = dol_get_last_day(($object->month_close == 1 ? $object->year_close - 1 : $object->year_close), ($object->month_close == 1 ? 12 : $object->month_close - 1), 'gmt'); + } elseif (empty($object->day_close) && empty($object->month_close)) { + $datestart = dol_get_last_day($object->year_close - 1, $object->month_close, 'gmt'); + } else { + $datestart = dol_time_plus_duree($dateend, -1, 'd', 'gmt'); + } + $datestart += 1; // Add 1 second + + //print '     '; + $htmltooltip = ''; + $htmltooltip .= dol_print_date($datestart, 'standard', 'tzuserrel').' - '; + $htmltooltip .= dol_print_date($dateend, 'standard', 'tzuserrel'); + $htmltooltip .= '
UTC : '; + $htmltooltip .= dol_print_date($datestart, 'standard', 'gmt').' - '; + $htmltooltip .= dol_print_date($dateend, 'standard', 'gmt'); + $htmltooltip .= ''; + print $form->textwithpicto('', $htmltooltip); print ''; print ''; @@ -727,57 +766,6 @@ if (empty($action) || $action == "view" || $action == "close") { print ''; } - /* - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print "\n"; - - $disabled = 1; - $prefix = 'close'; - - print ''; - print ''; - print ''; - print ''; - // Year - print ''; - // Month - print ''; - // Day - print ''; - - print ''; - print '
'.$langs->trans("Module").''.$langs->trans("Terminal").''.$langs->trans("Year").''.$langs->trans("Month").''.$langs->trans("Day").'
'.$form->selectarray('posmodulebis', $arrayofposavailable, $object->posmodule, (count($arrayofposavailable) > 1 ? 1 : 0), 0, 0, '', 0, 0, $disabled).''; - - $array = array(); - $numterminals = max(1, $conf->global->TAKEPOS_NUM_TERMINALS); - for($i = 1; $i <= $numterminals; $i++) { - $array[$i] = $i; - } - $selectedposnumber = $object->posnumber; $showempty = 1; - //print $form->selectarray('posnumber', $array, GETPOSTISSET('posnumber') ?GETPOST('posnumber', 'int') : $selectedposnumber, $showempty, 0, 0, '', 0, 0, $disabled); - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print '
'; - print '
'; - */ - // Table to see/enter balance if (($action == 'start' && GETPOST('posnumber') != '' && GETPOST('posnumber') != '' && GETPOST('posnumber') != '-1') || $action == 'close') { $posmodule = $object->posmodule; @@ -791,11 +779,14 @@ if (empty($action) || $action == "view" || $action == "close") { print ''; print ''; print ''.$langs->trans("InitialBankBalance"); - //print '
'.$langs->trans("TheoricalAmount").'
'.$langs->trans("RealAmount"); + print '
'; + print ''.$langs->trans("at").' '.dol_print_date($datestart, 'standard', 'gmt').' UTC'; print ''; print ''; print $langs->trans("AmountAtEndOfPeriod"); + print '
'; + print ''.$langs->trans("at").' '.dol_print_date($dateend, 'standard', 'gmt').' UTC'; print ''; print ''; print ''; diff --git a/htdocs/compta/cashcontrol/class/cashcontrol.class.php b/htdocs/compta/cashcontrol/class/cashcontrol.class.php index a49a8079040..e8fa396dac2 100644 --- a/htdocs/compta/cashcontrol/class/cashcontrol.class.php +++ b/htdocs/compta/cashcontrol/class/cashcontrol.class.php @@ -85,6 +85,9 @@ class CashControl extends CommonObject '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'), + 'hour_close' => array('type' => 'integer', 'label' => 'Hour', 'enabled' => 1, 'visible' => -1, 'position' => 62, 'css' => 'center'), + 'min_close' => array('type' => 'integer', 'label' => 'Min', 'enabled' => 1, 'visible' => -1, 'position' => 63, 'css' => 'center'), + 'sec_close' => array('type' => 'integer', 'label' => 'Sec', 'enabled' => 1, 'visible' => -1, 'position' => 64, 'css' => 'center'), 'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 500), 'date_valid' => array('type' => 'datetime', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 502), 'tms' => array('type' => 'timestamp', 'label' => 'Tms', 'enabled' => 1, 'visible' => 0, 'notnull' => 1, 'position' => 505), @@ -129,6 +132,21 @@ class CashControl extends CommonObject */ public $day_close; + /** + * @var int Hour close + */ + public $hour_close; + + /** + * @var int Minute close + */ + public $min_close; + + /** + * @var int Second close + */ + public $sec_close; + /** * @var string posmodule */ @@ -225,6 +243,9 @@ class CashControl extends CommonObject $sql .= ", day_close"; $sql .= ", month_close"; $sql .= ", year_close"; + $sql .= ", hour_close"; + $sql .= ", min_close"; + $sql .= ", sec_close"; $sql .= ", cash"; $sql .= ", cheque"; $sql .= ", card"; @@ -240,6 +261,9 @@ class CashControl extends CommonObject $sql .= ", ".($this->day_close > 0 ? $this->day_close : "null"); $sql .= ", ".($this->month_close > 0 ? $this->month_close : "null"); $sql .= ", ".((int) $this->year_close); + $sql .= ", ".((int) isset($this->hour_close) ? $this->hour_close : 23); + $sql .= ", ".((int) isset($this->min_close) ? $this->min_close : 59); + $sql .= ", ".((int) isset($this->sec_close) ? $this->sec_close : 59); $sql .= ", ".price2num($this->cash, 'MT'); $sql .= ", ".price2num($this->cheque, 'MT'); $sql .= ", ".price2num($this->card, 'MT'); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 71c5e0e4f5d..0406ed7edce 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -738,7 +738,7 @@ class Form if ($tooltipon == 2 || $tooltipon == 3) { $paramfortooltipimg = ' class="' . $classfortooltip . ($notabs != 3 ? ' inline-block' : '') . ($extracss ? ' ' . $extracss : '') . '" style="padding: 0px;' . ($extrastyle ? ' ' . $extrastyle : '') . '"'; if ($tooltiptrigger == '') { - $paramfortooltipimg .= ' title="' . ($noencodehtmltext ? $htmltext : dol_escape_htmltag($htmltext, 1)) . '"'; // Attribute to put on img tag to store tooltip + $paramfortooltipimg .= ' title="' . ($noencodehtmltext ? $htmltext : dol_escape_htmltag($htmltext, 1, 0, 'span', 0, 1)) . '"'; // Attribute to put on img tag to store tooltip } else { $paramfortooltipimg .= ' dolid="' . $tooltiptrigger . '"'; } @@ -748,7 +748,7 @@ class Form if ($tooltipon == 1 || $tooltipon == 3) { $paramfortooltiptd = ' class="' . ($tooltipon == 3 ? 'cursorpointer ' : '') . $classfortooltip . ($tag != 'td' ? ' inline-block' : '') . ($extracss ? ' ' . $extracss : '') . '" style="padding: 0px;' . ($extrastyle ? ' ' . $extrastyle : '') . '" '; if ($tooltiptrigger == '') { - $paramfortooltiptd .= ' title="' . ($noencodehtmltext ? $htmltext : dol_escape_htmltag($htmltext, 1)) . '"'; // Attribute to put on td tag to store tooltip + $paramfortooltiptd .= ' title="' . ($noencodehtmltext ? $htmltext : dol_escape_htmltag($htmltext, 1, 0, 'span', 0, 1)) . '"'; // Attribute to put on td tag to store tooltip } else { $paramfortooltiptd .= ' dolid="' . $tooltiptrigger . '"'; } @@ -794,7 +794,7 @@ class Form * Show a text with a picto and a tooltip on picto * * @param string $text Text to show - * @param string $htmltooltip Content of tooltip + * @param string $htmltooltip Content of tooltip. Warning: By default we keep only tags. * @param int<-1,1> $direction 1=Icon is after text, -1=Icon is before text, 0=no icon * @param string $type Type of picto ('info', 'infoclickable', 'help', 'helpclickable', 'warning', 'superadmin', 'mypicto@mymodule', ...) or image filepath or 'none' * @param string $extracss Add a CSS style to td, div or span tag diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index 49549691f39..d3e3f53cf57 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -118,7 +118,7 @@ function getServerTimeZoneInt($refgmtdate = 'now') * @param int $time Date timestamp (Must be a UTC timestamp) * @param float $duration_value Value of delay to add * @param string $duration_unit Unit of added delay (d, m, y, w, h, i) - * @param int<0,1> $ruleforendofmonth Change the behavior of PHP over data-interval, 0 or 1 + * @param int<0,1> $ruleforendofmonth Change the behavior when $duration_unit = 'm' and new date reaches a non existing date. Use 0 (PHP behaviour) or 1 * @return int New timestamp * @see convertSecondToTime(), convertTimeToSeconds() */ @@ -191,15 +191,15 @@ function dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforend $newtimemonth = (int) dol_print_date($newtime, '%m'); $newtimetotalmonths = (($newtimeyear * 12) + $newtimemonth); - if ($monthsexpected < $newtimetotalmonths) { + if ($monthsexpected < $newtimetotalmonths || $monthsexpected > $newtimetotalmonths) { // If months differs $newtimehours = (int) dol_print_date($newtime, '%H'); $newtimemins = (int) dol_print_date($newtime, '%M'); $newtimesecs = (int) dol_print_date($newtime, '%S'); - $datelim = dol_mktime($newtimehours, $newtimemins, $newtimesecs, $newtimemonth, 1, $newtimeyear); - $datelim -= (3600 * 24); + $datelim = dol_mktime($newtimehours, $newtimemins, $newtimesecs, $newtimemonth, 1, $newtimeyear); // Take first day + $datelim -= (3600 * 24); // Remove 1 day to get the last day of month - $date->setTimestamp($datelim); + $date->setTimestamp($datelim); // Set new date } } return $date->getTimestamp(); 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 44232441c0e..5960940831d 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 @@ -397,4 +397,8 @@ ALTER TABLE llx_blockedlog ADD CONSTRAINT fk_linktoref FOREIGN KEY (linktoref) R ALTER TABLE llx_fichinterdet ADD COLUMN special_code integer DEFAULT 0 AFTER fk_parent_line; ALTER TABLE llx_fichinterdet ADD COLUMN product_type integer DEFAULT 0 AFTER special_code; +ALTER TABLE llx_pos_cash_fence ADD COLUMN hour_close INTEGER DEFAULT null after year_close; +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; + -- 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 2b937e215fa..4fe7e71c6cd 100644 --- a/htdocs/install/mysql/tables/llx_pos_cash_fence.sql +++ b/htdocs/install/mysql/tables/llx_pos_cash_fence.sql @@ -29,6 +29,9 @@ CREATE TABLE llx_pos_cash_fence( day_close INTEGER, month_close INTEGER, year_close INTEGER, + hour_close INTEGER DEFAULT null, + min_close INTEGER DEFAULT null, + sec_close INTEGER DEFAULT null, posmodule VARCHAR(30), posnumber VARCHAR(30), fk_user_creat integer, diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 1fb8fe078bd..1f323b1a75f 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -1704,8 +1704,6 @@ class Project extends CommonObject $sql .= $filter; } - print $sql; - $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql);