feat: add function to get public holidays list within period
This commit is contained in:
parent
e217cd61ca
commit
fed049e93e
1 changed files with 268 additions and 0 deletions
|
|
@ -1013,6 +1013,274 @@ function num_public_holiday($timestampStart, $timestampEnd, $country_code = '',
|
|||
return $nbFerie;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of public holidays including Friday, Saturday and Sunday (or not) between 2 dates in timestamp.
|
||||
* Dates must be UTC with hour, min, sec to 0.
|
||||
* Called by function num_open_day()
|
||||
*
|
||||
* @param int $timestampStart Timestamp start (UTC with hour, min, sec = 0)
|
||||
* @param int $timestampEnd Timestamp end (UTC with hour, min, sec = 0)
|
||||
* @param string $country_code Country code
|
||||
* @param int $lastday Last day is included, 0: no, 1:yes
|
||||
* @param int $excludesaturday Exclude saturday as non working day (-1=use setup, 0=no, 1=yes)
|
||||
* @param int $excludesunday Exclude sunday as non working day (-1=use setup, 0=no, 1=yes)
|
||||
* @param int $excludefriday Exclude friday as non working day (-1=use setup, 0=no, 1=yes)
|
||||
* @param int $excludemonday Exclude monday as non working day (-1=use setup, 0=no, 1=yes)
|
||||
* @return int|array List of public holidays or error message string if error
|
||||
* @see num_between_day(), num_open_day()
|
||||
*/
|
||||
function list_public_holiday($timestampStart, $timestampEnd, $country_code = '', $lastday = 0, $excludesaturday = -1, $excludesunday = -1, $excludefriday = -1, $excludemonday = -1)
|
||||
{
|
||||
global $conf, $db, $mysoc;
|
||||
|
||||
// Check to ensure we use correct parameters
|
||||
if (($timestampEnd - $timestampStart) % 86400 != 0) {
|
||||
return 'Error Dates must use same hours and must be GMT dates';
|
||||
}
|
||||
|
||||
if (empty($country_code)) {
|
||||
$country_code = $mysoc->country_code;
|
||||
}
|
||||
if ($excludemonday < 0) {
|
||||
$excludemonday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_MONDAY', 0);
|
||||
}
|
||||
if ($excludefriday < 0) {
|
||||
$excludefriday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_FRIDAY', 0);
|
||||
}
|
||||
if ($excludesaturday < 0) {
|
||||
$excludesaturday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY', 1);
|
||||
}
|
||||
if ($excludesunday < 0) {
|
||||
$excludesunday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY', 1);
|
||||
}
|
||||
|
||||
$country_id = dol_getIdFromCode($db, $country_code, 'c_country', 'code', 'rowid');
|
||||
|
||||
if (empty($conf->cache['arrayOfActivePublicHolidays_' . $country_id])) {
|
||||
// Loop on public holiday defined into hrm_public_holiday for the day, month and year analyzed
|
||||
$tmpArrayOfPublicHolidays = array();
|
||||
$sql = "SELECT id, code, entity, fk_country, dayrule, year, month, day, active";
|
||||
$sql .= " FROM " . MAIN_DB_PREFIX . "c_hrm_public_holiday";
|
||||
$sql .= " WHERE active = 1 and fk_country IN (0" . ($country_id > 0 ? ", " . $country_id : 0) . ")";
|
||||
$sql .= " AND entity IN (0," . getEntity('holiday') . ")";
|
||||
|
||||
$resql = $db->query($sql);
|
||||
if ($resql) {
|
||||
$num_rows = $db->num_rows($resql);
|
||||
$i = 0;
|
||||
while ($i < $num_rows) {
|
||||
$obj = $db->fetch_object($resql);
|
||||
$tmpArrayOfPublicHolidays[$obj->id] = array('dayrule' => $obj->dayrule, 'year' => $obj->year, 'month' => $obj->month, 'day' => $obj->day);
|
||||
$i++;
|
||||
}
|
||||
} else {
|
||||
dol_syslog($db->lasterror(), LOG_ERR);
|
||||
return 'Error sql ' . $db->lasterror();
|
||||
}
|
||||
|
||||
//var_dump($tmpArrayOfPublicHolidays);
|
||||
$conf->cache['arrayOfActivePublicHolidays_' . $country_id] = $tmpArrayOfPublicHolidays;
|
||||
}
|
||||
|
||||
$arrayOfPublicHolidays = $conf->cache['arrayOfActivePublicHolidays_' . $country_id];
|
||||
$listFeries = [];
|
||||
$i = 0;
|
||||
while ((($lastday == 0 && $timestampStart < $timestampEnd) || ($lastday && $timestampStart <= $timestampEnd))
|
||||
&& ($i < 50000)) { // Loop end when equals (Test on i is a security loop to avoid infinite loop)
|
||||
$nonWorkingDay = false;
|
||||
$ferie = false;
|
||||
$specialdayrule = array();
|
||||
|
||||
$jour = (int) gmdate("d", $timestampStart);
|
||||
$mois = (int) gmdate("m", $timestampStart);
|
||||
$annee = (int) gmdate("Y", $timestampStart);
|
||||
|
||||
// If we have to exclude Friday, Saturday and Sunday
|
||||
if ($excludefriday || $excludesaturday || $excludesunday) {
|
||||
$jour_julien = unixtojd($timestampStart);
|
||||
$jour_semaine = jddayofweek($jour_julien, 0);
|
||||
if ($excludefriday) { //Friday (5), Saturday (6) and Sunday (0)
|
||||
if ($jour_semaine == 5) {
|
||||
$nonWorkingDay = true;
|
||||
}
|
||||
}
|
||||
if ($excludesaturday) { //Friday (5), Saturday (6) and Sunday (0)
|
||||
if ($jour_semaine == 6) {
|
||||
$nonWorkingDay = true;
|
||||
}
|
||||
}
|
||||
if ($excludesunday) { //Friday (5), Saturday (6) and Sunday (0)
|
||||
if ($jour_semaine == 0) {
|
||||
$nonWorkingDay = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//print "ferie=".$nonWorkingDay."\n";
|
||||
|
||||
if (!$nonWorkingDay) {
|
||||
//print "jour=".$jour." month=".$mois." year=".$annee." includesaturday=".$excludesaturday." includesunday=".$excludesunday."\n";
|
||||
foreach ($arrayOfPublicHolidays as $entrypublicholiday) {
|
||||
if (!empty($entrypublicholiday['dayrule']) && $entrypublicholiday['dayrule'] != 'date') { // For example 'easter', '...'
|
||||
$specialdayrule[$entrypublicholiday['dayrule']] = $entrypublicholiday['dayrule'];
|
||||
} else {
|
||||
$match = 1;
|
||||
if (!empty($entrypublicholiday['year']) && $entrypublicholiday['year'] != $annee) {
|
||||
$match = 0;
|
||||
}
|
||||
if ($entrypublicholiday['month'] != $mois) {
|
||||
$match = 0;
|
||||
}
|
||||
if ($entrypublicholiday['day'] != $jour) {
|
||||
$match = 0;
|
||||
}
|
||||
|
||||
if ($match) {
|
||||
$ferie = true;
|
||||
$listFeries[] = $timestampStart;
|
||||
}
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
//var_dump($specialdayrule)."\n";
|
||||
//print "ferie=".$nonWorkingDay."\n";
|
||||
}
|
||||
|
||||
if (!$nonWorkingDay && !$ferie) {
|
||||
// Special dayrules
|
||||
if (in_array('easter', $specialdayrule)) {
|
||||
// Calculation for easter date
|
||||
$date_paques = getGMTEasterDatetime($annee);
|
||||
$jour_paques = gmdate("d", $date_paques);
|
||||
$mois_paques = gmdate("m", $date_paques);
|
||||
if ($jour_paques == $jour && $mois_paques == $mois) {
|
||||
$ferie = true;
|
||||
$listFeries[] = $timestampStart;
|
||||
}
|
||||
// Easter (sunday)
|
||||
}
|
||||
|
||||
if (in_array('eastermonday', $specialdayrule)) {
|
||||
// Calculation for the monday of easter date
|
||||
$date_paques = getGMTEasterDatetime($annee);
|
||||
//print 'PPP'.$date_paques.' '.dol_print_date($date_paques, 'dayhour', 'gmt')." ";
|
||||
$date_lundi_paques = $date_paques + (3600 * 24);
|
||||
$jour_lundi_paques = gmdate("d", $date_lundi_paques);
|
||||
$mois_lundi_paques = gmdate("m", $date_lundi_paques);
|
||||
if ($jour_lundi_paques == $jour && $mois_lundi_paques == $mois) {
|
||||
$ferie = true;
|
||||
$listFeries[] = $timestampStart;
|
||||
}
|
||||
// Easter (monday)
|
||||
//print 'annee='.$annee.' $jour='.$jour.' $mois='.$mois.' $jour_lundi_paques='.$jour_lundi_paques.' $mois_lundi_paques='.$mois_lundi_paques."\n";
|
||||
}
|
||||
|
||||
//Good Friday
|
||||
if (in_array('goodfriday', $specialdayrule)) {
|
||||
// Pulls the date of Easter
|
||||
$easter = getGMTEasterDatetime($annee);
|
||||
|
||||
// Calculates the date of Good Friday based on Easter
|
||||
$date_good_friday = $easter - (2 * 3600 * 24);
|
||||
$dom_good_friday = gmdate("d", $date_good_friday);
|
||||
$month_good_friday = gmdate("m", $date_good_friday);
|
||||
|
||||
if ($dom_good_friday == $jour && $month_good_friday == $mois) {
|
||||
$ferie = true;
|
||||
$listFeries[] = $timestampStart;
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array('ascension', $specialdayrule)) {
|
||||
// Calcul du jour de l'ascension (39 days after easter day)
|
||||
$date_paques = getGMTEasterDatetime($annee);
|
||||
$date_ascension = $date_paques + (3600 * 24 * 39);
|
||||
$jour_ascension = gmdate("d", $date_ascension);
|
||||
$mois_ascension = gmdate("m", $date_ascension);
|
||||
if ($jour_ascension == $jour && $mois_ascension == $mois) {
|
||||
$ferie = true;
|
||||
$listFeries[] = $timestampStart;
|
||||
}
|
||||
// Ascension (thursday)
|
||||
}
|
||||
|
||||
if (in_array('pentecost', $specialdayrule)) {
|
||||
// Calculation of "Pentecote" (49 days after easter day)
|
||||
$date_paques = getGMTEasterDatetime($annee);
|
||||
$date_pentecote = $date_paques + (3600 * 24 * 49);
|
||||
$jour_pentecote = gmdate("d", $date_pentecote);
|
||||
$mois_pentecote = gmdate("m", $date_pentecote);
|
||||
if ($jour_pentecote == $jour && $mois_pentecote == $mois) {
|
||||
$ferie = true;
|
||||
$listFeries[] = $timestampStart;
|
||||
}
|
||||
// "Pentecote" (sunday)
|
||||
}
|
||||
|
||||
if (in_array('pentecotemonday', $specialdayrule)) {
|
||||
// Calculation of "Pentecote" (49 days after easter day)
|
||||
$date_paques = getGMTEasterDatetime($annee);
|
||||
$date_pentecote = $date_paques + (3600 * 24 * 50);
|
||||
$jour_pentecote = gmdate("d", $date_pentecote);
|
||||
$mois_pentecote = gmdate("m", $date_pentecote);
|
||||
if ($jour_pentecote == $jour && $mois_pentecote == $mois) {
|
||||
$ferie = true;
|
||||
$listFeries[] = $timestampStart;
|
||||
}
|
||||
// "Pentecote" (monday)
|
||||
}
|
||||
|
||||
if (in_array('viernessanto', $specialdayrule)) {
|
||||
// Viernes Santo
|
||||
$date_paques = getGMTEasterDatetime($annee);
|
||||
$date_viernes = $date_paques - (3600 * 24 * 2);
|
||||
$jour_viernes = gmdate("d", $date_viernes);
|
||||
$mois_viernes = gmdate("m", $date_viernes);
|
||||
if ($jour_viernes == $jour && $mois_viernes == $mois) {
|
||||
$ferie = true;
|
||||
$listFeries[] = $timestampStart;
|
||||
}
|
||||
//Viernes Santo
|
||||
}
|
||||
|
||||
if (in_array('fronleichnam', $specialdayrule)) {
|
||||
// Fronleichnam (60 days after easter sunday)
|
||||
$date_paques = getGMTEasterDatetime($annee);
|
||||
$date_fronleichnam = $date_paques + (3600 * 24 * 60);
|
||||
$jour_fronleichnam = gmdate("d", $date_fronleichnam);
|
||||
$mois_fronleichnam = gmdate("m", $date_fronleichnam);
|
||||
if ($jour_fronleichnam == $jour && $mois_fronleichnam == $mois) {
|
||||
$ferie = true;
|
||||
$listFeries[] = $timestampStart;
|
||||
}
|
||||
// Fronleichnam
|
||||
}
|
||||
|
||||
if (in_array('genevafast', $specialdayrule)) {
|
||||
// Geneva fast in Switzerland (Thursday after the first sunday in September)
|
||||
$date_1sunsept = strtotime('next thursday', strtotime('next sunday', mktime(0, 0, 0, 9, 1, $annee)));
|
||||
$jour_1sunsept = date("d", $date_1sunsept);
|
||||
$mois_1sunsept = date("m", $date_1sunsept);
|
||||
if ($jour_1sunsept == $jour && $mois_1sunsept == $mois) {
|
||||
$ferie = true;
|
||||
$listFeries[] = $timestampStart;
|
||||
}
|
||||
// Geneva fast in Switzerland
|
||||
}
|
||||
}
|
||||
//print "ferie=".$nonWorkingDay."\n";
|
||||
|
||||
// Increase number of days (on go up into loop)
|
||||
$timestampStart = dol_time_plus_duree($timestampStart, 1, 'd');
|
||||
//var_dump($jour.' '.$mois.' '.$annee.' '.$timestampStart);
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
//print "nbFerie=".$nbFerie."\n";
|
||||
return $listFeries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to return number of days between two dates (date must be UTC date !)
|
||||
* Example: 2012-01-01 2012-01-02 => 1 if lastday=0, 2 if lastday=1
|
||||
|
|
|
|||
Loading…
Reference in a new issue