New: add configuration to choose if holiday are updated at the end of month (#29438)

* New setting for holiday updates

* FIX: holidays accounting at the end of taken month: log consumption for every request + update translations

* FIX: holidays accounting at the end of taken month: update conf name

* FIX: holidays accounting at the end of taken month: refactor monthly cron update

* FIX: holidays accounting at the end of taken month: update conf translation

* FIX: holidays accounting at the end of taken month: initialize holiday array + delete duplicate code

* New setting for holiday updates

* FIX: holidays accounting at the end of taken month: log consumption for every request + update translations

* FIX: holidays accounting at the end of taken month: update conf name

* FIX: holidays accounting at the end of taken month: refactor monthly cron update

* FIX: holidays accounting at the end of taken month: update conf translation

* FIX: holidays accounting at the end of taken month: initialize holiday array + delete duplicate code

* FIX: holidays accounting at the end of taken month: clean code

* FIX: holidays accounting at the end of taken month: empty now used on variables

* FIX: holidays accounting at the end of taken month: resolve not casted var in sql request

* FIX: holidays accounting at the end of taken month: now using only dolibarr functions

* FIX: holidays accounting at the end of taken month: fix php-stan and rework casting to int

* FIX: holidays accounting at the end of taken month: fix php-stan and rework casting to int (2)

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
Co-authored-by: Yannis Hoareau <93135242+JustRaosha@users.noreply.github.com>
This commit is contained in:
Yannis Hoareau 2024-10-10 00:13:36 +02:00 committed by GitHub
parent 8c74ff6e58
commit 42089e3542
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 131 additions and 26 deletions

View File

@ -536,6 +536,22 @@ if ($conf->use_javascript_ajax) {
print "</td>";
print "</tr>";
// Set holiday decrease at the end of month
print '<tr class="oddeven">';
print "<td>".$langs->trans("ConsumeHolidaysAtTheEndOfTheMonthTheyAreTakenAt")."</td>";
print '<td class="center">';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('HOLIDAY_DECREASE_AT_END_OF_MONTH', array(), null, 0, 0, 0, 2, 0, 1);
} else {
if (getDolGlobalString('HOLIDAY_DECREASE_AT_END_OF_MONTH')) {
print '<a href="'.$_SERVER['PHP_SELF'].'?action=set_other&token='.newToken().'&HOLIDAY_DECREASE_AT_END_OF_MONTH=1">'.img_picto($langs->trans("Enabled"), 'on').'</a>';
} else {
print '<a href="'.$_SERVER['PHP_SELF'].'?action=set_other&token='.newToken().'&HOLIDAY_DECREASE_AT_END_OF_MONTH=0">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
}
}
print "</td>";
print "</tr>";
if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
$substitutionarray = pdf_getSubstitutionArray($langs, array('objectamount'), null, 2);
$substitutionarray['__(AnyTranslationKey)__'] = $langs->trans("Translation");

View File

@ -603,6 +603,8 @@ if (empty($reshook)) {
$object->statut = Holiday::STATUS_APPROVED;
$object->status = Holiday::STATUS_APPROVED;
$decrease = getDolGlobalInt('HOLIDAY_DECREASE_AT_END_OF_MONTH');
$db->begin();
$verif = $object->approve($user);
@ -612,12 +614,12 @@ if (empty($reshook)) {
}
// If no SQL error, we redirect to the request form
if (!$error) {
if (!$error && empty($decrease)) {
// Calculate number of days consumed
$nbopenedday = num_open_day($object->date_debut_gmt, $object->date_fin_gmt, 0, 1, $object->halfday);
$soldeActuel = $object->getCpforUser($object->fk_user, $object->fk_type);
$newSolde = ($soldeActuel - $nbopenedday);
$label = $langs->transnoentitiesnoconv("Holidays").' - '.$object->ref;
$label = $object->ref.' - '.$langs->transnoentitiesnoconv("HolidayConsumption");
// The modification is added to the LOG
$result = $object->addLogCP($user->id, $object->fk_user, $label, $newSolde, $object->fk_type);
@ -832,6 +834,8 @@ if (empty($reshook)) {
$object->statut = Holiday::STATUS_CANCELED;
$object->status = Holiday::STATUS_CANCELED;
$decrease = getDolGlobalInt('HOLIDAY_DECREASE_AT_END_OF_MONTH');
$result = $object->update($user);
if ($result >= 0 && $oldstatus == Holiday::STATUS_APPROVED) { // holiday was already validated, status 3, so we must increase back the balance
@ -841,14 +845,28 @@ if (empty($reshook)) {
$error++;
}
$startDate = $object->date_debut_gmt;
$endDate = $object->date_fin_gmt;
if (!empty($decrease)) {
$lastUpdate = strtotime($object->getConfCP('lastUpdate', dol_print_date(dol_now(), '%Y%m%d%H%M%S')));
$date = strtotime('-1 month', $lastUpdate);
$endOfMonthBeforeLastUpdate = dol_mktime(0, 0, 0, (int) date('m', $date), (int) date('t', $date), (int) date('Y', $date), 1);
if ($object->date_debut_gmt < $endOfMonthBeforeLastUpdate && $object->date_fin_gmt > $endOfMonthBeforeLastUpdate) {
$endDate = $endOfMonthBeforeLastUpdate;
} elseif ($object->date_debut_gmt > $endOfMonthBeforeLastUpdate) {
$endDate = $startDate;
}
}
// Calculate number of days consumed
$nbopenedday = num_open_day($object->date_debut_gmt, $object->date_fin_gmt, 0, 1, $object->halfday);
$nbopenedday = num_open_day($startDate, $endDate, 0, 1, $object->halfday);
$soldeActuel = $object->getCpforUser($object->fk_user, $object->fk_type);
$newSolde = ($soldeActuel + $nbopenedday);
// The modification is added to the LOG
$result1 = $object->addLogCP($user->id, $object->fk_user, $langs->transnoentitiesnoconv("HolidaysCancelation"), $newSolde, $object->fk_type);
$result1 = $object->addLogCP($user->id, $object->fk_user, $object->ref.' - '.$langs->transnoentitiesnoconv("HolidayCreditAfterCancellation"), $newSolde, $object->fk_type);
// Update of the balance
$result2 = $object->updateSoldeCP($object->fk_user, $newSolde, $object->fk_type);

View File

@ -505,6 +505,7 @@ class Holiday extends CommonObject
*/
public function fetchByUser($user_id, $order = '', $filter = '')
{
$this->holiday = [];
$sql = "SELECT";
$sql .= " cp.rowid,";
$sql .= " cp.ref,";
@ -1657,36 +1658,36 @@ class Holiday extends CommonObject
*/
public function updateSoldeCP($userID = 0, $nbHoliday = 0, $fk_type = 0)
{
global $user, $langs;
global $user, $langs, $conf;
$error = 0;
if (empty($userID) && empty($nbHoliday) && empty($fk_type)) {
$langs->load("holiday");
$decrease = getDolGlobalInt('HOLIDAY_DECREASE_AT_END_OF_MONTH');
// Si mise à jour pour tout le monde en début de mois
$now = dol_now();
$month = date('m', $now);
$newdateforlastupdate = dol_print_date($now, '%Y%m%d%H%M%S');
// Get month of last update
$lastUpdate = $this->getConfCP('lastUpdate', $newdateforlastupdate);
$monthLastUpdate = $lastUpdate[4].$lastUpdate[5];
$lastUpdate = dol_stringtotime($this->getConfCP('lastUpdate', dol_print_date($now, '%Y%m%d%H%M%S')));
//print 'month: '.$month.' lastUpdate:'.$lastUpdate.' monthLastUpdate:'.$monthLastUpdate;exit;
// If month date is not same than the one of last update (the one we saved in database), then we update the timestamp and balance of each open user.
if ($month != $monthLastUpdate) {
$yearMonthLastUpdate = dol_print_date($lastUpdate, '%Y%m');
$yearMonthNow = dol_print_date($now, '%Y%m');
// If month date is not same than the one of last update (the one we saved in database), then we update the timestamp and balance of each open user,
// catching up to the current month if a gap is detected
while ($yearMonthLastUpdate < $yearMonthNow) {
$this->db->begin();
$year = dol_print_date($lastUpdate, '%Y');
$month = dol_print_date($lastUpdate, '%m');
$users = $this->fetchUsers(false, false, ' AND u.statut > 0');
$nbUser = count($users);
$sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
$sql .= " value = '".$this->db->escape($newdateforlastupdate)."'";
$sql .= " WHERE name = 'lastUpdate'";
$result = $this->db->query($sql);
$typeleaves = $this->getTypes(1, 1);
// Update each user counter
@ -1701,27 +1702,89 @@ class Holiday extends CommonObject
$nowHoliday = (float) $userCounter['nb_holiday'];
$newSolde = $nowHoliday + $nbDaysToAdd;
// We add a log for each user
$this->addLogCP($user->id, $userCounter['rowid'], $langs->trans('HolidaysMonthlyUpdate'), $newSolde, $userCounter['type']);
// We add a log for each user when its balance gets increased
$this->addLogCP($user->id, $userCounter['rowid'], $langs->trans('HolidayMonthlyCredit'), $newSolde, $userCounter['type']);
$result = $this->updateSoldeCP($userCounter['rowid'], $newSolde, $userCounter['type']);
if ($result < 0) {
$error++;
break;
$this->db->rollback();
return -1;
}
if (empty($decrease)) {
continue;
}
// We fetch a user's holiday in the current month and then calculate the number of days to deduct if he has at least one registered
$filter = " AND cp.statut = ".((int) self::STATUS_APPROVED);
$filter .= " AND cp.date_fin >= '".$this->db->idate(dol_stringtotime(dol_print_date($lastUpdate, '%Y-%m-01')))."'";
$filter .= " AND cp.date_debut <= '".$this->db->idate(dol_stringtotime(dol_print_date($lastUpdate, '%Y-%m-t')))."'";
$filter .= " AND cp.fk_type = ".((int) $userCounter['type']);
$this->fetchByUser($userCounter['id'], '', $filter);
if (empty($this->holiday)) {
continue;
}
$startOfMonth = dol_mktime(0, 0, 0, (int) $month, 1, (int) $year, 1);
$endOfMonth = dol_mktime(0, 0, 0, (int) $month, (int) dol_print_date($lastUpdate, 't'), (int) $year, 1);
foreach ($this->holiday as $obj) {
$startDate = $obj['date_debut_gmt'];
$endDate = $obj['date_fin_gmt'];
if ($startDate <= $endOfMonth && $startDate < $startOfMonth) {
$startDate = $startOfMonth;
}
if ($startOfMonth <= $endDate && $endDate > $endOfMonth) {
$endDate = $endOfMonth;
}
$nbDaysToDeduct = (int) num_open_day($startDate, $endDate, 0, 1, $obj['halfday']);
if ($nbDaysToDeduct <= 0) {
continue;
}
$newSolde -= $nbDaysToDeduct;
// We add a log for each user when its balance gets decreased
$this->addLogCP($user->id, $userCounter['rowid'], $obj['ref'].' - '.$langs->trans('HolidayConsumption'), $newSolde, $userCounter['type']);
$result = $this->updateSoldeCP($userCounter['rowid'], $newSolde, $userCounter['type']);
if ($result < 0) {
$this->db->rollback();
return -1;
}
}
}
if (!$error) {
$this->db->commit();
return 1;
} else {
//updating the date of the last monthly balance update
$newMonth = dol_get_next_month((int) dol_print_date($lastUpdate, '%m'), (int) dol_print_date($lastUpdate, '%Y'));
$lastUpdate = dol_mktime(0, 0, 0, (int) $newMonth['month'], 1, (int) $newMonth['year']);
$sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
$sql .= " value = '".$this->db->escape(dol_print_date($lastUpdate, '%Y%m%d%H%M%S'))."'";
$sql .= " WHERE name = 'lastUpdate'";
$result = $this->db->query($sql);
if (!$result) {
$this->db->rollback();
return -1;
}
$this->db->commit();
$yearMonthLastUpdate = dol_print_date($lastUpdate, '%Y%m');
}
return 0;
if (!$error) {
return 1;
} else {
return 0;
}
} else {
// Mise à jour pour un utilisateur
$nbHoliday = price2num($nbHoliday, 5);

View File

@ -101,6 +101,9 @@ AutoValidationOnCreate=Automatic validation
FirstDayOfHoliday=Beginning day of leave request
LastDayOfHoliday=Ending day of leave request
HolidaysMonthlyUpdate=Monthly update
HolidayMonthlyCredit=Monthly credit
HolidayConsumption=Consumption
HolidayCreditAfterCancellation=Credit after cancellation
ManualUpdate=Manual update
HolidaysCancelation=Leave request cancellation
EmployeeLastname=Employee last name
@ -154,3 +157,4 @@ ConfirmMassIncreaseHoliday=Bulk leave balance increase
NumberDayAddMass=Number of day to add to the selection
ConfirmMassIncreaseHolidayQuestion=Are you sure you want to increase holiday of the %s selected record(s)?
HolidayQtyNotModified=Balance of remaining days for %s has not been changed
ConsumeHolidaysAtTheEndOfTheMonthTheyAreTakenAt=Consume holidays at the end of the month they are taken at

View File

@ -101,6 +101,9 @@ AutoValidationOnCreate=Validation automatique
FirstDayOfHoliday=Premier jour de congés
LastDayOfHoliday=Dernier jour de congés
HolidaysMonthlyUpdate=Mise à jour mensuelle
HolidayMonthlyCredit=Crédit mensuel
HolidayConsumption=Consommation
HolidayCreditAfterCancellation=Crédit après annulation
ManualUpdate=Mise à jour manuelle
HolidaysCancelation=Annulation de la demande de congés
EmployeeLastname=Nom du salarié
@ -155,3 +158,4 @@ ConfirmMassIncreaseHoliday=Augmentation massive du solde des congés
NumberDayAddMass=Nombre de jours à ajouter à la sélection
ConfirmMassIncreaseHolidayQuestion=Êtes-vous sûr de vouloir augmenter les vacances du ou des enregistrement(s) sélectionnés %s ?
HolidayQtyNotModified=Le solde des jours restants pour %s n'a pas été modifié
ConsumeHolidaysAtTheEndOfTheMonthTheyAreTakenAt=Consommer les jours de congés à la fin du mois où ils sont pris