diff --git a/ChangeLog b/ChangeLog index 76709bd8f85..763d8a0920c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,25 +30,23 @@ For users: NEW: PHP 8.1 compatibility NEW: Support for recurring purchase invoices. NEW: #20292 Include German public holidays -NEW: Can show ZATCA QRCode on PDFs -NEW: Can show Swiss QR Code on PDFs +NEW: Can show ZATCA QR-Code on PDFs +NEW: Can show Swiss QR-Code on PDFs NEW: #17123 added ExtraFields for Stock Mouvement -NEW: #20609 : new massaction to assign a sale representatives on a selection of thirdparties +NEW: #20609 new massaction to assign a sale representatives on a selection of thirdparties NEW: #20653 edit discount pourcentage for all lines in one shot NEW: Accept 'auto' for ref of object on import of purchase order/proposal NEW: Accountancy - Add more filters and info on page to bind accounting accounts -NEW: Accountancy - Add subledger account when we generate a transaction with a deposit invoice +NEW: Accountancy - Add subledger account when generate a transaction with a deposit invoice NEW: Accountancy - Add a massaction to preselect an account (customer and supplier list) NEW: ACE Editor is restored at same cursor position after a save. NEW: Add "addMoreActionsButtons" hook to subscription form NEW: Add an option in GUI to show a Quick add button into top menu bar -NEW: Module Recruitment - Add a public page with all list of open job positions. -NEW: Module Recruitment - Add a tab with list of application on the jobposition file. NEW: Add a workflow to auto link contract on a ticket NEW: Add column date of Signature on proposal list NEW: Add column template invoice in invoice list NEW: Add column "Total HT" to products array on document creation card -NEW: ADD configuration for text color of button action +NEW: Add configuration for text color of button action NEW: Add constant to hide categories in TakePos NEW: Add constant to show category description in TakePos NEW: Add constant to show only the products in stock in TakePos @@ -56,7 +54,7 @@ NEW: Add entity filter in exports NEW: Show the event block on recurring invoices #20870 NEW: Add filter "opportunity status" on statistics of projects. NEW: Add firstname, lastname and max number of attendees for module "Event Organization" -NEW: add margin info in proposal and order list +NEW: Add margin info in proposal and order list NEW: Add massaction "Edit Extrafield" for Product NEW: Add more fields to detect duplicate during import of thirdparties NEW: Add option to foce delivery on email for purchase order receipt to yes @@ -67,14 +65,12 @@ NEW: Add possibility with constant MAIN_LOGIN_BADCHARUNAUTHORIZED to define bad NEW: Add private and public notes on tax files. NEW: Add status "Obsolete" to KM articles NEW: Add substitutions "user numbers" -NEW: Add the possibility to add sub-BOMs to BOM NEW: allow a ticket to be automatically marked as read when created from backend. NEW: allow cut&paste as real numeric value to excel NEW: A public form to send a message and create a lead is available NEW: automatically set totally received status in reception NEW: Auto set invoice paid when adding credit not and remain to pay is 0 NEW: Availibility dictionnary has a new column unit and number -NEW: barcode rule to insert product in takepos NEW: Can change value of AWP during the inventory NEW: Can enter price with tax for predefined products on purchase objects NEW: Can filter on a thirdparty on product statistics @@ -90,7 +86,7 @@ NEW: create third-party with contact if not found on public ticket NEW: Default value for MAIN_SECURITY_CSRF_WITH_TOKEN is now 2 (GET are also protected agains CSRF attacks) NEW: deposit payment terms: add field into dictionary admin page to define default percentage of deposit. NEW: Dictionaries - add possibility to manage countries in EEC -NEW: display errors in a message box after generating documents +NEW: Display errors in a message box after generating documents NEW: Display physical and virtual stock of the products when creating OF from a BOM NEW: Display product ref in "Object link" product tab for BOM NEW: Enhance the import. Can use 'auto' for the ref (import of orders) @@ -102,10 +98,13 @@ NEW: leave requests: add field into type dictionary to block request if balance NEW: MAIN_MAIL_AUTOCOPY_TO can accept several email and special keys NEW: MAIN_SEARCH_CAT_OR_BY_DEFAULT const for search by category NEW: Mass action "Close shipments" +NEW: Module BOM - Add tabs for nets Bom +NEW: Module BOM - Add the possibility to add sub-BOMs to BOM +NEW: Module Recruitment - Add a public page with all list of open job positions. +NEW: Module Recruitment - Add a tab with list of application on the jobposition file. NEW: Module website now supports the multicompany module NEW: More mode for THEME_TOPMENU_DISABLE_IMAGE (2, 3, ...) NEW: Add option to move checkbox column as first column on Thirdparty list (only few screens) -NEW: Add tabs for nets Bom NEW: on redirect of page in website module, GET parameters are kept. NEW: optional display warning icons on ticket list NEW: option to default check "notify tier at creation" in ticket module @@ -117,15 +116,15 @@ NEW: Send email to the supplier order contact NEW: New permission to report time on timesheet. NEW: SEPA XML - option to place payment Type Info at Credit transfer Transaction level NEW: Show number of votes into the label of tab "Results" of a survey -NEW: Show product reference in Takepos NEW: Some core tables are created only at module activation NEW: split consumption line on MO NEW: stock filter in reassort lists NEW: stock limit in stock export CSV -NEW: Sub-bom are availables NEW: Supplier order - Show ref supplier of reception in linked object block NEW: support user_modif in order -NEW: TakePos - pagination on search results +NEW: TakePOS - barcode rule to insert product in TakePOS +NEW: TakePOS - pagination on search results +NEW: TakePOS - show product reference NEW: The backup tools has an "lowmemory" option for mysqldump on large database NEW: The 'reposition' class works on ajax constantonoff that make redirects NEW: Thirdparty - Add rules "customer accountancy code" is mandatory to validate invoice @@ -140,7 +139,7 @@ NEW: Added MMK currency (Myanmar Kyat) Modules NEW: Module Partnership Management -NEW: Experimental module Event Organization Management +NEW: Experimental Module Event Organization Management For developers or integrators: @@ -155,7 +154,6 @@ NEW: Suggest a way to run upgrade per entities. NEW: Support html content for multiselect component. NEW: ModuleBuilder - Add tabs view in module builder NEW: ModuleBuilder - More feature that can be modifed after module generation -NEW: Hook getNomUrl available everywhere in tooltip of ref links NEW: Identification of tr is possible with by attribute data-id on some pages NEW: Import with select boxes V2 NEW: Can update rank of invoice, proposal and order lines with API update @@ -182,6 +180,9 @@ NEW: Add a protection into PHPunit to avoid to forget a var_dump NEW: Add datem and type parameters to API to create movements NEW: Add hidden option on contract PDF line to hide qty and price NEW: Option MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND to send last document in mass mailing action + +Hooks: +NEW: Hook getNomUrl available everywhere in tooltip of ref links NEW: Add hooks: selectContactListWhere hook, selectThirdpartyListWhere hook NEW: TakePos - add hooks complete product display NEW: TakePos - add hooks for cart display diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 989c909487b..ed25d89db67 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -409,9 +409,13 @@ if (empty($reshook) && $action == 'add') { $error++; } + + if (!$error) { $db->begin(); + + // Creation of action/event $idaction = $object->create($user); @@ -474,15 +478,15 @@ if (empty($reshook) && $action == 'add') { $db->commit(); } - if (!empty($backtopage)) { - dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : '')); - header("Location: ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : '')); - } elseif ($idaction) { - header("Location: ".DOL_URL_ROOT.'/comm/action/card.php?id='.$idaction.($moreparam ? '&'.$moreparam : '')); - } else { - header("Location: ".DOL_URL_ROOT.'/comm/action/index.php'.($moreparam ? '?'.$moreparam : '')); - } - exit; + // if (!empty($backtopage)) { + // dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : '')); + // header("Location: ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : '')); + // } elseif ($idaction) { + // header("Location: ".DOL_URL_ROOT.'/comm/action/card.php?id='.$idaction.($moreparam ? '&'.$moreparam : '')); + // } else { + // header("Location: ".DOL_URL_ROOT.'/comm/action/index.php'.($moreparam ? '?'.$moreparam : '')); + // } + // exit; } else { // If error $db->rollback(); @@ -496,6 +500,151 @@ if (empty($reshook) && $action == 'add') { setEventMessages($object->error, $object->errors, 'errors'); $action = 'create'; $donotclearsession = 1; } + + $selectedrecurrulefreq = 'no'; + $selectedrecurrulebymonthday = ''; + $selectedrecurrulebyday = ''; + $object->recurrule = GETPOSTISSET('recurrulefreq') ? "FREQ=".GETPOST('recurrulefreq', 'alpha') : ""; + $object->recurrule .= GETPOSTISSET('BYMONTHDAY') ? "_BYMONTHDAY".GETPOST('BYMONTHDAY', 'alpha') : ""; + $object->recurrule .= GETPOSTISSET('BYDAY') ? "_BYDAY".GETPOST('BYDAY', 'alpha') : ""; + + if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg1)) { + $selectedrecurrulefreq = $reg1[1]; + } + if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY(\d+)/i', $object->recurrule, $reg2)) { + $selectedrecurrulebymonthday = $reg2[1]; + } + if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i', $object->recurrule, $reg3)) { + $selectedrecurrulebyday = $reg3[1]; + } + + // If event is recurrent + $userepeatevent = ($conf->global->MAIN_FEATURES_LEVEL == 2 ? 1 : 0); + if ($userepeatevent && !empty($selectedrecurrulefreq) && $selectedrecurrulefreq != 'no') { + // We set first date of recurrence and offsets + if ($selectedrecurrulefreq == 'WEEKLY' && !empty($selectedrecurrulebyday)) { + $firstdatearray = dol_get_first_day_week(GETPOST("apday", 'int'), GETPOST("apmonth", 'int'), GETPOST("apyear", 'int')); + $datep = dol_mktime($fulldayevent ? '00' : GETPOST("aphour", 'int'), $fulldayevent ? '00' : GETPOST("apmin", 'int'), $fulldayevent ? '00' : GETPOST("apsec", 'int'), $firstdatearray['month'], $firstdatearray['first_day'], $firstdatearray['year'], $tzforfullday ? $tzforfullday : 'tzuser'); + $datep = dol_time_plus_duree($datep, $selectedrecurrulebyday + 6, 'd');//We begin the week after + $dayoffset = 7; + $monthoffset = 0; + } elseif ($selectedrecurrulefreq == 'MONTHLY' && !empty($selectedrecurrulebymonthday)) { + $firstday = $selectedrecurrulebymonthday; + $firstmonth = GETPOST("apday") > $selectedrecurrulebymonthday ? GETPOST("apmonth", 'int') + 1 : GETPOST("apmonth", 'int');//We begin the week after + $datep = dol_mktime($fulldayevent ? '00' : GETPOST("aphour", 'int'), $fulldayevent ? '00' : GETPOST("apmin", 'int'), $fulldayevent ? '00' : GETPOST("apsec", 'int'), $firstmonth, $firstday, GETPOST("apyear", 'int'), $tzforfullday ? $tzforfullday : 'tzuser'); + $dayoffset = 0; + $monthoffset = 1; + } else { + $error++; + } + // End date + $repeateventlimitdate = dol_mktime('23', '59', '59', GETPOSTISSET("limitmonth", 'int') ? GETPOST("limitmonth", 'int') : 01, GETPOSTISSET("limitday", 'int') ? GETPOST("limitday", 'int') : 01, GETPOSTISSET("limityear", 'int') && GETPOST("limityear", 'int') < 2100 ? GETPOST("limityear", 'int') : 2100, $tzforfullday ? $tzforfullday : 'tzuser'); + // Set date of end of event + $deltatime = num_between_day($object->datep, $datep); + $datef = dol_time_plus_duree($datef, $deltatime, 'd'); + + while ($datep <= $repeateventlimitdate && !$error) { + $finalobject = clone $object; + + + $finalobject->datep = $datep; + $finalobject->datef = $datef; + // Creation of action/event + $idaction = $finalobject->create($user); + + if ($idaction > 0) { + if (!$finalobject->error) { + // Category association + $categories = GETPOST('categories', 'array'); + $finalobject->setCategories($categories); + + unset($_SESSION['assignedtouser']); + + $moreparam = ''; + if ($user->id != $finalobject->userownerid) { + $moreparam = "filtert=-1"; // We force to remove filter so created record is visible when going back to per user view. + } + + // Create reminders + if ($addreminder == 'on') { + $actionCommReminder = new ActionCommReminder($db); + + $dateremind = dol_time_plus_duree($datep, -$offsetvalue, $offsetunit); + + $actionCommReminder->dateremind = $dateremind; + $actionCommReminder->typeremind = $remindertype; + $actionCommReminder->offsetunit = $offsetunit; + $actionCommReminder->offsetvalue = $offsetvalue; + $actionCommReminder->status = $actionCommReminder::STATUS_TODO; + $actionCommReminder->fk_actioncomm = $finalobject->id; + if ($remindertype == 'email') { + $actionCommReminder->fk_email_template = $modelmail; + } + + // the notification must be created for every user assigned to the event + foreach ($finalobject->userassigned as $userassigned) { + $actionCommReminder->fk_user = $userassigned['id']; + $res = $actionCommReminder->create($user); + + if ($res <= 0) { + // If error + $db->rollback(); + $langs->load("errors"); + $error = $langs->trans('ErrorReminderActionCommCreation'); + setEventMessages($error, null, 'errors'); + $action = 'create'; $donotclearsession = 1; + break; + } + } + } + + // Modify $moreparam so we are sure to see the event we have just created, whatever are the default value of filter on next page. + /*$moreparam .= ($moreparam ? '&' : '').'search_actioncode=0'; + $moreparam .= ($moreparam ? '&' : '').'search_status=-1'; + $moreparam .= ($moreparam ? '&' : '').'search_filtert='.$object->userownerid; + */ + $moreparam .= ($moreparam ? '&' : '').'disabledefaultvalues=1'; + + if ($error) { + $db->rollback(); + } else { + $db->commit(); + } + } else { + // If error + $db->rollback(); + $langs->load("errors"); + $error = $langs->trans($finalobject->error); + setEventMessages($error, null, 'errors'); + $action = 'create'; $donotclearsession = 1; + } + } else { + $db->rollback(); + setEventMessages($finalobject->error, $finalobject->errors, 'errors'); + $action = 'create'; $donotclearsession = 1; + } + + // If event is not recurrent, we stop here + if (!($userepeatevent && GETPOSTISSET('recurrulefreq') && GETPOST('recurrulefreq') != 'no' && GETPOSTISSET("limityear") && GETPOSTISSET("limitmonth") && GETPOSTISSET("limitday"))) { + break; + } + + // increment date for recurrent events + $datep = dol_time_plus_duree($datep, $dayoffset, 'd'); + $datep = dol_time_plus_duree($datep, $monthoffset, 'm'); + $datef = dol_time_plus_duree($datef, $dayoffset, 'd'); + $datef = dol_time_plus_duree($datef, $monthoffset, 'm'); + } + } + if (!empty($backtopage) && !$error) { + dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : '')); + header("Location: ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : '')); + } elseif ($idaction) { + header("Location: ".DOL_URL_ROOT.'/comm/action/card.php?id='.$idaction.($moreparam ? '&'.$moreparam : '')); + } else { + header("Location: ".DOL_URL_ROOT.'/comm/action/index.php'.($moreparam ? '?'.$moreparam : '')); + } + exit; } } @@ -916,10 +1065,11 @@ $formproject = new FormProjets($db); $arrayrecurrulefreq = array( 'no'=>$langs->trans("OnceOnly"), 'MONTHLY'=>$langs->trans("EveryMonth"), - 'WEEKLY'=>$langs->trans("EveryWeek"), - //'DAYLY'=>$langs->trans("EveryDay") + 'WEEKLY'=>$langs->trans("EveryWeek") + // 'DAILY'=>$langs->trans("EveryDay") ); + $help_url = 'EN:Module_Agenda_En|FR:Module_Agenda|ES:M&omodulodulo_Agenda'; llxHeader('', $langs->trans("Agenda"), $help_url); @@ -1037,20 +1187,31 @@ if ($action == 'create') { print '        
'; print img_picto($langs->trans("Recurrence"), 'recurring', 'class="paddingright2"'); print ''; + $selectedrecurrulefreq = 'no'; $selectedrecurrulebymonthday = ''; $selectedrecurrulebyday = ''; + $object->recurrule = GETPOSTISSET('recurrulefreq') ? "FREQ=".GETPOST('recurrulefreq', 'alpha') : ""; + $object->recurrule .= GETPOSTISSET('BYMONTHDAY') ? "_BYMONTHDAY".GETPOST('BYMONTHDAY', 'alpha') : ""; + $object->recurrule .= GETPOSTISSET('BYDAY') ? "_BYDAY".GETPOST('BYDAY', 'alpha') : ""; + + $reg = array(); if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg)) { $selectedrecurrulefreq = $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 = $reg[1]; } if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i', $object->recurrule, $reg)) { $selectedrecurrulebyday = $reg[1]; } + print $form->selectarray('recurrulefreq', $arrayrecurrulefreq, $selectedrecurrulefreq, 0, 0, 0, '', 0, 0, 0, '', 'marginrightonly'); + // print ''; + // For recursive event + + // If recurrulefreq is MONTHLY print ''; //print ''; } @@ -1545,64 +1721,64 @@ if ($id > 0) { print ''.$langs->trans("Date").'fulldayevent ? ' checked' : '').'>'; print ''; - // Recurring event - $userepeatevent = ($conf->global->MAIN_FEATURES_LEVEL == 2 ? 1 : 0); - if ($userepeatevent) { - // Repeat - //print ''; - print '        
'; - print img_picto($langs->trans("Recurrence"), 'recurring', 'class="paddingright2"'); - print ''; - $selectedrecurrulefreq = 'no'; - $selectedrecurrulebymonthday = ''; - $selectedrecurrulebyday = ''; - if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg)) { - $selectedrecurrulefreq = $reg[1]; - } - if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY=(\d+)/i', $object->recurrule, $reg)) { - $selectedrecurrulebymonthday = $reg[1]; - } - if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i', $object->recurrule, $reg)) { - $selectedrecurrulebyday = $reg[1]; - } - print $form->selectarray('recurrulefreq', $arrayrecurrulefreq, $selectedrecurrulefreq, 0, 0, 0, '', 0, 0, 0, '', 'marginrightonly'); - // If recurrulefreq is MONTHLY - print ''; - // If recurrulefreq is WEEKLY - print ''; - print ''; - print '
'; - //print ''; - } + // // Recurring event + // $userepeatevent = ($conf->global->MAIN_FEATURES_LEVEL == 2 ? 1 : 0); + // if ($userepeatevent) { + // // Repeat + // //print ''; + // print '        
'; + // print img_picto($langs->trans("Recurrence"), 'recurring', 'class="paddingright2"'); + // print ''; + // $selectedrecurrulefreq = 'no'; + // $selectedrecurrulebymonthday = ''; + // $selectedrecurrulebyday = ''; + // if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg)) { + // $selectedrecurrulefreq = $reg[1]; + // } + // if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY=(\d+)/i', $object->recurrule, $reg)) { + // $selectedrecurrulebymonthday = $reg[1]; + // } + // if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i', $object->recurrule, $reg)) { + // $selectedrecurrulebyday = $reg[1]; + // } + // print $form->selectarray('recurrulefreq', $arrayrecurrulefreq, $selectedrecurrulefreq, 0, 0, 0, '', 0, 0, 0, '', 'marginrightonly'); + // // If recurrulefreq is MONTHLY + // print ''; + // // If recurrulefreq is WEEKLY + // print ''; + // print ''; + // print '
'; + // //print ''; + // } print ''; // Date start - end diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 8e59e688e2c..61a603f48bd 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -10411,6 +10411,7 @@ function dolGetStatus($statusLabel = '', $statusLabelShort = '', $html = '', $st * 'cancel-btn-label' => '', // Overide label of cancel button, if empty default label use "CloseDialog" lang key * 'content' => '', // Overide text of content, if empty default content use "ConfirmBtnCommonContent" lang key * 'modal' => true, // true|false to display dialog as a modal (with dark background) + * 'isDropDrown' => false, // true|false to display dialog as a dropdown (with dark background) * ], * ] * // phpcs:enable @@ -10420,12 +10421,16 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = { global $hookmanager, $action, $object, $langs; - $class = 'butAction'; - if ($actionType == 'danger' || $actionType == 'delete') { - $class = 'butActionDelete'; - if (!empty($url) && strpos($url, 'token=') === false) $url .= '&token='.newToken(); + //var_dump($params); + if ($params['isDropdown']) + $class = "dropdown-item"; + else { + $class = 'butAction'; + if ($actionType == 'danger' || $actionType == 'delete') { + $class = 'butActionDelete'; + if (!empty($url) && strpos($url, 'token=') === false) $url .= '&token='.newToken(); + } } - $attr = array( 'class' => $class, 'href' => empty($url) ? '' : $url, diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index b8f9ffa857b..9dffacf774c 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -136,7 +136,7 @@ AgendaUrlOptionsNotAdmin=logina=!%s to restrict output to actions not own AgendaUrlOptions4=logint=%s to restrict output to actions assigned to user %s (owner and others). AgendaUrlOptionsProject=project=__PROJECT_ID__ to restrict output to actions linked to project __PROJECT_ID__. AgendaUrlOptionsNotAutoEvent=notactiontype=systemauto to exclude automatic events. -AgendaUrlOptionsIncludeHolidays=includeholidays=1 to include events of holidays. +AgendaUrlOptionsIncludeHolidays=includeholidays=1 to include events of holidays. AgendaShowBirthdayEvents=Birthdays of contacts AgendaHideBirthdayEvents=Hide birthdays of contacts Busy=Busy @@ -160,6 +160,7 @@ DateActionBegin=Start event date ConfirmCloneEvent=Are you sure you want to clone the event %s? RepeatEvent=Repeat event OnceOnly=Once only +EveryDay=Every day EveryWeek=Every week EveryMonth=Every month DayOfMonth=Day of month @@ -175,3 +176,4 @@ AddReminder=Create an automatic reminder notification for this event ErrorReminderActionCommCreation=Error creating the reminder notification for this event BrowserPush=Browser Popup Notification ActiveByDefault=Enabled by default +Until=until \ No newline at end of file diff --git a/htdocs/langs/fr_FR/agenda.lang b/htdocs/langs/fr_FR/agenda.lang index 65e06587e88..a589163dfad 100644 --- a/htdocs/langs/fr_FR/agenda.lang +++ b/htdocs/langs/fr_FR/agenda.lang @@ -96,7 +96,7 @@ PRODUCT_MODIFYInDolibarr=Produit %s modifié PRODUCT_DELETEInDolibarr=Produit%ssupprimé HOLIDAY_CREATEInDolibarr=Demande de congé %s créée HOLIDAY_MODIFYInDolibarr=Demande de congé %s modifiée -HOLIDAY_APPROVEInDolibarr=Demande de congé %s approuvée +HOLIDAY_APPROVEInDolibarr=Demande de congé %s approuvée HOLIDAY_VALIDATEInDolibarr=Demande de congé %s validée HOLIDAY_DELETEInDolibarr=Demande de congé %s supprimée EXPENSE_REPORT_CREATEInDolibarr=Note de frais %s créée @@ -157,6 +157,7 @@ DateActionBegin=Date début événément ConfirmCloneEvent=Êtes-vous sûr de vouloir cloner cet événement %s ? RepeatEvent=Evénement répétitif OnceOnly=Une seule fois +EveryDay=Chaque jour EveryWeek=Chaque semaine EveryMonth=Chaque mois DayOfMonth=Jour du mois @@ -172,3 +173,4 @@ AddReminder=Créer une notification de rappel automatique pour cet événement ErrorReminderActionCommCreation=Erreur lors de la création de la notification de rappel pour cet événement BrowserPush=Notification par Popup navigateur ActiveByDefault=Activé par défaut +Until=jusqu'à diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index c246b73e816..081057f5f06 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -1331,50 +1331,56 @@ if ($action == 'create' && $user->rights->projet->creer) { } } - // Add button to create objects from project + if (!empty($conf->global->PROJECT_SHOW_CREATE_OBJECT_BUTTON)) { + print'"; } - // Clone if ($user->rights->projet->creer) { if ($userWrite > 0) {