Fix yearly events and duplicate recurring events

This commit is contained in:
Laurent Destailleur
2025-12-02 21:33:09 +01:00
parent e60de6525b
commit 10b087e209
2 changed files with 67 additions and 29 deletions

View File

@@ -541,22 +541,29 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
if (!$error) { if (!$error) {
$db->begin(); $db->begin();
$dayinyear = dol_print_date($object->datep, '%m%d');
$dayinmonth = dol_print_date($object->datep, '%d'); $dayinmonth = dol_print_date($object->datep, '%d');
$dayinweek = dol_print_date($object->datep, '%w'); $dayinweek = dol_print_date($object->datep, '%w');
$selectedrecurrulefreq = 'no'; $selectedrecurrulefreq = 'no';
$selectedrecurrulebyyearmonthday = '';
$selectedrecurrulebymonthday = ''; $selectedrecurrulebymonthday = '';
$selectedrecurrulebyday = ''; $selectedrecurrulebyday = '';
$object->recurrule = GETPOSTISSET('recurrulefreq') ? "FREQ=".GETPOST('recurrulefreq', 'alpha') : ""; $object->recurrule = GETPOSTISSET('recurrulefreq') ? "FREQ=".GETPOST('recurrulefreq', 'alpha') : "";
$object->recurrule .= (GETPOST('recurrulefreq', 'alpha') == 'YEARLY') ? "_BYYEARMONTHDAY".((int) $dayinyear) : "";
$object->recurrule .= (GETPOST('recurrulefreq', 'alpha') == 'MONTHLY') ? "_BYMONTHDAY".((int) $dayinmonth) : ""; $object->recurrule .= (GETPOST('recurrulefreq', 'alpha') == 'MONTHLY') ? "_BYMONTHDAY".((int) $dayinmonth) : "";
$object->recurrule .= (GETPOST('recurrulefreq', 'alpha') == 'WEEKLY') ? "_BYDAY".((int) $dayinweek) : ""; $object->recurrule .= (GETPOST('recurrulefreq', 'alpha') == 'WEEKLY') ? "_BYDAY".((int) $dayinweek) : "";
$reg1 = []; $reg1 = [];
$reg2 = []; $reg2 = [];
$reg3 = []; $reg3 = [];
$reg4 = [];
if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg1)) { if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg1)) {
$selectedrecurrulefreq = $reg1[1]; $selectedrecurrulefreq = $reg1[1];
} }
if ($object->recurrule && preg_match('/FREQ=YEARLY.*BYYEARMONTHDAY(\d+)/i', $object->recurrule, $reg4)) {
$selectedrecurrulebyyearmonthday = (int) $reg4[1];
}
if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY(\d+)/i', $object->recurrule, $reg2)) { if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY(\d+)/i', $object->recurrule, $reg2)) {
$selectedrecurrulebymonthday = (int) $reg2[1]; $selectedrecurrulebymonthday = (int) $reg2[1];
} }
@@ -689,10 +696,9 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
if ($res <= 0) { if ($res <= 0) {
// If error // If error
$db->rollback();
$langs->load("errors"); $langs->load("errors");
$error = $langs->trans('ErrorReminderActionCommCreation'); $error++;
setEventMessages($error, null, 'errors'); setEventMessages($langs->trans('ErrorReminderActionCommCreation'), null, 'errors');
$action = 'create'; $action = 'create';
$donotclearsession = 1; $donotclearsession = 1;
break; break;
@@ -707,13 +713,6 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
*/ */
$moreparam .= ($moreparam ? '&' : '').'disabledefaultvalues=1'; $moreparam .= ($moreparam ? '&' : '').'disabledefaultvalues=1';
if ($error) {
$db->rollback();
} else {
$db->commit();
}
// if (!empty($backtopage)) { // if (!empty($backtopage)) {
// dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : '')); // dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
// header("Location: ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : '')); // header("Location: ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
@@ -725,23 +724,24 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
// exit; // exit;
} else { } else {
// If error // If error
$db->rollback();
$langs->load("errors"); $langs->load("errors");
$error = $langs->trans($object->error); $error++;
setEventMessages($error, null, 'errors'); setEventMessages($langs->trans($object->error), null, 'errors');
$action = 'create'; $action = 'create';
$donotclearsession = 1; $donotclearsession = 1;
} }
} else { } else {
$db->rollback(); $error++;
setEventMessages($object->error, $object->errors, 'errors'); setEventMessages($object->error, $object->errors, 'errors');
$action = 'create'; $action = 'create';
$donotclearsession = 1; $donotclearsession = 1;
} }
// Manage other events in case of recurring event
if (!$error && $eventisrecurring) { if (!$error && $eventisrecurring) {
$dayoffset = 0; $dayoffset = 0;
$monthoffset = 0; $monthoffset = 0;
$yearoffset = 0;
// We set first date of recurrence and offsets // We set first date of recurrence and offsets
if ($selectedrecurrulefreq == 'WEEKLY' && !empty($selectedrecurrulebyday)) { if ($selectedrecurrulefreq == 'WEEKLY' && !empty($selectedrecurrulebyday)) {
$firstdatearray = dol_get_first_day_week(GETPOSTINT("apday"), GETPOSTINT("apmonth"), GETPOSTINT("apyear")); $firstdatearray = dol_get_first_day_week(GETPOSTINT("apday"), GETPOSTINT("apmonth"), GETPOSTINT("apyear"));
@@ -749,12 +749,20 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
$datep = dol_time_plus_duree($datep, $selectedrecurrulebyday + 6, 'd');//We begin the week after $datep = dol_time_plus_duree($datep, $selectedrecurrulebyday + 6, 'd');//We begin the week after
$dayoffset = 7; $dayoffset = 7;
$monthoffset = 0; $monthoffset = 0;
$yearoffset = 0;
} elseif ($selectedrecurrulefreq == 'MONTHLY' && !empty($selectedrecurrulebymonthday)) { } elseif ($selectedrecurrulefreq == 'MONTHLY' && !empty($selectedrecurrulebymonthday)) {
$firstday = $selectedrecurrulebymonthday; $firstday = $selectedrecurrulebymonthday;
$firstmonth = GETPOST("apday") > $selectedrecurrulebymonthday ? GETPOSTINT("apmonth") + 1 : GETPOSTINT("apmonth");//We begin the week after $firstmonth = GETPOST("apday") > $selectedrecurrulebymonthday ? GETPOSTINT("apmonth") + 1 : GETPOSTINT("apmonth");//We begin the month after
$datep = dol_mktime($fulldayevent ? 0 : GETPOSTINT("aphour"), $fulldayevent ? 0 : GETPOSTINT("apmin"), $fulldayevent ? 0 : GETPOSTINT("apsec"), $firstmonth, $firstday, GETPOSTINT("apyear"), $tzforfullday ? $tzforfullday : 'tzuserrel'); $datep = dol_mktime($fulldayevent ? 0 : GETPOSTINT("aphour"), $fulldayevent ? 0 : GETPOSTINT("apmin"), $fulldayevent ? 0 : GETPOSTINT("apsec"), $firstmonth, $firstday, GETPOSTINT("apyear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
$dayoffset = 0; $dayoffset = 0;
$monthoffset = 1; $monthoffset = 1;
$yearoffset = 0;
} elseif ($selectedrecurrulefreq == 'YEARLY' && !empty($selectedrecurrulebyyearmonthday)) {
$datep = dol_mktime($fulldayevent ? 0 : GETPOSTINT("aphour"), $fulldayevent ? 0 : GETPOSTINT("apmin"), $fulldayevent ? 0 : GETPOSTINT("apsec"), GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
$datep = dol_time_plus_duree($datep, 1, 'y');//We begin the week after
$dayoffset = 0;
$monthoffset = 0;
$yearoffset = 1;
} else { } else {
$error++; $error++;
} }
@@ -764,6 +772,14 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
// @phan-suppress-next-line PhanPluginSuspiciousParamOrder // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
$datef = dol_time_plus_duree($datef, $deltatime, 'd'); $datef = dol_time_plus_duree($datef, $deltatime, 'd');
// increment date for recurrent events
$datep = dol_time_plus_duree($datep, $dayoffset, 'd');
$datep = dol_time_plus_duree($datep, $monthoffset, 'm'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
$datep = dol_time_plus_duree($datep, $yearoffset, 'y'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
$datef = dol_time_plus_duree($datef, $dayoffset, 'd');
$datef = dol_time_plus_duree($datef, $monthoffset, 'm'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
$datef = dol_time_plus_duree($datef, $yearoffset, 'y'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
while ($datep <= $repeateventlimitdate && !$error) { while ($datep <= $repeateventlimitdate && !$error) {
$finalobject = clone $object; $finalobject = clone $object;
@@ -809,10 +825,9 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
if ($res <= 0) { if ($res <= 0) {
// If error // If error
$db->rollback(); $error++;
$langs->load("errors"); $langs->load("errors");
$error = $langs->trans('ErrorReminderActionCommCreation'); setEventMessages($langs->trans('ErrorReminderActionCommCreation'), null, 'errors');
setEventMessages($error, null, 'errors');
$action = 'create'; $action = 'create';
$donotclearsession = 1; $donotclearsession = 1;
break; break;
@@ -826,15 +841,9 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
$moreparam .= ($moreparam ? '&' : '').'search_filtert='.$object->userownerid; $moreparam .= ($moreparam ? '&' : '').'search_filtert='.$object->userownerid;
*/ */
$moreparam .= ($moreparam ? '&' : '').'disabledefaultvalues=1'; $moreparam .= ($moreparam ? '&' : '').'disabledefaultvalues=1';
if ($error) {
$db->rollback();
} else {
$db->commit();
}
} else { } else {
// If error // If error
$db->rollback(); $error++;
$langs->load("errors"); $langs->load("errors");
$error = $langs->trans($finalobject->error); $error = $langs->trans($finalobject->error);
setEventMessages($error, null, 'errors'); setEventMessages($error, null, 'errors');
@@ -842,7 +851,7 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
$donotclearsession = 1; $donotclearsession = 1;
} }
} else { } else {
$db->rollback(); $error++;
setEventMessages($finalobject->error, $finalobject->errors, 'errors'); setEventMessages($finalobject->error, $finalobject->errors, 'errors');
$action = 'create'; $action = 'create';
$donotclearsession = 1; $donotclearsession = 1;
@@ -856,10 +865,19 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
// increment date for recurrent events // increment date for recurrent events
$datep = dol_time_plus_duree($datep, $dayoffset, 'd'); $datep = dol_time_plus_duree($datep, $dayoffset, 'd');
$datep = dol_time_plus_duree($datep, $monthoffset, 'm'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder $datep = dol_time_plus_duree($datep, $monthoffset, 'm'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
$datep = dol_time_plus_duree($datep, $yearoffset, 'y'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
$datef = dol_time_plus_duree($datef, $dayoffset, 'd'); $datef = dol_time_plus_duree($datef, $dayoffset, 'd');
$datef = dol_time_plus_duree($datef, $monthoffset, 'm'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder $datef = dol_time_plus_duree($datef, $monthoffset, 'm'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
$datef = dol_time_plus_duree($datef, $yearoffset, 'y'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
} }
} }
if ($error) {
$db->rollback();
} else {
$db->commit();
}
if (!empty($backtopage) && !$error) { if (!empty($backtopage) && !$error) {
dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : '')); dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
header("Location: ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : '')); header("Location: ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
@@ -1335,6 +1353,7 @@ $formproject = new FormProjets($db);
$arrayrecurrulefreq = array( $arrayrecurrulefreq = array(
'no' => $langs->trans("OnceOnly"), 'no' => $langs->trans("OnceOnly"),
'YEARLY' => $langs->trans("EveryYear"),
'MONTHLY' => $langs->trans("EveryMonth"), 'MONTHLY' => $langs->trans("EveryMonth"),
'WEEKLY' => $langs->trans("EveryWeek") 'WEEKLY' => $langs->trans("EveryWeek")
// 'DAILY'=>$langs->trans("EveryDay") // 'DAILY'=>$langs->trans("EveryDay")
@@ -1521,9 +1540,11 @@ if ($action == 'create') {
print '<input type="hidden" name="recurid" value="'.(empty($object->recurid) ? '' : $object->recurid).'">'; print '<input type="hidden" name="recurid" value="'.(empty($object->recurid) ? '' : $object->recurid).'">';
$selectedrecurrulefreq = 'no'; $selectedrecurrulefreq = 'no';
$selectedrecurrulebyyearmonthday = '';
$selectedrecurrulebymonthday = ''; $selectedrecurrulebymonthday = '';
$selectedrecurrulebyday = ''; $selectedrecurrulebyday = '';
$object->recurrule = GETPOSTISSET('recurrulefreq') ? "FREQ=".GETPOST('recurrulefreq', 'alpha') : ""; $object->recurrule = GETPOSTISSET('recurrulefreq') ? "FREQ=".GETPOST('recurrulefreq', 'alpha') : "";
$object->recurrule .= GETPOSTISSET('BYYEARMONTHDAY') ? "_BYYEARMONTHDAY".GETPOST('BYYEARMONTHDAY', 'alpha') : "";
$object->recurrule .= GETPOSTISSET('BYMONTHDAY') ? "_BYMONTHDAY".GETPOST('BYMONTHDAY', 'alpha') : ""; $object->recurrule .= GETPOSTISSET('BYMONTHDAY') ? "_BYMONTHDAY".GETPOST('BYMONTHDAY', 'alpha') : "";
$object->recurrule .= GETPOSTISSET('BYDAY') ? "_BYDAY".GETPOST('BYDAY', 'alpha') : ""; $object->recurrule .= GETPOSTISSET('BYDAY') ? "_BYDAY".GETPOST('BYDAY', 'alpha') : "";
@@ -1532,6 +1553,9 @@ if ($action == 'create') {
if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg)) { if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg)) {
$selectedrecurrulefreq = $reg[1]; $selectedrecurrulefreq = $reg[1];
} }
if ($object->recurrule && preg_match('/FREQ=YEARLY.*BYYEARMONTHDAY(\d+)/i', $object->recurrule, $reg)) {
$selectedrecurrulebyyearmonthday = (int) $reg[1];
}
if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY(\d+)/i', $object->recurrule, $reg)) { if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY(\d+)/i', $object->recurrule, $reg)) {
$selectedrecurrulebymonthday = (int) $reg[1]; $selectedrecurrulebymonthday = (int) $reg[1];
} }
@@ -1571,16 +1595,25 @@ if ($action == 'create') {
console.log("reg1: " + "<?php echo $selectedrecurrulefreq; ?>"); console.log("reg1: " + "<?php echo $selectedrecurrulefreq; ?>");
console.log("reg2: " + "<?php echo $selectedrecurrulebymonthday; ?>"); console.log("reg2: " + "<?php echo $selectedrecurrulebymonthday; ?>");
console.log("reg3: " + "<?php echo $selectedrecurrulebyday; ?>"); console.log("reg3: " + "<?php echo $selectedrecurrulebyday; ?>");
console.log("reg4: " + "<?php echo $selectedrecurrulebyyearmonthday; ?>");
console.log("selectedrulefreq: " + "<?php echo $selectedrecurrulefreq; ?>"); console.log("selectedrulefreq: " + "<?php echo $selectedrecurrulefreq; ?>");
if (jQuery("#recurrulefreq").val() == 'MONTHLY') { if (jQuery("#recurrulefreq").val() == 'YEARLY') {
/* jQuery(".repeateventBYYEARMONTHDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */
jQuery(".repeateventlimitdate").css("display", "inline-block");
jQuery(".repeateventBYMONTHDAY").hide();
jQuery(".repeateventBYDAY").hide();
} else if (jQuery("#recurrulefreq").val() == 'MONTHLY') {
/* jQuery(".repeateventBYMONTHDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */ /* jQuery(".repeateventBYMONTHDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */
jQuery(".repeateventlimitdate").css("display", "inline-block"); jQuery(".repeateventlimitdate").css("display", "inline-block");
jQuery(".repeateventBYYEARMONTHDAY").hide();
jQuery(".repeateventBYDAY").hide(); jQuery(".repeateventBYDAY").hide();
} else if (jQuery("#recurrulefreq").val() == 'WEEKLY') { } else if (jQuery("#recurrulefreq").val() == 'WEEKLY') {
jQuery(".repeateventBYYEARMONTHDAY").hide();
jQuery(".repeateventBYMONTHDAY").hide(); jQuery(".repeateventBYMONTHDAY").hide();
/* jQuery(".repeateventBYDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */ /* jQuery(".repeateventBYDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */
jQuery(".repeateventlimitdate").css("display", "inline-block"); jQuery(".repeateventlimitdate").css("display", "inline-block");
} else { } else {
jQuery(".repeateventBYYEARMONTHDAY").hide();
jQuery(".repeateventBYMONTHDAY").hide(); jQuery(".repeateventBYMONTHDAY").hide();
jQuery(".repeateventBYDAY").hide(); jQuery(".repeateventBYDAY").hide();
jQuery(".repeateventlimitdate").hide(); jQuery(".repeateventlimitdate").hide();
@@ -1616,7 +1649,7 @@ if ($action == 'create') {
print '<table class="border centpercent nobottom">'; print '<table class="border centpercent nobottom">';
// Assigned to user // Assigned to user
print '<tr><td class="tdtop nowrap titlefieldcreate"><span>'.$langs->trans("ActionAffectedTo").'</span></td><td>'; print '<tr><td class="nowrap titlefieldcreate"><span>'.$langs->trans("ActionAffectedTo").'</span></td><td>';
$listofuserid = []; $listofuserid = [];
$listofcontactid = []; $listofcontactid = [];
$listofotherid = []; $listofotherid = [];
@@ -2248,7 +2281,7 @@ if ($id > 0 && $action != 'create') {
$listofcontactid = $object->socpeopleassigned; // Contact assigned $listofcontactid = $object->socpeopleassigned; // Contact assigned
$listofotherid = $object->otherassigned; // Other undefined email (not used yet) $listofotherid = $object->otherassigned; // Other undefined email (not used yet)
print '<tr><td class="tdtop nowrap fieldrequired">'.$langs->trans("ActionAssignedTo").'</td><td>'; print '<tr><td class="nowrap fieldrequired">'.$langs->trans("ActionAssignedTo").'</td><td>';
print '<div class="assignedtouser">'; print '<div class="assignedtouser">';
print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, [], 0, '', [], '0', 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid, (int) $caneditdateorowner); print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, [], 0, '', [], '0', 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid, (int) $caneditdateorowner);
print '</div>'; print '</div>';
@@ -2723,6 +2756,9 @@ if ($id > 0 && $action != 'create') {
if (preg_match('/FREQ=MONTHLY_BYMONTHDAY(\d+)/', $object->recurrule, $reg)) { if (preg_match('/FREQ=MONTHLY_BYMONTHDAY(\d+)/', $object->recurrule, $reg)) {
print $langs->trans("EveryMonth").' <span class="opacitymedium small">('.$langs->trans("DayOfMonth").' '.$reg[1].' - '.$langs->trans("Until").' '.dol_print_date($object->recurdateend, 'day').')</span>'; print $langs->trans("EveryMonth").' <span class="opacitymedium small">('.$langs->trans("DayOfMonth").' '.$reg[1].' - '.$langs->trans("Until").' '.dol_print_date($object->recurdateend, 'day').')</span>';
} }
if (preg_match('/FREQ=YEARLY_BYYEARMONTHDAY(\d+)/', $object->recurrule, $reg)) {
print $langs->trans("EveryYear").' <span class="opacitymedium small">('.$langs->trans("DayOfYear").' '.$reg[1].' - '.$langs->trans("Until").' '.dol_print_date($object->recurdateend, 'day').')</span>';
}
print '</td></tr>'; print '</td></tr>';
} }

View File

@@ -171,8 +171,10 @@ OnceOnly=Once only
EveryDay=Every day EveryDay=Every day
EveryWeek=Every week EveryWeek=Every week
EveryMonth=Every month EveryMonth=Every month
EveryYear=Every year
DayOfMonth=Day of month DayOfMonth=Day of month
DayOfWeek=Day of week DayOfWeek=Day of week
DayOfYear=Day of year
DateStartPlusOne=Date start + 1 hour DateStartPlusOne=Date start + 1 hour
SetAllEventsToTodo=Set all events to todo SetAllEventsToTodo=Set all events to todo
SetAllEventsToInProgress=Set all events to in progress SetAllEventsToInProgress=Set all events to in progress