From f48c9903757771fc3897bbf4b5044eda1db70598 Mon Sep 17 00:00:00 2001 From: Quatadah Nasdami Date: Thu, 23 Jun 2022 17:47:56 +0200 Subject: [PATCH 001/205] adding dropdown menu in case of a lot of buttons in project --- htdocs/projet/card.php | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 0cfe126d69b..3193c410679 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -1318,46 +1318,52 @@ if ($action == 'create' && $user->rights->projet->creer) { // Add button to create objects from project if (!empty($conf->global->PROJECT_SHOW_CREATE_OBJECT_BUTTON)) { + print''; + //print''; } // Clone From 259224c3bef96b19f4d63a88d3502800b4bf6b8f Mon Sep 17 00:00:00 2001 From: Faustin Date: Sat, 2 Jul 2022 18:48:35 +0200 Subject: [PATCH 002/205] NEW : Recurrent events on agenda v1 --- htdocs/comm/action/card.php | 322 +++++++++++++++++---------------- htdocs/langs/en_US/agenda.lang | 4 +- htdocs/langs/fr_FR/agenda.lang | 4 +- 3 files changed, 177 insertions(+), 153 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 351ab9212bc..ac943350819 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -409,93 +409,130 @@ if (empty($reshook) && $action == 'add') { $error++; } + + if (!$error) { $db->begin(); - // Creation of action/event - $idaction = $object->create($user); + $dayoffset = 0; + $monthoffset = 0; - if ($idaction > 0) { - if (!$object->error) { - // Category association - $categories = GETPOST('categories', 'array'); - $object->setCategories($categories); + // If event is recurrent + $userepeatevent = ($conf->global->MAIN_FEATURES_LEVEL == 2 ? 1 : 0); + if ($userepeatevent && GETPOSTISSET('recurrulefreq') && GETPOST('recurrulefreq') != 'no' && GETPOSTISSET("limityear") && GETPOSTISSET("limitmonth") && GETPOSTISSET("limitday")) { + $repeateventlimitdate = dol_mktime('23', '59', '59', GETPOST("limitmonth", 'int'), GETPOST("limitday", 'int'), GETPOST("limityear", 'int') < 2100 ? GETPOST("limityear", 'int') : 2100, $tzforfullday ? $tzforfullday : 'tzuser'); + if (GETPOST('recurrulefreq') == 'DAILY') { + $dayoffset = 1; + } elseif (GETPOST('recurrulefreq') == 'WEEKLY') { + $dayoffset = 7; + } elseif (GETPOST('recurrulefreq') == 'MONTHLY') { + $monthoffset = 1; + } + } else { // If event is not recurrent, limit date is the date of the event + $repeateventlimitdate = $datep; + } - unset($_SESSION['assignedtouser']); + while ($datep <= $repeateventlimitdate) { + $finalobject = clone $object; - $moreparam = ''; - if ($user->id != $object->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); + $finalobject->datep = $datep; + $finalobject->datef = $datef; + // Creation of action/event + $idaction = $finalobject->create($user); - $dateremind = dol_time_plus_duree($datep, -$offsetvalue, $offsetunit); + if ($idaction > 0) { + if (!$finalobject->error) { + // Category association + $categories = GETPOST('categories', 'array'); + $finalobject->setCategories($categories); - $actionCommReminder->dateremind = $dateremind; - $actionCommReminder->typeremind = $remindertype; - $actionCommReminder->offsetunit = $offsetunit; - $actionCommReminder->offsetvalue = $offsetvalue; - $actionCommReminder->status = $actionCommReminder::STATUS_TODO; - $actionCommReminder->fk_actioncomm = $object->id; - if ($remindertype == 'email') { - $actionCommReminder->fk_email_template = $modelmail; + 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. } - // the notification must be created for every user assigned to the event - foreach ($object->userassigned as $userassigned) { - $actionCommReminder->fk_user = $userassigned['id']; - $res = $actionCommReminder->create($user); + // Create reminders + if ($addreminder == 'on') { + $actionCommReminder = new ActionCommReminder($db); - if ($res <= 0) { - // If error - $db->rollback(); - $langs->load("errors"); - $error = $langs->trans('ErrorReminderActionCommCreation'); - setEventMessages($error, null, 'errors'); - $action = 'create'; $donotclearsession = 1; - break; + $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'; + // 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) { + if ($error) { + $db->rollback(); + } else { + $db->commit(); + } + } else { + // If error $db->rollback(); - } else { - $db->commit(); + $langs->load("errors"); + $error = $langs->trans($finalobject->error); + setEventMessages($error, null, 'errors'); + $action = 'create'; $donotclearsession = 1; } - - 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(); - $langs->load("errors"); - $error = $langs->trans($object->error); - setEventMessages($error, null, 'errors'); + setEventMessages($finalobject->error, $finalobject->errors, 'errors'); $action = 'create'; $donotclearsession = 1; } - } else { - $db->rollback(); - setEventMessages($object->error, $object->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)) { + 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; } } @@ -917,9 +954,10 @@ $arrayrecurrulefreq = array( 'no'=>$langs->trans("OnceOnly"), 'MONTHLY'=>$langs->trans("EveryMonth"), 'WEEKLY'=>$langs->trans("EveryWeek"), - //'DAYLY'=>$langs->trans("EveryDay") + 'DAILY'=>$langs->trans("EveryDay") ); + $help_url = 'EN:Module_Agenda_En|FR:Module_Agenda|ES:M&omodulodulo_Agenda'; llxHeader('', $langs->trans("Agenda"), $help_url); @@ -1038,44 +1076,26 @@ if ($action == 'create') { 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 ''; - } + // // 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/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index 272ec22df5c..410537acbc1 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -135,7 +135,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 @@ -159,6 +159,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 @@ -174,3 +175,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'à From 572f1f0feefc1c6e2d7a9474a414282d10a4d4db Mon Sep 17 00:00:00 2001 From: Faustin Date: Thu, 7 Jul 2022 00:07:15 +0200 Subject: [PATCH 003/205] NEW : Recurrent events on agenda v2 --- htdocs/comm/action/card.php | 351 ++++++++++++++++++++++++++---------- 1 file changed, 253 insertions(+), 98 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index ac943350819..6701b8e367f 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -414,117 +414,229 @@ if (empty($reshook) && $action == 'add') { if (!$error) { $db->begin(); - $dayoffset = 0; - $monthoffset = 0; + + + // Creation of action/event + $idaction = $object->create($user); + + if ($idaction > 0) { + if (!$object->error) { + // Category association + $categories = GETPOST('categories', 'array'); + $object->setCategories($categories); + + unset($_SESSION['assignedtouser']); + + $moreparam = ''; + if ($user->id != $object->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 = $object->id; + if ($remindertype == 'email') { + $actionCommReminder->fk_email_template = $modelmail; + } + + // the notification must be created for every user assigned to the event + foreach ($object->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(); + } + + // 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(); + $langs->load("errors"); + $error = $langs->trans($object->error); + setEventMessages($error, null, 'errors'); + $action = 'create'; $donotclearsession = 1; + } + } else { + $db->rollback(); + 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 && GETPOSTISSET('recurrulefreq') && GETPOST('recurrulefreq') != 'no' && GETPOSTISSET("limityear") && GETPOSTISSET("limitmonth") && GETPOSTISSET("limitday")) { - $repeateventlimitdate = dol_mktime('23', '59', '59', GETPOST("limitmonth", 'int'), GETPOST("limitday", 'int'), GETPOST("limityear", 'int') < 2100 ? GETPOST("limityear", 'int') : 2100, $tzforfullday ? $tzforfullday : 'tzuser'); - if (GETPOST('recurrulefreq') == 'DAILY') { - $dayoffset = 1; - } elseif (GETPOST('recurrulefreq') == 'WEEKLY') { + 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; - } elseif (GETPOST('recurrulefreq') == 'MONTHLY') { + $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++; } - } else { // If event is not recurrent, limit date is the date of the event - $repeateventlimitdate = $datep; - } + // 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) { - $finalobject = clone $object; + while ($datep <= $repeateventlimitdate && !$error) { + $finalobject = clone $object; - $finalobject->datep = $datep; - $finalobject->datef = $datef; - // Creation of action/event - $idaction = $finalobject->create($user); + $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); + if ($idaction > 0) { + if (!$finalobject->error) { + // Category association + $categories = GETPOST('categories', 'array'); + $finalobject->setCategories($categories); - unset($_SESSION['assignedtouser']); + 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; + $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. } - // 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); + // Create reminders + if ($addreminder == 'on') { + $actionCommReminder = new ActionCommReminder($db); - if ($res <= 0) { - // If error - $db->rollback(); - $langs->load("errors"); - $error = $langs->trans('ErrorReminderActionCommCreation'); - setEventMessages($error, null, 'errors'); - $action = 'create'; $donotclearsession = 1; - break; + $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'; + // 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(); + if ($error) { + $db->rollback(); + } else { + $db->commit(); + } } else { - $db->commit(); + // If error + $db->rollback(); + $langs->load("errors"); + $error = $langs->trans($finalobject->error); + setEventMessages($error, null, 'errors'); + $action = 'create'; $donotclearsession = 1; } } else { - // If error $db->rollback(); - $langs->load("errors"); - $error = $langs->trans($finalobject->error); - setEventMessages($error, null, 'errors'); + setEventMessages($finalobject->error, $finalobject->errors, '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; - } + // 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'); + // 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)) { + 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) { @@ -1075,35 +1187,78 @@ 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') : ""; + + 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]; + } + print $form->selectarray('recurrulefreq', $arrayrecurrulefreq, $selectedrecurrulefreq, 0, 0, 0, '', 0, 0, 0, '', 'marginrightonly'); + // print ''; // For recursive event + + + // If recurrulefreq is MONTHLY + print ''; + // If recurrulefreq is WEEKLY + print ''; + // limit date $repeateventlimitdate = $repeateventlimitdate ? $repeateventlimitdate : ''; print ''; - print ''; + }); + '; print '
'; //print ''; } From 0da4360b9fb77db7130aa514077aa8aac8025ec5 Mon Sep 17 00:00:00 2001 From: Quatadah Nasdami Date: Mon, 11 Jul 2022 17:30:11 +0200 Subject: [PATCH 004/205] almost done --- htdocs/core/lib/functions.lib.php | 17 +++++++++------ htdocs/projet/card.php | 36 +++++++++++++++---------------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index bf41b5a624a..e7c0244387f 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -10343,6 +10343,7 @@ function dolGetStatus($statusLabel = '', $statusLabelShort = '', $html = '', $st * @param string $actionType default, delete, danger * @param string $url the url for link * @param string $id attribute id of button + * @param bboolean $isDropdown is dropdown button * @param int $userRight user action right * // phpcs:disable * @param array $params = [ // Various params for future : recommended rather than adding more function arguments @@ -10363,16 +10364,20 @@ function dolGetStatus($statusLabel = '', $statusLabelShort = '', $html = '', $st * // phpcs:enable * @return string html button */ -function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = '', $id = '', $userRight = 1, $params = array()) +function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = '', $id = '', $isDropdown = false, $userRight = 1, $params = array()) { 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($isDropdown); + if ($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/projet/card.php b/htdocs/projet/card.php index 3193c410679..0864a5b53f6 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -1316,56 +1316,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'"; + print ""; } - // Clone if ($user->rights->projet->creer) { if ($userWrite > 0) { From 8c5f4d5ac639ca20782be0a932aba28d9d1089b7 Mon Sep 17 00:00:00 2001 From: Chl Date: Fri, 15 Jul 2022 00:04:00 +0200 Subject: [PATCH 005/205] FIX #20476 migration postgresql 13.0.x to 14.0.x packaging type Taken from ff35bf8d47650b453f7224ced7857e2bbc53ecd5 --- htdocs/install/mysql/migration/13.0.0-14.0.0.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql index 2ec43548bb6..44b1a6b5185 100644 --- a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql +++ b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql @@ -85,7 +85,8 @@ UPDATE llx_const set value = __ENCRYPT('eldy')__ WHERE __DECRYPT('value')__ = 'c DELETE FROM llx_user_param where param = 'MAIN_THEME' and value in ('auguria', 'amarok', 'cameleo'); ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging real DEFAULT NULL; -ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN packaging real DEFAULT NULL; +-- VMYSQL4.3 ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN packaging real DEFAULT NULL; +-- VPGSQL8.2 ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN packaging real DEFAULT NULL USING packaging::real; -- For v14 From 87b80912df6308562e68c50a2c37fe3bc8ba2a42 Mon Sep 17 00:00:00 2001 From: Faustin Date: Tue, 19 Jul 2022 20:35:03 +0200 Subject: [PATCH 006/205] merge --- htdocs/comm/action/card.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index eef679b7141..8d1f75c4990 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -1195,15 +1195,16 @@ if ($action == 'create') { $object->recurrule .= GETPOSTISSET('BYMONTHDAY') ? "_BYMONTHDAY".GETPOST('BYMONTHDAY', 'alpha') : ""; $object->recurrule .= GETPOSTISSET('BYDAY') ? "_BYDAY".GETPOST('BYDAY', 'alpha') : ""; - $reg1 = array(); - if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg1)) { - $selectedrecurrulefreq = $reg1[1]; + + $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, $reg2)) { - $selectedrecurrulebymonthday = $reg2[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, $reg3)) { - $selectedrecurrulebyday = $reg3[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'); From 1f9afaadb1df40589d622570ef7199b9a64a8b1f Mon Sep 17 00:00:00 2001 From: Faustin Date: Wed, 20 Jul 2022 13:08:28 +0200 Subject: [PATCH 007/205] Removing daily event for the moment --- htdocs/comm/action/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 8d1f75c4990..1ab81b01bd7 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -1065,8 +1065,8 @@ $formproject = new FormProjets($db); $arrayrecurrulefreq = array( 'no'=>$langs->trans("OnceOnly"), 'MONTHLY'=>$langs->trans("EveryMonth"), - 'WEEKLY'=>$langs->trans("EveryWeek"), - 'DAILY'=>$langs->trans("EveryDay") + 'WEEKLY'=>$langs->trans("EveryWeek") + // 'DAILY'=>$langs->trans("EveryDay") ); From 9209c83054b909eeaaa4c8ce48ea868c3e907aa0 Mon Sep 17 00:00:00 2001 From: marc Date: Sun, 24 Jul 2022 14:49:57 +0200 Subject: [PATCH 008/205] Fix deleting logo/photo doesn't delete file from disk --- htdocs/societe/card.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index b6c483fc026..b20a00e0c4d 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -554,9 +554,7 @@ if (empty($reshook)) { } //var_dump($object->array_languages);exit; - if (GETPOST('deletephoto')) { - $object->logo = ''; - } elseif (!empty($_FILES['photo']['name'])) { + if (!empty($_FILES['photo']['name'])) { $object->logo = dol_sanitizeFileName($_FILES['photo']['name']); } From d8dfe360ecfab25fef8e78b6db926964c5209cc0 Mon Sep 17 00:00:00 2001 From: marc Date: Sun, 24 Jul 2022 15:03:32 +0200 Subject: [PATCH 009/205] Fix #21518 delete old logo/photo from disk when load a new logo/photo --- htdocs/societe/card.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index b20a00e0c4d..0436a1160a7 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -555,6 +555,7 @@ if (empty($reshook)) { //var_dump($object->array_languages);exit; if (!empty($_FILES['photo']['name'])) { + $current_logo = $object->logo; $object->logo = dol_sanitizeFileName($_FILES['photo']['name']); } @@ -784,6 +785,13 @@ if (empty($reshook)) { } if ($file_OK) { if (image_format_supported($_FILES['photo']['name']) > 0) { + if($current_logo != $object->logo) { + $fileimg = $dir.'/'.$current_logo; + $dirthumbs = $dir.'/thumbs'; + dol_delete_file($fileimg); + dol_delete_dir_recursive($dirthumbs); + } + dol_mkdir($dir); if (@is_dir($dir)) { From bd88c9e0cd0d0361ffd6aa91036d487fbbaa221a Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Sun, 24 Jul 2022 13:15:39 +0000 Subject: [PATCH 010/205] Fixing style errors. --- htdocs/societe/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 0436a1160a7..c8370452d4f 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -785,11 +785,11 @@ if (empty($reshook)) { } if ($file_OK) { if (image_format_supported($_FILES['photo']['name']) > 0) { - if($current_logo != $object->logo) { + if ($current_logo != $object->logo) { $fileimg = $dir.'/'.$current_logo; $dirthumbs = $dir.'/thumbs'; dol_delete_file($fileimg); - dol_delete_dir_recursive($dirthumbs); + dol_delete_dir_recursive($dirthumbs); } dol_mkdir($dir); From 266b0213a5286fdb8841283b22f835082c44b0f4 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Mon, 25 Jul 2022 13:18:03 +0200 Subject: [PATCH 011/205] fix: filter Status Not applicable into is not correctly manage on Agenda list --- htdocs/comm/action/index.php | 10 ++++++---- htdocs/comm/action/peruser.php | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 419d98dbef8..9b451a47659 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -109,7 +109,7 @@ $month = GETPOST("month", "int") ?GETPOST("month", "int") : date("m"); $week = GETPOST("week", "int") ?GETPOST("week", "int") : date("W"); $day = GETPOST("day", "int") ?GETPOST("day", "int") : date("d"); $pid = GETPOST("search_projectid", "int", 3) ? GETPOST("search_projectid", "int", 3) : GETPOST("projectid", "int", 3); -$status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo' +$status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo', 'na' or -1 $type = GETPOSTISSET("search_type", 'aZ09') ? GETPOST("search_type", 'aZ09') : GETPOST("type", 'aZ09'); $maxprint = GETPOSTISSET("maxprint") ? GETPOST("maxprint", 'int') : $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW; $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') @@ -760,12 +760,14 @@ if ($type) { if ($status == '0') { $sql .= " AND a.percent = 0"; } -if ($status == '-1') { +if ($status == '-1' || $status == 'na') { + // Not applicable $sql .= " AND a.percent = -1"; -} // Not applicable +} if ($status == '50') { + // Running already started $sql .= " AND (a.percent > 0 AND a.percent < 100)"; -} // Running already started +} if ($status == 'done' || $status == '100') { $sql .= " AND (a.percent = 100)"; } diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index 82c15392349..78fcfe657db 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -99,7 +99,7 @@ $month = GETPOST("month", "int") ?GETPOST("month", "int") : date("m"); $week = GETPOST("week", "int") ?GETPOST("week", "int") : date("W"); $day = GETPOST("day", "int") ?GETPOST("day", "int") : date("d"); $pid = GETPOST("search_projectid", "int", 3) ?GETPOST("search_projectid", "int", 3) : GETPOST("projectid", "int", 3); -$status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo' +$status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo', 'na' or -1 $type = GETPOST("search_type", 'alpha') ?GETPOST("search_type", 'alpha') : GETPOST("type", 'alpha'); $maxprint = ((GETPOST("maxprint", 'int') != '') ?GETPOST("maxprint", 'int') : $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') @@ -626,12 +626,14 @@ if ($type) { if ($status == '0') { $sql .= " AND a.percent = 0"; } -if ($status == '-1') { +if ($status == '-1' || $status == 'na') { + // Not applicable $sql .= " AND a.percent = -1"; -} // Not applicable +} if ($status == '50') { + // Running already started $sql .= " AND (a.percent > 0 AND a.percent < 100)"; -} // Running already started +} if ($status == 'done' || $status == '100') { $sql .= " AND (a.percent = 100)"; } From 873745a178ab3bdca28cff576ea4e998d25f53be Mon Sep 17 00:00:00 2001 From: Quatadah Nasdami Date: Mon, 25 Jul 2022 20:13:54 +0200 Subject: [PATCH 012/205] I included the boolean in the `$params` and resolved the margin issue. --- htdocs/core/lib/functions.lib.php | 8 ++++---- htdocs/projet/card.php | 22 +++++++++++----------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index e7c0244387f..3df96d4e057 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -10343,7 +10343,6 @@ function dolGetStatus($statusLabel = '', $statusLabelShort = '', $html = '', $st * @param string $actionType default, delete, danger * @param string $url the url for link * @param string $id attribute id of button - * @param bboolean $isDropdown is dropdown button * @param int $userRight user action right * // phpcs:disable * @param array $params = [ // Various params for future : recommended rather than adding more function arguments @@ -10359,17 +10358,18 @@ 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 * @return string html button */ -function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = '', $id = '', $isDropdown = false, $userRight = 1, $params = array()) +function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = '', $id = '', $userRight = 1, $params = array()) { global $hookmanager, $action, $object, $langs; - //var_dump($isDropdown); - if ($isDropdown) + //var_dump($params); + if ($params['isDropdown']) $class = "dropdown-item"; else { $class = 'butAction'; diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 0864a5b53f6..7353323b60d 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -1319,48 +1319,48 @@ if ($action == 'create' && $user->rights->projet->creer) { if (!empty($conf->global->PROJECT_SHOW_CREATE_OBJECT_BUTTON)) { print''; print ''; +print ''; print ''; print ''; print '
'; From d400ee97031574c2a824ee146c7d4ed6802cebae Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 27 Jul 2022 13:42:59 +0200 Subject: [PATCH 057/205] Fix missing link to public interface --- htdocs/recruitment/admin/public_interface.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/htdocs/recruitment/admin/public_interface.php b/htdocs/recruitment/admin/public_interface.php index b951f440005..7212a687442 100644 --- a/htdocs/recruitment/admin/public_interface.php +++ b/htdocs/recruitment/admin/public_interface.php @@ -139,12 +139,12 @@ print dol_get_fiche_end(); print ''; -/* + if (!empty($conf->global->RECRUITMENT_ENABLE_PUBLIC_INTERFACE)) { print '
'; //print $langs->trans('FollowingLinksArePublic').'
'; - print img_picto('', 'globe').' '.$langs->trans('BlankSubscriptionForm').':
'; - if ($conf->multicompany->enabled) { + print img_picto('', 'globe').' '.$langs->trans('BlankSubscriptionForm').'
'; + if (!empty($conf->multicompany->enabled)) { $entity_qr = '?entity='.$conf->entity; } else { $entity_qr = ''; @@ -155,9 +155,12 @@ if (!empty($conf->global->RECRUITMENT_ENABLE_PUBLIC_INTERFACE)) { $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current - print ''.$urlwithroot.'/public/members/new.php'.$entity_qr.''; + print ''; + print ajax_autoselect('publicurlmember'); } -*/ // End of page llxFooter(); From 29cb21fdabeb7e2026598ccd0da2ef477f837026 Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Wed, 27 Jul 2022 17:48:10 +0200 Subject: [PATCH 058/205] FIX - php V8 functions lib dolGetButtonAction --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 61a603f48bd..1eb72d50455 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -10422,7 +10422,7 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = global $hookmanager, $action, $object, $langs; //var_dump($params); - if ($params['isDropdown']) + if (isset($params['isDropdown'])) $class = "dropdown-item"; else { $class = 'butAction'; From 31d4d0dcd42c56c2664e029b04ba23e566325f51 Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Wed, 27 Jul 2022 18:09:11 +0200 Subject: [PATCH 059/205] FIX - php V8 user right in propal card and use $user->hasRight --- htdocs/comm/propal/card.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 06c36ce517c..f1a92d032cf 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -120,9 +120,9 @@ $usercanclose = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreat $usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->propal_advance->validate))); $usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->propal_advance->send))); -$usercancreateorder = $user->rights->commande->creer; -$usercancreateinvoice = $user->rights->facture->creer; -$usercancreatecontract = $user->rights->contrat->creer; +$usercancreateorder = $user->hasRight('commande', 'creer'); +$usercancreateinvoice = $user->hasRight('facture', 'creer'); +$usercancreatecontract = $user->hasRight('contrat', 'creer'); $usercancreateintervention = $user->hasRight('ficheinter', 'creer'); $usercancreatepurchaseorder = ($user->hasRight('fournisseur', 'commande', 'creer') || $user->hasRight('supplier_order', 'creer')); From 9393a51621fdaf8679cf9b54a28c24f5b3c7c4a2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 27 Jul 2022 18:22:08 +0200 Subject: [PATCH 060/205] Clean code --- build/makepack-dolibarr.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index 01240ae34d7..3b84815455e 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -1276,7 +1276,7 @@ if ($nboftargetok) { print "\n----- Summary -----\n"; foreach my $target (sort keys %CHOOSEDTARGET) { - if ($target eq '-CHKSUM') { print "Checksum was generated"; next; } + if ($target eq '-CHKSUM') { print "Checksum was generated\n"; next; } if ($CHOOSEDTARGET{$target} < 0) { print "Package $target not built (bad requirement).\n"; } else { From c5e5f2915e600b80c4ba6d8b809e06ff69d934fe Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 27 Jul 2022 19:01:26 +0200 Subject: [PATCH 061/205] Look and feel v17 --- htdocs/core/lib/functions.lib.php | 2 +- htdocs/langs/en_US/website.lang | 5 +++++ htdocs/theme/eldy/global.inc.php | 1 + htdocs/theme/md/style.css.php | 1 + htdocs/website/index.php | 35 +++++++++++++++++-------------- 5 files changed, 27 insertions(+), 17 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 61a603f48bd..b286adae481 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1718,7 +1718,7 @@ function dolButtonToOpenUrlInDialogPopup($name, $label, $buttonstring, $url, $di //print ''; $out .= ''."\n"; - $out .= ''.$buttonstring.''; + $out .= ''.$buttonstring.''; $out .= ''; $out .= ''; $out .= ''; diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index b5ef14bd118..59a23e65d9b 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -1,5 +1,6 @@ # Dolibarr language file - Source file is en_US - website Shortname=Code +WebsiteName=Name of the website WebsiteSetupDesc=Create here the websites you wish to use. Then go into menu Websites to edit them. DeleteWebsite=Delete website ConfirmDeleteWebsite=Are you sure you want to delete this web site? All its pages and content will also be removed. The files uploaded (like into the medias directory, the ECM module, ...) will remain. @@ -42,6 +43,8 @@ ViewPageInNewTab=View page in new tab SetAsHomePage=Set as Home page RealURL=Real URL ViewWebsiteInProduction=View web site using home URLs +Virtualhost=Virtual host or domain name +VirtualhostDesc=The name of the Virtual host or domain (For example: www.mywebsite.com, mybigcompany.net, ...) SetHereVirtualHost=Use with Apache/NGinx/...
Create on your web server (Apache, Nginx, ...) a dedicated Virtual Host with PHP enabled and a Root directory on
%s ExampleToUseInApacheVirtualHostConfig=Example to use in Apache virtual host setup: YouCanAlsoTestWithPHPS=Use with PHP embedded server
On develop environment, you may prefer to test the site with the PHP embedded web server (PHP 5.5 required) by running
php -S 0.0.0.0:8080 -t %s @@ -145,3 +148,5 @@ ImportFavicon=Favicon ErrorFaviconType=Favicon must be png ErrorFaviconSize=Favicon must be sized 16x16, 32x32 or 64x64 FaviconTooltip=Upload an image which needs to be a png (16x16, 32x32 or 64x64) +NextContainer=Next page/container +PreviousContainer=Previous page/container diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 6a2ce22fa68..2074325c6e4 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -5143,6 +5143,7 @@ span[phptag] { } .centpercent.websitebar { width: calc(100% - 10px); + font-size: 0.94em; } .websitebar .buttonDelete, .websitebar .button { text-shadow: none; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 03e9565db21..81c3941d434 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -4992,6 +4992,7 @@ span[phptag] { } .centpercent.websitebar { width: calc(100% - 10px); + font-size: 0.94em; } .websitebar .buttonDelete, .websitebar .button { text-shadow: none; diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 2b3eedf995f..b05cfe51eed 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -2933,12 +2933,12 @@ if (!GETPOST('hide_websitemenu')) { if ($pagepreviousid) { print ''.img_previous($langs->trans("PreviousContainer")).''; } else { - print ''.img_previous($langs->trans("Previous")).''; + print ''.img_previous($langs->trans("PreviousContainer")).''; } if ($pagenextid) { print ''.img_next($langs->trans("NextContainer")).''; } else { - print ''.img_next($langs->trans("Next")).''; + print ''.img_next($langs->trans("NextContainer")).''; } print ''; @@ -3547,7 +3547,7 @@ if ($action == 'createsite') { } print ''."\n"; - //print '
'; + print '
'; print ''; @@ -3566,7 +3566,7 @@ if ($action == 'createsite') { } print ''; @@ -3575,9 +3575,18 @@ if ($action == 'createsite') { print $langs->trans('MainLanguage'); print ''; + print ''; + print ''; print ''; - print ''; - print '
'; - print $form->textwithpicto($langs->trans('WebSite'), $langs->trans("Example").': www.mywebsite.com, myportal, ...'); + print $form->textwithpicto($langs->trans('WebsiteName'), $langs->trans("Example").': MyPortal, www.mywebsite.com, ...'); print ''; print ''; print '
'; $shortlangcode = preg_replace('/[_-].*$/', '', trim($langs->defaultlang)); + print img_picto('', 'language', 'class="pictofixedwidth"'); print $formadmin->select_language((GETPOSTISSET('WEBSITE_LANG') ? GETPOST('WEBSITE_LANG', 'aZ09comma') : $shortlangcode), 'WEBSITE_LANG', 0, null, 1, 0, 0, 'minwidth300', 2, 0, 0, array(), 1); print '
'; + $htmltext = $langs->trans("Example").': fr,de,sv,it,pt'; + print $form->textwithpicto($langs->trans('OtherLanguages'), $htmltext, 1, 'help', '', 0, 2); + print ''; + print img_picto('', 'language', 'class="pictofixedwidth"'); + print ''; + print '
'; print $langs->trans('Description'); print ''; @@ -3585,28 +3594,22 @@ if ($action == 'createsite') { print '
'; - $htmltext = $langs->trans("Example").': fr,de,sv,it,pt'; - print $form->textwithpicto($langs->trans('OtherLanguages'), $htmltext, 1, 'help', '', 0, 2); - print ''; - print ''; - print '
'; - - $htmltext = $langs->trans("SetHereVirtualHost", '{s1}'); - $htmltext = str_replace('{s1}', DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/website/websiteref', $htmltext); + $htmltext = $langs->trans("VirtualhostDesc"); + /*$htmltext = str_replace('{s1}', DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/website/websiteref', $htmltext); $htmltext .= '
'; $htmltext .= '
'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT); $htmltext .= '
'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), '{s1}'); - $htmltext = str_replace('{s1}', DOL_DATA_ROOT.'/website
'.DOL_DATA_ROOT.'/medias', $htmltext); + $htmltext = str_replace('{s1}', DOL_DATA_ROOT.'/website
'.DOL_DATA_ROOT.'/medias', $htmltext);*/ - print $form->textwithpicto($langs->trans('Virtualhost'), $htmltext, 1, 'help', '', 0, 2, 'virtualhosttooltip'); + + print $form->textwithpicto($langs->trans('Virtualhost'), $htmltext, 1, 'help', '', 0, 2, ''); print '
'; print ''; print '
'; + print '
'; if ($action == 'createsite') { print '
'; From 5e94e464617080fced85839689a160088bf6ce6e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 27 Jul 2022 20:11:57 +0200 Subject: [PATCH 062/205] Trans --- htdocs/website/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/website/index.php b/htdocs/website/index.php index b05cfe51eed..d2015df83b5 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -587,7 +587,7 @@ if ($action == 'addsite' && $usercanedit) { if (!$error && !GETPOST('WEBSITE_REF', 'alpha')) { $error++; $langs->load("errors"); - setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities("Ref")), null, 'errors'); + setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities("WebsiteName")), null, 'errors'); } if (!$error && !preg_match('/^[a-z0-9_\-\.]+$/i', GETPOST('WEBSITE_REF', 'alpha'))) { $error++; From 6519edabc5c12831c171fce308330b3339bec4a2 Mon Sep 17 00:00:00 2001 From: Yoan Mollard Date: Wed, 27 Jul 2022 21:34:36 +0200 Subject: [PATCH 063/205] Error messages for category --- htdocs/categories/class/categorie.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index dad25199566..f860023ed4f 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -332,6 +332,7 @@ class Categorie extends CommonObject // Check parameters if (empty($id) && empty($label) && empty($ref_ext)) { + $this->error = "No category to search for"; return -1; } if (!is_null($type) && !is_numeric($type)) { @@ -389,6 +390,7 @@ class Categorie extends CommonObject return 1; } else { + $this->error = "No category found"; return 0; } } else { From 244f3913b075f4f4faf9f21e56f3e24a14c37342 Mon Sep 17 00:00:00 2001 From: Yoan Mollard Date: Wed, 27 Jul 2022 21:35:52 +0200 Subject: [PATCH 064/205] Qualify cactionevents for eventorganization --- htdocs/comm/action/class/cactioncomm.class.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/comm/action/class/cactioncomm.class.php b/htdocs/comm/action/class/cactioncomm.class.php index d2b089491a7..db62dfe6a9f 100644 --- a/htdocs/comm/action/class/cactioncomm.class.php +++ b/htdocs/comm/action/class/cactioncomm.class.php @@ -216,6 +216,9 @@ class CActionComm if ($obj->module == 'shipping' && !empty($conf->expedition->enabled) && !empty($user->rights->expedition->lire)) { $qualified = 1; } + if (preg_split("/@/", $obj->module, -1)[1] == 'eventorganization' && !empty($conf->eventorganization->enabled)) { + $qualified = 1; + } // For the generic case with type = 'module...' and module = 'myobject@mymodule' $regs = array(); if (preg_match('/^module/', $obj->type)) { From 5600fd63df04a657e834946fee04bfffc64243f7 Mon Sep 17 00:00:00 2001 From: Yoan Mollard Date: Wed, 27 Jul 2022 21:36:57 +0200 Subject: [PATCH 065/205] Retrieve category and insert default const at init of eventorganization module --- .../core/modules/modEventOrganization.class.php | 17 ++++++++++++++++- htdocs/langs/en_US/eventorganization.lang | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/htdocs/core/modules/modEventOrganization.class.php b/htdocs/core/modules/modEventOrganization.class.php index 93318bb952e..ad62dca3f3c 100644 --- a/htdocs/core/modules/modEventOrganization.class.php +++ b/htdocs/core/modules/modEventOrganization.class.php @@ -24,6 +24,7 @@ * \brief Description and activation file for the EventOrganization */ include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php'; +require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; /** * Description and activation class for module EventOrganization @@ -367,7 +368,21 @@ class modEventOrganization extends DolibarrModules } } - return $this->_init($sql, $options); + $langs->load("eventorganization"); + $cat = new Categorie($this->db); + $sql[] = "INSERT IGNORE INTO ".MAIN_DB_PREFIX.$cat->table_element."(label, type, entity, description, visible) VALUES('".$langs->trans('ApplicantOrVisitor')."', 2, 1, '".$langs->trans('EVENTORGANIZATION_CATEG_THIRDPARTY_CONF')."', 1)"; + + $init = $this->_init($sql, $options); + + if(empty($conf->global->EVENTORGANIZATION_CATEG_THIRDPARTY_CONF)) { + $langs->load('eventorganization'); + $res = $cat->fetch(null, $langs->trans('ApplicantOrVisitor')); + if($cat->id) { + dolibarr_set_const($this->db, 'EVENTORGANIZATION_CATEG_THIRDPARTY_CONF', $res); + } + } + + return $init; } /** diff --git a/htdocs/langs/en_US/eventorganization.lang b/htdocs/langs/en_US/eventorganization.lang index 4b05b4e312e..7966c6712ad 100644 --- a/htdocs/langs/en_US/eventorganization.lang +++ b/htdocs/langs/en_US/eventorganization.lang @@ -60,6 +60,7 @@ ConferenceOrBoothTab = Conference Or Booth AmountPaid = Amount paid DateOfRegistration = Date of registration ConferenceOrBoothAttendee = Conference Or Booth Attendee +ApplicantOrVisitor=Applicant or visitor # # Template Mail From e271175de6c9f0cb6c91865b3472a7708d0e5330 Mon Sep 17 00:00:00 2001 From: Yoan Mollard Date: Wed, 27 Jul 2022 21:37:06 +0200 Subject: [PATCH 066/205] Display all errors --- htdocs/public/project/suggestconference.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/public/project/suggestconference.php b/htdocs/public/project/suggestconference.php index 22589c941d2..ca34a05253d 100644 --- a/htdocs/public/project/suggestconference.php +++ b/htdocs/public/project/suggestconference.php @@ -463,8 +463,7 @@ print '
'; print '
'; print '
'; - -dol_htmloutput_errors($errmsg); +dol_htmloutput_errors($errmsg, $errors); // Print form print '
'."\n"; From e9528443b26fbcff5733c5a846e281e1fc4800d1 Mon Sep 17 00:00:00 2001 From: Yoan Mollard Date: Wed, 27 Jul 2022 22:12:36 +0200 Subject: [PATCH 067/205] Insert speaker contact type into db --- htdocs/core/modules/modEventOrganization.class.php | 1 + htdocs/langs/en_US/eventorganization.lang | 1 + 2 files changed, 2 insertions(+) diff --git a/htdocs/core/modules/modEventOrganization.class.php b/htdocs/core/modules/modEventOrganization.class.php index ad62dca3f3c..57b05131025 100644 --- a/htdocs/core/modules/modEventOrganization.class.php +++ b/htdocs/core/modules/modEventOrganization.class.php @@ -371,6 +371,7 @@ class modEventOrganization extends DolibarrModules $langs->load("eventorganization"); $cat = new Categorie($this->db); $sql[] = "INSERT IGNORE INTO ".MAIN_DB_PREFIX.$cat->table_element."(label, type, entity, description, visible) VALUES('".$langs->trans('ApplicantOrVisitor')."', 2, 1, '".$langs->trans('EVENTORGANIZATION_CATEG_THIRDPARTY_CONF')."', 1)"; + $sql[] = "INSERT IGNORE INTO ".MAIN_DB_PREFIX."c_type_contact(rowid, element, source, code, libelle, active) VALUES(300, 'conferenceorbooth', 'external', 'SPEAKER', '".$langs->trans('Speaker')."', 1)"; $init = $this->_init($sql, $options); diff --git a/htdocs/langs/en_US/eventorganization.lang b/htdocs/langs/en_US/eventorganization.lang index 7966c6712ad..b4179b04be6 100644 --- a/htdocs/langs/en_US/eventorganization.lang +++ b/htdocs/langs/en_US/eventorganization.lang @@ -61,6 +61,7 @@ AmountPaid = Amount paid DateOfRegistration = Date of registration ConferenceOrBoothAttendee = Conference Or Booth Attendee ApplicantOrVisitor=Applicant or visitor +Speaker=Speaker # # Template Mail From 37c725fc6c9f83cbec60b5d54723e0e51f2ac144 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 27 Jul 2022 23:01:33 +0200 Subject: [PATCH 068/205] NEW Can delete a website even if not empty --- htdocs/core/class/html.form.class.php | 5 +-- htdocs/langs/en_US/errors.lang | 3 +- .../template/class/myobject.class.php | 2 +- htdocs/website/class/website.class.php | 31 +++++++++---------- htdocs/website/index.php | 12 +++++-- 5 files changed, 30 insertions(+), 23 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index d31cdda5770..82e73186233 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4914,8 +4914,9 @@ class Form * @param string $question Question * @param string $action Action * @param array|string $formquestion An array with complementary inputs to add into forms: array(array('label'=> ,'type'=> , 'size'=>, 'morecss'=>, 'moreattr'=>'autofocus' or 'style=...')) - * 'type' can be 'hidden', 'text', 'password', 'checkbox', 'radio', 'date', 'select', 'multiselect', 'morecss', 'other' or 'onecolumn'... - * @param string $selectedchoice '' or 'no', or 'yes' or '1' or '0' + * 'type' can be 'text', 'password', 'checkbox', 'radio', 'date', 'select', 'multiselect', 'morecss', + * 'other', 'onecolumn' or 'hidden'... + * @param int|string $selectedchoice '' or 'no', or 'yes' or '1', 1, '0' or 0 * @param int|string $useajax 0=No, 1=Yes, 2=Yes but submit page with &confirm=no if choice is No, 'xxx'=Yes and preoutput confirm box with div id=dialog-confirm-xxx * @param int|string $height Force height of box (0 = auto) * @param int $width Force width of box ('999' or '90%'). Ignored and forced to 90% on smartphones. diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 7e29572c9f5..5326a0f11d1 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -324,7 +324,8 @@ WarningAvailableOnlyForHTTPSServers=Available only if using HTTPS secured connec WarningModuleXDisabledSoYouMayMissEventHere=Module %s has not been enabled. So you may miss a lot of event here. WarningPaypalPaymentNotCompatibleWithStrict=The value 'Strict' makes the online payment features not working correctly. Use 'Lax' instead. WarningThemeForcedTo=Warning, theme has been forced to %s by hidden constant MAIN_FORCETHEME - +WarningPagesWillBeDeleted=Warning, this will also delete all existing pages/containers of the website. You should export your website before, so you have a backup to re-import it later. + # Validate RequireValidValue = Value not valid RequireAtLeastXString = Requires at least %s character(s) diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 767cb1105fc..664eb44d5f6 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -524,7 +524,7 @@ class MyObject extends CommonObject * Delete object in database * * @param User $user User that deletes - * @param bool $notrigger false=launch triggers after, true=disable triggers + * @param bool $notrigger false=launch triggers, true=disable triggers * @return int <0 if KO, >0 if OK */ public function delete(User $user, $notrigger = false) diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index 3cb5386e831..0e062b038a0 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -30,6 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; //require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; //require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + /** * Class Website */ @@ -50,6 +51,10 @@ class Website extends CommonObject */ public $ismultientitymanaged = 1; + + protected $childtablesoncascade = array(); + + /** * @var string String with name of icon for website. Must be the part after the 'object_' into object_myobject.png */ @@ -580,8 +585,8 @@ class Website extends CommonObject /** * Delete object in database * - * @param User $user User that deletes - * @param bool $notrigger false=launch triggers after, true=disable triggers + * @param User $user User that deletes + * @param bool $notrigger false=launch triggers, true=disable triggers * * @return int <0 if KO, >0 if OK */ @@ -596,20 +601,8 @@ class Website extends CommonObject $this->db->begin(); if (!$error) { - if (!$notrigger) { - // Uncomment this and change WEBSITE to your own tag if you - // want this action calls a trigger. - - //// Call triggers - //$result=$this->call_trigger('WEBSITE_DELETE',$user); - //if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail} - //// End call triggers - } - } - - if (!$error) { - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' WHERE rowid='.((int) $this->id); + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'website_page'; + $sql .= ' WHERE fk_website = '.((int) $this->id); $resql = $this->db->query($sql); if (!$resql) { @@ -619,6 +612,12 @@ class Website extends CommonObject } } + // Delete common code. This include execution of trigger. + $result = $this->deleteCommon($user, $notrigger); + if ($result <= 0) { + $error++; + } + if (!$error && !empty($this->ref)) { $pathofwebsite = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/website/'.$this->ref; diff --git a/htdocs/website/index.php b/htdocs/website/index.php index d2015df83b5..35591c3447d 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -1230,7 +1230,7 @@ if ($action == 'confirm_deletesite' && $confirm == 'yes' && $permissiontodelete) exit; } else { $db->rollback(); - dol_print_error($db); + setEventMessages($object->error, $object->errors, 'errors'); } } @@ -2741,7 +2741,8 @@ if (!GETPOST('hide_websitemenu')) { print ''; - print ''; + //print ''; + print ''; // Regenerate all pages print 'ref).'" class="button bordertransp"'.$disabled.' title="'.dol_escape_htmltag($langs->trans("RegenerateWebsiteContent")).'">'; @@ -2964,7 +2965,12 @@ if (!GETPOST('hide_websitemenu')) { //array('type' => 'other','name' => 'newwebsite','label' => $langs->trans("WebSite"), 'value' => $formwebsite->selectWebsite($object->id, 'newwebsite', 0)) ); - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteWebsite'), '', 'confirm_deletesite', $formquestion, 0, 1, 200); + if ($atleastonepage) { + $langs->load("errors"); + $formquestion[] = array('type' => 'onecolumn', 'value' => '
'.$langs->trans("WarningPagesWillBeDeleted").'
'); + } + + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteWebsite'), '', 'confirm_deletesite', $formquestion, 0, 1, 210 + ($atleastonepage ? 70 : 0), 580); print $formconfirm; } From 630dced71cb668bac9274ed0efe020be130cad7e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 27 Jul 2022 23:09:29 +0200 Subject: [PATCH 069/205] Look and feel v17 --- htdocs/website/index.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 35591c3447d..90277e59594 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2016-2022 Laurent Destailleur * Copyright (C) 2020 Nicolas ZABOURI * * This program is free software; you can redistribute it and/or modify @@ -3385,6 +3385,7 @@ if ($action == 'editcss') { $htmltext = ''; print $form->textwithpicto($langs->trans('MainLanguage'), $htmltext, 1, 'help', '', 0, 2, 'WEBSITE_LANG'); print ''; + print img_picto('', 'language', 'class="picotfixedwidth"'); print $formadmin->select_language((GETPOSTISSET('WEBSITE_LANG') ? GETPOST('WEBSITE_LANG', 'aZ09comma') : ($object->lang ? $object->lang : '0')), 'WEBSITE_LANG', 0, null, 1, 0, 0, 'minwidth300', 2, 0, 0, array(), 1); print ''; print ''; @@ -3394,6 +3395,7 @@ if ($action == 'editcss') { $htmltext = $langs->trans("Example").': fr,de,sv,it,pt'; print $form->textwithpicto($langs->trans('OtherLanguages'), $htmltext, 1, 'help', '', 0, 2); print ''; + print img_picto('', 'language', 'class="picotfixedwidth"'); print ''; print ''; print ''; @@ -3401,13 +3403,7 @@ if ($action == 'editcss') { // VirtualHost print ''; - $htmltext = $langs->trans("SetHereVirtualHost", DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/website/{s1}'.$websitekey.'{s2}'); - $htmltext = str_replace(array('{s1}', '{s2}'), array('', ''), $htmltext); - $htmltext .= '
'; - $htmltext .= '
'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT); - $htmltext .= '
'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), '{s1}'); - $htmltext = str_replace('{s1}', DOL_DATA_ROOT.'/website
'.DOL_DATA_ROOT.'/medias', $htmltext); - + $htmltext = $langs->trans("VirtualhostDesc"); print $form->textwithpicto($langs->trans('Virtualhost'), $htmltext, 1, 'help', '', 0, 2, 'virtualhosttooltip'); print ''; print ''; From c000bd7f8932721ca27573831fea956f472407ae Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 28 Jul 2022 02:31:47 +0200 Subject: [PATCH 070/205] css --- htdocs/theme/eldy/global.inc.php | 4 ++++ htdocs/theme/md/style.css.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 6a2ce22fa68..8b2cbced058 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -7639,6 +7639,10 @@ div.clipboardCPValue.hidewithsize { #dolpaymenttable { padding: 5px; } + + .lilevel1 span.paddingright { + padding-right: 3px; + } } @media only screen and (max-width: 320px) diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 03e9565db21..065ab494551 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -7319,6 +7319,10 @@ div.clipboardCPValue.hidewithsize { #dolpaymenttable { padding: 5px; } + + .lilevel1 span.paddingright { + padding-right: 3px; + } } From 2020a58ebd8db13f0bf6801caa735db33915438a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 28 Jul 2022 10:47:36 +0200 Subject: [PATCH 071/205] Fix fatal error in Stripe setup page --- htdocs/langs/en_US/stripe.lang | 3 +- htdocs/stripe/admin/stripe.php | 53 +++++++++++++++++++--------------- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/htdocs/langs/en_US/stripe.lang b/htdocs/langs/en_US/stripe.lang index 0a376ca9fb1..3ea0cf2354b 100644 --- a/htdocs/langs/en_US/stripe.lang +++ b/htdocs/langs/en_US/stripe.lang @@ -68,4 +68,5 @@ ToOfferALinkForTestWebhook=Link to setup Stripe WebHook to call the IPN (test mo ToOfferALinkForLiveWebhook=Link to setup Stripe WebHook to call the IPN (live mode) PaymentWillBeRecordedForNextPeriod=Payment will be recorded for the next period. ClickHereToTryAgain=Click here to try again... -CreationOfPaymentModeMustBeDoneFromStripeInterface=Due to Strong Customer Authentication rules, creation of a card must be done from Stripe backoffice. You can click here to switch on Stripe customer record: %s \ No newline at end of file +CreationOfPaymentModeMustBeDoneFromStripeInterface=Due to Strong Customer Authentication rules, creation of a card must be done from Stripe backoffice. You can click here to switch on Stripe customer record: %s +TERMINAL_LOCATION=Location (address) for terminals \ No newline at end of file diff --git a/htdocs/stripe/admin/stripe.php b/htdocs/stripe/admin/stripe.php index d61d03b2be6..67e0c26ce8c 100644 --- a/htdocs/stripe/admin/stripe.php +++ b/htdocs/stripe/admin/stripe.php @@ -227,10 +227,10 @@ if (empty($conf->stripeconnect->enabled)) { print ''; print ''.$langs->trans("STRIPE_TEST_WEBHOOK_KEY").''; if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { - print ''; + print ''; print '
'; } - print ''; + print ''; $out = img_picto('', 'globe').' '.$langs->trans("ToOfferALinkForTestWebhook").' '; $url = dol_buildpath('/public/stripe/ipn.php?test', 3); $out .= ''; @@ -278,21 +278,21 @@ if (empty($conf->stripeconnect->enabled)) { if (empty($conf->stripeconnect->enabled)) { print ''; print ''.$langs->trans("STRIPE_LIVE_PUBLISHABLE_KEY").''; - print ''; + print ''; print ''; print ''; print ''.$langs->trans("STRIPE_LIVE_SECRET_KEY").''; - print ''; + print ''; print ''; print ''; print ''.$langs->trans("STRIPE_LIVE_WEBHOOK_KEY").''; if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { - print ''; + print ''; print '
'; } - print ''; + print ''; $out = img_picto('', 'globe', 'class="pictofixedwidth"').' '.$langs->trans("ToOfferALinkForLiveWebhook").' '; $url = dol_buildpath('/public/stripe/ipn.php', 3); $out .= ''; @@ -347,26 +347,26 @@ print "\n"; print ''; print $langs->trans("PublicVendorName").''; -print ''; +print ''; print '   '.$langs->trans("Example").': '.$mysoc->name.''; print ''; print ''; print $langs->trans("StripeUserAccountForActions").''; -print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers($conf->global->STRIPE_USER_ACCOUNT_FOR_ACTIONS, 'STRIPE_USER_ACCOUNT_FOR_ACTIONS', 0); +print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers(getDolGlobalString('STRIPE_USER_ACCOUNT_FOR_ACTIONS'), 'STRIPE_USER_ACCOUNT_FOR_ACTIONS', 0); print ''; print ''; print $langs->trans("BankAccount").''; print img_picto('', 'bank_account', 'class="pictofixedwidth"'); -$form->select_comptes($conf->global->STRIPE_BANK_ACCOUNT_FOR_PAYMENTS, 'STRIPE_BANK_ACCOUNT_FOR_PAYMENTS', 0, '', 1); +$form->select_comptes(getDolGlobalString('STRIPE_BANK_ACCOUNT_FOR_PAYMENTS'), 'STRIPE_BANK_ACCOUNT_FOR_PAYMENTS', 0, '', 1); print ''; if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { // What is this for ? print ''; print $langs->trans("BankAccountForBankTransfer").''; print img_picto('', 'bank_account', 'class="pictofixedwidth"'); - $form->select_comptes($conf->global->STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS, 'STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS', 0, '', 1); + $form->select_comptes(getDolGlobalString('STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS'), 'STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS', 0, '', 1); print ''; } @@ -386,7 +386,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code // Locations for Stripe Terminal if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code print ''; - print $langs->trans("STRIPE_LOCATION").''; + print $langs->trans("TERMINAL_LOCATION").''; $service = 'StripeTest'; $servicestatus = 0; if (!empty($conf->global->STRIPE_LIVE) && !GETPOST('forcesandbox', 'alpha')) { @@ -395,7 +395,9 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code } global $stripearrayofkeysbyenv; $site_account = $stripearrayofkeysbyenv[$servicestatus]['secret_key']; - \Stripe\Stripe::setApiKey($site_account); + if (!empty($site_account)) { + \Stripe\Stripe::setApiKey($site_account); + } if (!empty($conf->stripe->enabled) && (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha'))) { $service = 'StripeTest'; $servicestatus = '0'; @@ -405,30 +407,34 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code $servicestatus = '1'; } $stripe = new Stripe($db); - $stripeacc = $stripe->getStripeAccount($service); - if ($stripeacc) { - $locations = \Stripe\Terminal\Location::all('', array("stripe_account" => $stripeacc)); - } else { - $locations = \Stripe\Terminal\Location::all(); + if (!empty($site_account)) { + // If $site_account not defined, then key not set and no way to call API Location + $stripeacc = $stripe->getStripeAccount($service); + if ($stripeacc) { + $locations = \Stripe\Terminal\Location::all('', array("stripe_account" => $stripeacc)); + } else { + $locations = \Stripe\Terminal\Location::all(); + } } + $location = array(); - $location[""] = $langs->trans("EmptyLocation"); + $location[""] = $langs->trans("NotDefined"); foreach ($locations as $locations) { $location[$locations->id] = $locations->display_name; } - print $form->selectarray("STRIPE_LOCATION", $location, $conf->global->STRIPE_LOCATION); + print $form->selectarray("STRIPE_LOCATION", $location, getDolGlobalString('STRIPE_LOCATION')); print ''; } // Activate Payment Request API if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code print ''; - print $langs->trans("STRIPE_PAYMENT_REQUEST_API").''; + print $langs->trans("STRIPE_PAYMENT_REQUEST_API").' ?? Not used, what is it for ??'; if ($conf->use_javascript_ajax) { print ajax_constantonoff('STRIPE_PAYMENT_REQUEST_API'); } else { $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("STRIPE_PAYMENT_REQUEST_API", $arrval, $conf->global->STRIPE_PAYMENT_REQUEST_API); + print $form->selectarray("STRIPE_PAYMENT_REQUEST_API", $arrval, getDolGlobalString('STRIPE_PAYMENT_REQUEST_API')); } print ''; } @@ -441,7 +447,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code print ajax_constantonoff('STRIPE_SEPA_DIRECT_DEBIT'); } else { $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("STRIPE_SEPA_DIRECT_DEBIT", $arrval, $conf->global->STRIPE_SEPA_DIRECT_DEBIT); + print $form->selectarray("STRIPE_SEPA_DIRECT_DEBIT", $arrval, getDolGlobalString('STRIPE_SEPA_DIRECT_DEBIT')); } print ''; } @@ -542,6 +548,7 @@ print ''; print ''; print $langs->trans("ONLINE_PAYMENT_SENDEMAIL").''; +print img_picto('', 'email', 'class="pictofixedwidth"'); print ''; print '   '.$langs->trans("Example").': myemail@myserver.com, Payment service <myemail2@myserver2.com>'; print ''; @@ -575,7 +582,7 @@ print ''; print ''; print $langs->trans("SecurityTokenIsUnique").''; if ($conf->use_javascript_ajax) { - print ajax_constantonoff('PAYMENT_SECURITY_TOKEN_UNIQUE'); + print ajax_constantonoff('PAYMENT_SECURITY_TOKEN_UNIQUE', null, null, 0, 0, 1); } else { $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); print $form->selectarray("PAYMENT_SECURITY_TOKEN_UNIQUE", $arrval, $conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE); From 1a61209c0ddf4e6fc116da2d94c780a581ec8c3f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 28 Jul 2022 10:47:36 +0200 Subject: [PATCH 072/205] Fix fatal error in Stripe setup page Conflicts: htdocs/stripe/admin/stripe.php --- htdocs/langs/en_US/stripe.lang | 3 ++- htdocs/stripe/admin/stripe.php | 33 +++++++++++++++++---------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/htdocs/langs/en_US/stripe.lang b/htdocs/langs/en_US/stripe.lang index 0a376ca9fb1..3ea0cf2354b 100644 --- a/htdocs/langs/en_US/stripe.lang +++ b/htdocs/langs/en_US/stripe.lang @@ -68,4 +68,5 @@ ToOfferALinkForTestWebhook=Link to setup Stripe WebHook to call the IPN (test mo ToOfferALinkForLiveWebhook=Link to setup Stripe WebHook to call the IPN (live mode) PaymentWillBeRecordedForNextPeriod=Payment will be recorded for the next period. ClickHereToTryAgain=Click here to try again... -CreationOfPaymentModeMustBeDoneFromStripeInterface=Due to Strong Customer Authentication rules, creation of a card must be done from Stripe backoffice. You can click here to switch on Stripe customer record: %s \ No newline at end of file +CreationOfPaymentModeMustBeDoneFromStripeInterface=Due to Strong Customer Authentication rules, creation of a card must be done from Stripe backoffice. You can click here to switch on Stripe customer record: %s +TERMINAL_LOCATION=Location (address) for terminals \ No newline at end of file diff --git a/htdocs/stripe/admin/stripe.php b/htdocs/stripe/admin/stripe.php index 77c8d9a03b2..e3befa94108 100644 --- a/htdocs/stripe/admin/stripe.php +++ b/htdocs/stripe/admin/stripe.php @@ -221,10 +221,10 @@ if (empty($conf->stripeconnect->enabled)) { print ''; print ''.$langs->trans("STRIPE_TEST_WEBHOOK_KEY").''; if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { - print ''; + print ''; print '
'; } - print ''; + print ''; $out = img_picto('', 'globe').' '.$langs->trans("ToOfferALinkForTestWebhook").' '; $url = dol_buildpath('/public/stripe/ipn.php?test', 3); $out .= ''; @@ -272,22 +272,22 @@ if (empty($conf->stripeconnect->enabled)) { if (empty($conf->stripeconnect->enabled)) { print ''; print ''.$langs->trans("STRIPE_LIVE_PUBLISHABLE_KEY").''; - print ''; + print ''; print ''; print ''; print ''.$langs->trans("STRIPE_LIVE_SECRET_KEY").''; - print ''; + print ''; print ''; print ''; print ''.$langs->trans("STRIPE_LIVE_WEBHOOK_KEY").''; if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { - print ''; + print ''; print '
'; } print ''; - $out = img_picto('', 'globe').' '.$langs->trans("ToOfferALinkForLiveWebhook").' '; + $out = img_picto('', 'globe', 'class="pictofixedwidth"').' '.$langs->trans("ToOfferALinkForLiveWebhook").' '; $url = dol_buildpath('/public/stripe/ipn.php', 3); $out .= ''; $out .= ajax_autoselect("onlinelivewebhookurl", 0); @@ -341,38 +341,38 @@ print "\n"; print ''; print $langs->trans("PublicVendorName").''; -print ''; +print ''; print '   '.$langs->trans("Example").': '.$mysoc->name.''; print ''; print ''; print $langs->trans("StripeUserAccountForActions").''; -print img_picto('', 'user').$form->select_dolusers($conf->global->STRIPE_USER_ACCOUNT_FOR_ACTIONS, 'STRIPE_USER_ACCOUNT_FOR_ACTIONS', 0); +print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers(getDolGlobalString('STRIPE_USER_ACCOUNT_FOR_ACTIONS'), 'STRIPE_USER_ACCOUNT_FOR_ACTIONS', 0); print ''; print ''; print $langs->trans("BankAccount").''; -print img_picto('', 'bank_account').' '; -$form->select_comptes($conf->global->STRIPE_BANK_ACCOUNT_FOR_PAYMENTS, 'STRIPE_BANK_ACCOUNT_FOR_PAYMENTS', 0, '', 1); +print img_picto('', 'bank_account', 'class="pictofixedwidth"'); +$form->select_comptes(getDolGlobalString('STRIPE_BANK_ACCOUNT_FOR_PAYMENTS'), 'STRIPE_BANK_ACCOUNT_FOR_PAYMENTS', 0, '', 1); print ''; if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { // What is this for ? print ''; print $langs->trans("BankAccountForBankTransfer").''; - print img_picto('', 'bank_account').' '; - $form->select_comptes($conf->global->STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS, 'STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS', 0, '', 1); + print img_picto('', 'bank_account', 'class="pictofixedwidth"'); + $form->select_comptes(getDolGlobalString('STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS'), 'STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS', 0, '', 1); print ''; } // Activate Payment Request API if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code print ''; - print $langs->trans("STRIPE_PAYMENT_REQUEST_API").''; + print $langs->trans("STRIPE_PAYMENT_REQUEST_API").' ?? Not used, what is it for ??'; if ($conf->use_javascript_ajax) { print ajax_constantonoff('STRIPE_PAYMENT_REQUEST_API'); } else { $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("STRIPE_PAYMENT_REQUEST_API", $arrval, $conf->global->STRIPE_PAYMENT_REQUEST_API); + print $form->selectarray("STRIPE_PAYMENT_REQUEST_API", $arrval, getDolGlobalString('STRIPE_PAYMENT_REQUEST_API')); } print ''; } @@ -385,7 +385,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code print ajax_constantonoff('STRIPE_SEPA_DIRECT_DEBIT'); } else { $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("STRIPE_SEPA_DIRECT_DEBIT", $arrval, $conf->global->STRIPE_SEPA_DIRECT_DEBIT); + print $form->selectarray("STRIPE_SEPA_DIRECT_DEBIT", $arrval, getDolGlobalString('STRIPE_SEPA_DIRECT_DEBIT')); } print ''; } @@ -486,6 +486,7 @@ print ''; print ''; print $langs->trans("ONLINE_PAYMENT_SENDEMAIL").''; +print img_picto('', 'email', 'class="pictofixedwidth"'); print ''; print '   '.$langs->trans("Example").': myemail@myserver.com, Payment service <myemail2@myserver2.com>'; print ''; @@ -519,7 +520,7 @@ print ''; print ''; print $langs->trans("SecurityTokenIsUnique").''; if ($conf->use_javascript_ajax) { - print ajax_constantonoff('PAYMENT_SECURITY_TOKEN_UNIQUE'); + print ajax_constantonoff('PAYMENT_SECURITY_TOKEN_UNIQUE', null, null, 0, 0, 1); } else { $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); print $form->selectarray("PAYMENT_SECURITY_TOKEN_UNIQUE", $arrval, $conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE); From c34579a2b0f1e6f58cab64b4e2ed7ed1970697eb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 28 Jul 2022 11:16:21 +0200 Subject: [PATCH 073/205] CSS --- htdocs/societe/paymentmodes.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index a63b91b024b..0f41ce6a56b 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -815,7 +815,8 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' print ''; print ''; print ''; - print ''; + print img_picto($langs->trans("CreateCustomerOnStripe"), 'stripe'); + print ''; print ''; } print ''; @@ -1289,6 +1290,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' $morehtmlright = dolGetButtonTitle($langs->trans('Add'), '', 'fa fa-plus-circle', $_SERVER["PHP_SELF"] . '?socid=' . $object->id . '&action=create'); } + print load_fiche_titre($langs->trans("BankAccounts"), $morehtmlright, 'bank'); $rib_list = $object->get_all_rib(); @@ -1454,6 +1456,10 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' // Edit/Delete print ''; if ($permissiontoaddupdatepaymentinformation) { + print ''; + print img_picto($langs->trans("CreateBAN"), 'stripe'); + print ''; + print ''; print img_picto($langs->trans("Modify"), 'edit'); print ''; From d8ae2361a984f0c3e337c96262ec488cc9cc7cf0 Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Thu, 28 Jul 2022 11:29:36 +0200 Subject: [PATCH 074/205] NEW - Add user right order generete doc --- htdocs/commande/card.php | 7 ++++--- htdocs/core/actions_builddoc.inc.php | 2 +- htdocs/core/modules/modCommande.class.php | 10 +++++++++- htdocs/langs/en_US/admin.lang | 1 + 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 668787349be..a85aa2c5f77 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -108,14 +108,15 @@ $extrafields->fetch_name_optionals_label($object->table_element); // Load object include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once -$usercanread = $user->rights->commande->lire; -$usercancreate = $user->rights->commande->creer; -$usercandelete = $user->rights->commande->supprimer; +$usercanread = $user->hasRight('commande', 'lire'); +$usercancreate = $user->hasRight('commande', 'creer'); +$usercandelete = $user->hasRight('commande', 'supprimer'); // Advanced permissions $usercanclose = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->commande->creer)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->commande->order_advance->close))); $usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->commande->order_advance->validate))); $usercancancel = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->commande->order_advance->annuler))); $usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->commande->order_advance->send); +$usercangeneretedoc = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->hasRight('commande', 'order_advance', 'generetedoc')); $usercancreatepurchaseorder = ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer); diff --git a/htdocs/core/actions_builddoc.inc.php b/htdocs/core/actions_builddoc.inc.php index 69d46dae51c..385b36bdbce 100644 --- a/htdocs/core/actions_builddoc.inc.php +++ b/htdocs/core/actions_builddoc.inc.php @@ -34,7 +34,7 @@ if (!empty($permissioncreate) && empty($permissiontoadd)) { } // Build doc -if ($action == 'builddoc' && $permissiontoadd) { +if ($action == 'builddoc' && ($permissiontoadd || !empty($usercangeneretedoc))) { if (is_numeric(GETPOST('model', 'alpha'))) { $error = $langs->trans("ErrorFieldRequired", $langs->transnoentities("Model")); } else { diff --git a/htdocs/core/modules/modCommande.class.php b/htdocs/core/modules/modCommande.class.php index e75147ba78a..70f06169394 100644 --- a/htdocs/core/modules/modCommande.class.php +++ b/htdocs/core/modules/modCommande.class.php @@ -139,9 +139,17 @@ class modCommande extends DolibarrModules $this->rights[$r][4] = 'order_advance'; $this->rights[$r][5] = 'validate'; + $r++; + $this->rights[$r][0] = 85; + $this->rights[$r][1] = 'Generate the documents sales orders'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'order_advance'; + $this->rights[$r][5] = 'generetedoc'; + $r++; $this->rights[$r][0] = 86; - $this->rights[$r][1] = 'Send sale orders by email'; + $this->rights[$r][1] = 'Send sales orders by email'; $this->rights[$r][2] = 'd'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'order_advance'; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 16c39de46b9..f004079ea09 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -739,6 +739,7 @@ Permission79=Create/modify subscriptions Permission81=Read customers orders Permission82=Create/modify customers orders Permission84=Validate customers orders +Permission85=Generate the documents sales orders Permission86=Send customers orders Permission87=Close customers orders Permission88=Cancel customers orders From 03e265b080acf46478ae4049e2557cea3b2153bc Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Thu, 28 Jul 2022 11:43:00 +0200 Subject: [PATCH 075/205] FIX - php V8 user right order card --- htdocs/commande/card.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 668787349be..cf8e16f94ec 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -108,16 +108,16 @@ $extrafields->fetch_name_optionals_label($object->table_element); // Load object include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once -$usercanread = $user->rights->commande->lire; -$usercancreate = $user->rights->commande->creer; -$usercandelete = $user->rights->commande->supprimer; +$usercanread = $user->hasRight('commande', 'lire'); +$usercancreate = $user->hasRight('commande', 'creer'); +$usercandelete = $user->hasRight('commande', 'supprimer'); // Advanced permissions -$usercanclose = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->commande->creer)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->commande->order_advance->close))); -$usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->commande->order_advance->validate))); -$usercancancel = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->commande->order_advance->annuler))); -$usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->commande->order_advance->send); +$usercanclose = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($usercancreate)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->hasRight('commande', 'order_advance', 'close')))); +$usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->hasRight('commande', 'order_advance', 'validate')))); +$usercancancel = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->hasRight('commande', 'order_advance', 'annuler')))); +$usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->hasRight('commande', 'order_advance', 'send')); -$usercancreatepurchaseorder = ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer); +$usercancreatepurchaseorder = ($user->hasRight('fournisseur', 'commande', 'creer') || $user->hasRight('supplier_order', 'creer')); $permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php $permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php From a778a5ff78a649043c9b061fc22cb1da8c84a6d9 Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Thu, 28 Jul 2022 11:50:42 +0200 Subject: [PATCH 076/205] and order lib --- htdocs/commande/card.php | 8 ++++---- htdocs/core/lib/order.lib.php | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index cf8e16f94ec..0af1c2b7d9f 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -2747,7 +2747,7 @@ if ($action == 'create' && $usercancreate) { $langs->load("interventions"); if ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED && $object->getNbOfServicesLines() > 0) { - if ($user->rights->ficheinter->creer) { + if ($user->hasRight('ficheinter', 'creer')) { print dolGetButtonAction('', $langs->trans('AddIntervention'), 'default', DOL_URL_ROOT.'/fichinter/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid, ''); } else { print dolGetButtonAction($langs->trans('NotAllowed'), $langs->trans('AddIntervention'), 'default', $_SERVER['PHP_SELF']. '#', '', false); @@ -2759,7 +2759,7 @@ if ($action == 'create' && $usercancreate) { if (!empty($conf->contrat->enabled) && ($object->statut == Commande::STATUS_VALIDATED || $object->statut == Commande::STATUS_SHIPMENTONPROCESS || $object->statut == Commande::STATUS_CLOSED)) { $langs->load("contracts"); - if ($user->rights->contrat->creer) { + if ($user->hasRight('contrat', 'creer')) { print dolGetButtonAction('', $langs->trans('AddContract'), 'default', DOL_URL_ROOT.'/contrat/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid, ''); } } @@ -2771,7 +2771,7 @@ if ($action == 'create' && $usercancreate) { if ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED && ($object->getNbOfProductsLines() > 0 || !empty($conf->global->STOCK_SUPPORTS_SERVICES))) { if ((isModEnabled('expedition_bon') && $user->rights->expedition->creer) || ($conf->delivery_note->enabled && $user->rights->expedition->delivery->creer)) { - if ($user->rights->expedition->creer) { + if ($user->hasRight('expedition', 'creer')) { print dolGetButtonAction('', $langs->trans('CreateShipment'), 'default', DOL_URL_ROOT.'/expedition/shipment.php?id='.$object->id, ''); } else { print dolGetButtonAction($langs->trans('NotAllowed'), $langs->trans('CreateShipment'), 'default', $_SERVER['PHP_SELF']. '#', '', false); @@ -2790,7 +2790,7 @@ if ($action == 'create' && $usercancreate) { // Create bill and Classify billed // Note: Even if module invoice is not enabled, we should be able to use button "Classified billed" if ($object->statut > Commande::STATUS_DRAFT && !$object->billed && $object->total_ttc >= 0) { - if (isModEnabled('facture') && $user->rights->facture->creer && empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) { + if (isModEnabled('facture') && $user->hasRight('facture', 'creer') && empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) { print dolGetButtonAction('', $langs->trans('CreateBill'), 'default', DOL_URL_ROOT.'/compta/facture/card.php?action=create&token='.newToken().'&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid, ''); } if ($usercancreate && $object->statut >= Commande::STATUS_VALIDATED && empty($conf->global->WORKFLOW_DISABLE_CLASSIFY_BILLED_FROM_ORDER) && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) { diff --git a/htdocs/core/lib/order.lib.php b/htdocs/core/lib/order.lib.php index 8860f4126c4..bde894940de 100644 --- a/htdocs/core/lib/order.lib.php +++ b/htdocs/core/lib/order.lib.php @@ -60,8 +60,8 @@ function commande_prepare_head(Commande $object) $h++; } - if ((isModEnabled('expedition_bon') && $user->rights->expedition->lire) - || ($conf->delivery_note->enabled && $user->rights->expedition->delivery->lire)) { + if ((isModEnabled('expedition_bon') && $user->hasRight('expedition', 'lire')) + || ($conf->delivery_note->enabled && $user->hasRight('expedition', 'delivery', 'lire'))) { $nbShipments = $object->getNbOfShipments(); $nbReceiption = 0; $head[$h][0] = DOL_URL_ROOT.'/expedition/shipment.php?id='.$object->id; From 9c0cf32ef7dbe94f639c7688cf447cc5ce3e8161 Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Thu, 28 Jul 2022 11:56:07 +0200 Subject: [PATCH 077/205] FIX - php V8 user right actioncomm class --- htdocs/comm/action/class/actioncomm.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 68e358f18eb..9a7114a6113 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -1558,13 +1558,13 @@ class ActionComm extends CommonObject } $canread = 0; - if ($user->rights->agenda->myactions->read && $this->authorid == $user->id) { + if (!empty($user->rights->agenda->myactions->read) && $this->authorid == $user->id) { $canread = 1; // Can read my event } - if ($user->rights->agenda->myactions->read && array_key_exists($user->id, $this->userassigned)) { + if (!empty($user->rights->agenda->myactions->read) && array_key_exists($user->id, $this->userassigned)) { $canread = 1; // Can read my event i am assigned } - if ($user->rights->agenda->allactions->read) { + if (!empty($user->rights->agenda->allactions->read)) { $canread = 1; // Can read all event of other } if (!$canread) { From c1b98e8e733ec7205dfadea65161bef5770d048f Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Thu, 28 Jul 2022 12:09:22 +0200 Subject: [PATCH 078/205] FIX - php V8 user right box --- htdocs/core/boxes/box_actions.php | 2 +- htdocs/core/boxes/box_contacts.php | 2 +- htdocs/core/boxes/box_contracts.php | 2 +- htdocs/core/boxes/box_factures_fourn.php | 2 +- htdocs/core/boxes/box_factures_fourn_imp.php | 2 +- htdocs/core/boxes/box_ficheinter.php | 2 +- htdocs/core/boxes/box_propales.php | 2 +- htdocs/core/boxes/box_services_expired.php | 2 +- htdocs/core/boxes/box_supplier_orders.php | 2 +- htdocs/core/boxes/box_supplier_orders_awaiting_reception.php | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/htdocs/core/boxes/box_actions.php b/htdocs/core/boxes/box_actions.php index 551b892f0f7..fb0f93086d2 100644 --- a/htdocs/core/boxes/box_actions.php +++ b/htdocs/core/boxes/box_actions.php @@ -62,7 +62,7 @@ class box_actions extends ModeleBoxes $this->enabled = $conf->agenda->enabled; - $this->hidden = !($user->rights->agenda->myactions->read); + $this->hidden = !($user->hasRight('agenda', 'myactions', 'read')); } /** diff --git a/htdocs/core/boxes/box_contacts.php b/htdocs/core/boxes/box_contacts.php index ea35a080d0e..f257d7db18d 100644 --- a/htdocs/core/boxes/box_contacts.php +++ b/htdocs/core/boxes/box_contacts.php @@ -63,7 +63,7 @@ class box_contacts extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->societe->lire && $user->rights->societe->contact->lire); + $this->hidden = !($user->hasRight('societe', 'lire') && $user->hasRight('societe', 'contact', 'lire')); } /** diff --git a/htdocs/core/boxes/box_contracts.php b/htdocs/core/boxes/box_contracts.php index dddafffdc02..99ea5541c98 100644 --- a/htdocs/core/boxes/box_contracts.php +++ b/htdocs/core/boxes/box_contracts.php @@ -59,7 +59,7 @@ class box_contracts extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->contrat->lire); + $this->hidden = !($user->hasRight('contrat', 'lire')); } /** diff --git a/htdocs/core/boxes/box_factures_fourn.php b/htdocs/core/boxes/box_factures_fourn.php index 5fc3bdafa38..06124d4ab35 100644 --- a/htdocs/core/boxes/box_factures_fourn.php +++ b/htdocs/core/boxes/box_factures_fourn.php @@ -59,7 +59,7 @@ class box_factures_fourn extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->fournisseur->facture->lire); + $this->hidden = !($user->hasRight('fournisseur', 'facture', 'lire')); } /** diff --git a/htdocs/core/boxes/box_factures_fourn_imp.php b/htdocs/core/boxes/box_factures_fourn_imp.php index d8c9321411d..ad6c6c97c27 100644 --- a/htdocs/core/boxes/box_factures_fourn_imp.php +++ b/htdocs/core/boxes/box_factures_fourn_imp.php @@ -58,7 +58,7 @@ class box_factures_fourn_imp extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->fournisseur->facture->lire); + $this->hidden = !($user->hasRight('fournisseur', 'facture', 'lire')); } /** diff --git a/htdocs/core/boxes/box_ficheinter.php b/htdocs/core/boxes/box_ficheinter.php index b0f0e691471..f69ccb0ad94 100644 --- a/htdocs/core/boxes/box_ficheinter.php +++ b/htdocs/core/boxes/box_ficheinter.php @@ -59,7 +59,7 @@ class box_ficheinter extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->ficheinter->lire); + $this->hidden = !($user->hasRight('ficheinter', 'lire')); } /** diff --git a/htdocs/core/boxes/box_propales.php b/htdocs/core/boxes/box_propales.php index cdaf629ae3f..8e8efc8d8f3 100644 --- a/htdocs/core/boxes/box_propales.php +++ b/htdocs/core/boxes/box_propales.php @@ -61,7 +61,7 @@ class box_propales extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->propale->lire); + $this->hidden = !($user->hasRight('propale', 'lire')); } /** diff --git a/htdocs/core/boxes/box_services_expired.php b/htdocs/core/boxes/box_services_expired.php index e9cca792de1..25fa5ca2b1f 100644 --- a/htdocs/core/boxes/box_services_expired.php +++ b/htdocs/core/boxes/box_services_expired.php @@ -58,7 +58,7 @@ class box_services_expired extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->contrat->lire); + $this->hidden = !($user->hasRight('contrat', 'lire')); } /** diff --git a/htdocs/core/boxes/box_supplier_orders.php b/htdocs/core/boxes/box_supplier_orders.php index 6ee0c5ef8a3..f3db3526bb6 100644 --- a/htdocs/core/boxes/box_supplier_orders.php +++ b/htdocs/core/boxes/box_supplier_orders.php @@ -58,7 +58,7 @@ class box_supplier_orders extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->fournisseur->commande->lire); + $this->hidden = !($user->hasRight('fournisseur', 'commande', 'lire')); } /** diff --git a/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php b/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php index 32151828b83..ce0161582de 100644 --- a/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php +++ b/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php @@ -58,7 +58,7 @@ class box_supplier_orders_awaiting_reception extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->fournisseur->commande->lire); + $this->hidden = !($user->hasRight('fournisseur', 'commande', 'lire')); } /** From 524c2e932cafa4ecb38de52af73a7a251ab46a68 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Thu, 28 Jul 2022 13:35:43 +0200 Subject: [PATCH 079/205] NEW display currency in takepos menu --- htdocs/takepos/public/menu.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/takepos/public/menu.php b/htdocs/takepos/public/menu.php index ad4dfd9035e..5d9d318db07 100644 --- a/htdocs/takepos/public/menu.php +++ b/htdocs/takepos/public/menu.php @@ -97,7 +97,7 @@ foreach ($maincategories as $cat) {

'.$pro->label.'

- '.price($pro->price_ttc, 1).' + '.price($pro->price_ttc, 1, $langs, 1, -1, -1, $conf->currency).'
'; } From d66aa960bb57ccdf7cd137ea1ece07540b1d7d31 Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Thu, 28 Jul 2022 14:33:33 +0200 Subject: [PATCH 080/205] Resolve --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 1eb72d50455..707f8cb7384 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -10422,7 +10422,7 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = global $hookmanager, $action, $object, $langs; //var_dump($params); - if (isset($params['isDropdown'])) + if (!empty($params['isDropdown'])) $class = "dropdown-item"; else { $class = 'butAction'; From 7301ef6bfa1e40d263e647be63526ed364b7c9d8 Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Thu, 28 Jul 2022 14:55:42 +0200 Subject: [PATCH 081/205] FIX - strlower to email --- htdocs/contact/class/contact.class.php | 2 +- htdocs/societe/class/societe.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 9fa3602ee4b..9957174dcc3 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -563,7 +563,7 @@ class Contact extends CommonObject $this->ref_ext = trim($this->ref_ext); $this->lastname = trim($this->lastname) ?trim($this->lastname) : trim($this->lastname); $this->firstname = trim($this->firstname); - $this->email = trim($this->email); + $this->email = dol_strtolower(trim($this->email)); $this->phone_pro = trim($this->phone_pro); $this->phone_perso = trim($this->phone_perso); $this->phone_mobile = trim($this->phone_mobile); diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 90766323080..2279aa90cdb 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1279,7 +1279,7 @@ class Societe extends CommonObject $this->fax = trim($this->fax); $this->fax = preg_replace("/\s/", "", $this->fax); $this->fax = preg_replace("/\./", "", $this->fax); - $this->email = trim($this->email); + $this->email = dol_strtolower(trim($this->email)); $this->url = $this->url ?clean_url($this->url, 0) : ''; $this->note_private = trim($this->note_private); $this->note_public = trim($this->note_public); From 5c3139974c2462da0ce8c7bb4bc4fdf2457af42c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 28 Jul 2022 14:55:47 +0200 Subject: [PATCH 082/205] css --- htdocs/comm/mailing/list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/mailing/list.php b/htdocs/comm/mailing/list.php index ecde836c428..757b6373f3f 100644 --- a/htdocs/comm/mailing/list.php +++ b/htdocs/comm/mailing/list.php @@ -277,7 +277,7 @@ if ($resql) { print ''; // Title - print ''.$obj->title.''; + print ''.dol_escape_htmltag($obj->title).''; // Date creation print ''; @@ -286,7 +286,7 @@ if ($resql) { // Nb of email if (!$filteremail) { - print ''; + print ''; $nbemail = $obj->nbemail; /*if ($obj->statut != 3 && !empty($conf->global->MAILING_LIMIT_SENDBYWEB) && $conf->global->MAILING_LIMIT_SENDBYWEB < $nbemail) { From cfc9819e49496ef2c4297f857650de34ec0f3910 Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Thu, 28 Jul 2022 15:13:13 +0200 Subject: [PATCH 083/205] FIX - strlower for email --- htdocs/adherents/class/adherent.class.php | 3 +-- htdocs/contact/class/contact.class.php | 4 ++-- htdocs/core/class/commonobject.class.php | 2 ++ htdocs/societe/class/societe.class.php | 5 ++--- htdocs/user/class/user.class.php | 3 ++- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index c860a19d588..dec7584b68e 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -670,11 +670,10 @@ class Adherent extends CommonObject $this->town = ($this->town ? $this->town : $this->town); $this->country_id = ($this->country_id > 0 ? $this->country_id : $this->country_id); $this->state_id = ($this->state_id > 0 ? $this->state_id : $this->state_id); - $this->setUpperOrLowerCase(); $this->note_public = ($this->note_public ? $this->note_public : $this->note_public); $this->note_private = ($this->note_private ? $this->note_private : $this->note_private); $this->url = $this->url ?clean_url($this->url, 0) : ''; - + $this->setUpperOrLowerCase(); // Check parameters if (!empty($conf->global->ADHERENT_MAIL_REQUIRED) && !isValidEMail($this->email)) { $langs->load("errors"); diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 9957174dcc3..799b53cdad0 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -563,7 +563,7 @@ class Contact extends CommonObject $this->ref_ext = trim($this->ref_ext); $this->lastname = trim($this->lastname) ?trim($this->lastname) : trim($this->lastname); $this->firstname = trim($this->firstname); - $this->email = dol_strtolower(trim($this->email)); + $this->email = trim($this->email); $this->phone_pro = trim($this->phone_pro); $this->phone_perso = trim($this->phone_perso); $this->phone_mobile = trim($this->phone_mobile); @@ -571,7 +571,6 @@ class Contact extends CommonObject $this->fax = trim($this->fax); $this->zip = (empty($this->zip) ? '' : trim($this->zip)); $this->town = (empty($this->town) ? '' : trim($this->town)); - $this->setUpperOrLowerCase(); $this->country_id = ($this->country_id > 0 ? $this->country_id : $this->country_id); if (empty($this->statut)) { $this->statut = 0; @@ -579,6 +578,7 @@ class Contact extends CommonObject if (empty($this->civility_code) && !is_numeric($this->civility_id)) { $this->civility_code = $this->civility_id; // For backward compatibility } + $this->setUpperOrLowerCase(); $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."socpeople SET"; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 01665e99ca5..f3c49ae1f75 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -759,6 +759,8 @@ abstract class CommonObject $this->address = dol_strtoupper($this->address); $this->town = dol_strtoupper($this->town); } + $this->email = dol_strtolower($this->email); + $this->personal_email = dol_strtolower($this->personal_email); } /** diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 2279aa90cdb..a65b49d4bb2 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1270,7 +1270,6 @@ class Societe extends CommonObject $this->address = $this->address ?trim($this->address) : trim($this->address); $this->zip = $this->zip ?trim($this->zip) : trim($this->zip); $this->town = $this->town ?trim($this->town) : trim($this->town); - $this->setUpperOrLowerCase(); $this->state_id = trim($this->state_id); $this->country_id = ($this->country_id > 0) ? $this->country_id : 0; $this->phone = trim($this->phone); @@ -1279,7 +1278,7 @@ class Societe extends CommonObject $this->fax = trim($this->fax); $this->fax = preg_replace("/\s/", "", $this->fax); $this->fax = preg_replace("/\./", "", $this->fax); - $this->email = dol_strtolower(trim($this->email)); + $this->email = trim($this->email); $this->url = $this->url ?clean_url($this->url, 0) : ''; $this->note_private = trim($this->note_private); $this->note_public = trim($this->note_public); @@ -1412,7 +1411,7 @@ class Societe extends CommonObject } } } - + $this->setUpperOrLowerCase(); if ($result >= 0) { dol_syslog(get_class($this)."::update verify ok or not done"); diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index fcd1505a402..6fca728ee8b 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1864,7 +1864,6 @@ class User extends CommonObject $this->address = trim((string) $this->address); $this->zip = trim((string) $this->zip); $this->town = trim((string) $this->town); - $this->setUpperOrLowerCase(); $this->state_id = ($this->state_id > 0 ? $this->state_id : 0); $this->country_id = ($this->country_id > 0 ? $this->country_id : 0); @@ -1891,6 +1890,8 @@ class User extends CommonObject $this->birth = empty($this->birth) ? '' : $this->birth; $this->fk_warehouse = (int) $this->fk_warehouse; + $this->setUpperOrLowerCase(); + // Check parameters $badCharUnauthorizedIntoLoginName = getDolGlobalString('MAIN_LOGIN_BADCHARUNAUTHORIZED', ',@<>"\''); From f984af7d13ac96bdf10f53f81b21bbaf36c051a7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 28 Jul 2022 15:35:57 +0200 Subject: [PATCH 084/205] css --- htdocs/core/menus/standard/eldy.lib.php | 54 ++++++++++++------------- htdocs/core/modules/modFTP.class.php | 3 +- htdocs/theme/eldy/global.inc.php | 4 +- htdocs/theme/md/style.css.php | 2 +- 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 6c8652b63a7..e2f11c9544c 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -112,7 +112,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = 'id' => $id, 'idsel' => 'members', 'classname' => $classname = (!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "members") ? 'class="tmenusel"' : 'class="tmenu"', - 'prefix' => img_picto('', 'member', 'class="fa-fw paddingright"'), + 'prefix' => img_picto('', 'member', 'class="fa-fw paddingright pictofixedwidth"'), 'session' => ((!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "members") ? 0 : 1), 'loadLangs' => array(), 'submenus' => array(), @@ -141,7 +141,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = 'id' => $id, 'idsel' => 'companies', 'classname' => $classname = (!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "companies") ? 'class="tmenusel"' : 'class="tmenu"', - 'prefix' => img_picto('', 'company', 'class="fa-fw paddingright"'), + 'prefix' => img_picto('', 'company', 'class="fa-fw paddingright pictofixedwidth"'), 'session' => ((!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "companies") ? 0 : 1), 'loadLangs' => array("companies", "suppliers"), 'submenus' => array(), @@ -168,7 +168,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = 'id' => $id, 'idsel' => 'products', 'classname' => $classname = (!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "products") ? 'class="tmenusel"' : 'class="tmenu"', - 'prefix' => img_picto('', 'product', 'class="fa-fw paddingright"'), + 'prefix' => img_picto('', 'product', 'class="fa-fw paddingright pictofixedwidth"'), 'session' => ((!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "products") ? 0 : 1), 'loadLangs' => array("products"), 'submenus' => array(), @@ -193,7 +193,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = 'id' => $id, 'idsel' => 'mrp', 'classname' => $classname = (!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "mrp") ? 'class="tmenusel"' : 'class="tmenu"', - 'prefix' => img_picto('', 'mrp', 'class="fa-fw paddingright"'), + 'prefix' => img_picto('', 'mrp', 'class="fa-fw paddingright pictofixedwidth"'), 'session' => ((!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "mrp") ? 0 : 1), 'loadLangs' => array("mrp"), 'submenus' => array(), @@ -218,7 +218,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = 'id' => $id, 'idsel' => 'project', 'classname' => $classname = (!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "project") ? 'class="tmenusel"' : 'class="tmenu"', - 'prefix' => img_picto('', 'project', 'class="fa-fw paddingright"'), + 'prefix' => img_picto('', 'project', 'class="fa-fw paddingright pictofixedwidth"'), 'session' => ((!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "project") ? 0 : 1), 'loadLangs' => array("projects"), 'submenus' => array(), @@ -267,7 +267,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = 'id' => $id, 'idsel' => 'commercial', 'classname' => $classname = (!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "commercial") ? 'class="tmenusel"' : 'class="tmenu"', - 'prefix' => img_picto('', 'contract', 'class="fa-fw paddingright"'), + 'prefix' => img_picto('', 'contract', 'class="fa-fw paddingright pictofixedwidth"'), 'session' => ((!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "commercial") ? 0 : 1), 'loadLangs' => array("commercial"), 'submenus' => array(), @@ -301,7 +301,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = 'id' => $id, 'idsel' => 'billing', 'classname' => $classname = (!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "billing") ? 'class="tmenusel"' : 'class="tmenu"', - 'prefix' => img_picto('', 'bill', 'class="fa-fw paddingright"'), + 'prefix' => img_picto('', 'bill', 'class="fa-fw paddingright pictofixedwidth"'), 'session' => ((!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "billing") ? 0 : 1), 'loadLangs' => array("compta"), 'submenus' => array(), @@ -326,7 +326,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = 'id' => $id, 'idsel' => 'bank', 'classname' => $classname = (!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "bank") ? 'class="tmenusel"' : 'class="tmenu"', - 'prefix' => img_picto('', 'bank_account', 'class="fa-fw paddingright"'), + 'prefix' => img_picto('', 'bank_account', 'class="fa-fw paddingright pictofixedwidth"'), 'session' => ((!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "bank") ? 0 : 1), 'loadLangs' => array("compta", "banks"), 'submenus' => array(), @@ -351,7 +351,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = 'id' => $id, 'idsel' => 'accountancy', 'classname' => $classname = (!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "accountancy") ? 'class="tmenusel"' : 'class="tmenu"', - 'prefix' => img_picto('', 'accountancy', 'class="fa-fw paddingright"'), + 'prefix' => img_picto('', 'accountancy', 'class="fa-fw paddingright pictofixedwidth"'), 'session' => ((!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "accountancy") ? 0 : 1), 'loadLangs' => array("compta", "accountancy", "assets", "intracommreport"), 'submenus' => array(), @@ -377,7 +377,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = 'id' => $id, 'idsel' => 'hrm', 'classname' => $classname = (!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "hrm") ? 'class="tmenusel"' : 'class="tmenu"', - 'prefix' => img_picto('', 'hrm', 'class="fa-fw paddingright"'), + 'prefix' => img_picto('', 'hrm', 'class="fa-fw paddingright pictofixedwidth"'), 'session' => ((!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "hrm") ? 0 : 1), 'loadLangs' => array("holiday"), 'submenus' => array(), @@ -408,7 +408,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = 'id' => $id, 'idsel' => 'ticket', 'classname' => $classname = (!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "ticket") ? 'class="tmenusel"' : 'class="tmenu"', - 'prefix' => img_picto('', 'ticket', 'class="fa-fw paddingright"'), + 'prefix' => img_picto('', 'ticket', 'class="fa-fw paddingright pictofixedwidth"'), 'session' => ((!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "ticket") ? 0 : 1), 'loadLangs' => array("other"), 'submenus' => array(), @@ -433,7 +433,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = 'id' => $id, 'idsel' => 'tools', 'classname' => $classname = (!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "tools") ? 'class="tmenusel"' : 'class="tmenu"', - 'prefix' => img_picto('', 'tools', 'class="fa-fw paddingright"'), + 'prefix' => img_picto('', 'tools', 'class="fa-fw paddingright pictofixedwidth"'), 'session' => ((!empty($_SESSION["mainmenu"]) && $_SESSION["mainmenu"] == "tools") ? 0 : 1), 'loadLangs' => array("other"), 'submenus' => array(), @@ -2129,7 +2129,7 @@ function get_left_menu_mrp($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = if (isModEnabled('bom') || isModEnabled('mrp')) { $langs->load("mrp"); - $newmenu->add("", $langs->trans("MenuBOM"), 0, $user->rights->bom->read, '', $mainmenu, 'bom', 0, '', '', '', img_picto('', 'bom', 'class="paddingrightonly pictofixedwidth"')); + $newmenu->add("", $langs->trans("MenuBOM"), 0, $user->rights->bom->read, '', $mainmenu, 'bom', 0, '', '', '', img_picto('', 'bom', 'class="paddingright pictofixedwidth"')); $newmenu->add("/bom/bom_card.php?leftmenu=bom&action=create", $langs->trans("NewBOM"), 1, $user->rights->bom->write, '', $mainmenu, 'bom'); $newmenu->add("/bom/bom_list.php?leftmenu=bom", $langs->trans("List"), 1, $user->rights->bom->read, '', $mainmenu, 'bom'); } @@ -2137,7 +2137,7 @@ function get_left_menu_mrp($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = if (isModEnabled('mrp')) { $langs->load("mrp"); - $newmenu->add("", $langs->trans("MenuMRP"), 0, $user->rights->mrp->read, '', $mainmenu, 'mo', 0, '', '', '', img_picto('', 'mrp', 'class="paddingrightonly pictofixedwidth"')); + $newmenu->add("", $langs->trans("MenuMRP"), 0, $user->rights->mrp->read, '', $mainmenu, 'mo', 0, '', '', '', img_picto('', 'mrp', 'class="paddingright pictofixedwidth"')); $newmenu->add("/mrp/mo_card.php?leftmenu=mo&action=create", $langs->trans("NewMO"), 1, $user->rights->mrp->write, '', $mainmenu, 'mo'); $newmenu->add("/mrp/mo_list.php?leftmenu=mo", $langs->trans("List"), 1, $user->rights->mrp->read, '', $mainmenu, 'mo'); } @@ -2184,7 +2184,7 @@ function get_left_menu_projects($mainmenu, &$newmenu, $usemenuhider = 1, $leftme } // Project assigned to user - $newmenu->add("/projet/index.php?leftmenu=projects".($search_project_user ? '&search_project_user='.$search_project_user : ''), $titleboth, 0, $user->rights->projet->lire, '', $mainmenu, 'projects', 0, '', '', '', img_picto('', 'project', 'class="pictofixedwidth"')); + $newmenu->add("/projet/index.php?leftmenu=projects".($search_project_user ? '&search_project_user='.$search_project_user : ''), $titleboth, 0, $user->rights->projet->lire, '', $mainmenu, 'projects', 0, '', '', '', img_picto('', 'project', 'class="paddingright pictofixedwidth"')); $newmenu->add("/projet/card.php?leftmenu=projects&action=create".($search_project_user ? '&search_project_user='.$search_project_user : ''), $titlenew, 1, $user->rights->projet->creer); if (empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { @@ -2207,12 +2207,12 @@ function get_left_menu_projects($mainmenu, &$newmenu, $usemenuhider = 1, $leftme if (empty($conf->global->PROJECT_HIDE_TASKS)) { // Project affected to user - $newmenu->add("/projet/activity/index.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("Activities"), 0, $user->rights->projet->lire, '', 'project', 'tasks', 0, '', '', '', img_picto('', 'projecttask', 'class="pictofixedwidth"')); + $newmenu->add("/projet/activity/index.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("Activities"), 0, $user->rights->projet->lire, '', 'project', 'tasks', 0, '', '', '', img_picto('', 'projecttask', 'class="paddingright pictofixedwidth"')); $newmenu->add("/projet/tasks.php?leftmenu=tasks&action=create", $langs->trans("NewTask"), 1, $user->rights->projet->creer); $newmenu->add("/projet/tasks/list.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("List"), 1, $user->rights->projet->lire); $newmenu->add("/projet/tasks/stats/index.php?leftmenu=projects", $langs->trans("Statistics"), 1, $user->rights->projet->lire); - $newmenu->add("/projet/activity/perweek.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("NewTimeSpent"), 0, $user->rights->projet->lire, '', 'project', 'timespent', 0, '', '', '', img_picto('', 'timespent', 'class="pictofixedwidth"')); + $newmenu->add("/projet/activity/perweek.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("NewTimeSpent"), 0, $user->rights->projet->lire, '', 'project', 'timespent', 0, '', '', '', img_picto('', 'timespent', 'class="paddingright pictofixedwidth"')); $newmenu->add("/projet/tasks/time.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("List"), 1, $user->rights->projet->lire); } } @@ -2238,29 +2238,29 @@ function get_left_menu_hrm($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = if (isModEnabled('hrm')) { $langs->load("hrm"); - $newmenu->add("/user/list.php?mainmenu=hrm&leftmenu=hrm&mode=employee", $langs->trans("Employees"), 0, $user->rights->user->user->lire, '', $mainmenu, 'hrm', 0, '', '', '', img_picto('', 'user', 'class="pictofixedwidth"')); + $newmenu->add("/user/list.php?mainmenu=hrm&leftmenu=hrm&mode=employee", $langs->trans("Employees"), 0, $user->rights->user->user->lire, '', $mainmenu, 'hrm', 0, '', '', '', img_picto('', 'user', 'class="paddingright pictofixedwidth"')); $newmenu->add("/user/card.php?mainmenu=hrm&leftmenu=hrm&action=create&employee=1", $langs->trans("NewEmployee"), 1, $user->rights->user->user->creer); $newmenu->add("/user/list.php?mainmenu=hrm&leftmenu=hrm&mode=employee&contextpage=employeelist", $langs->trans("List"), 1, $user->rights->user->user->lire); - $newmenu->add("/hrm/skill_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("SkillsManagement"), 0, $user->rights->hrm->all->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'shapes', 'class="pictofixedwidth"')); + $newmenu->add("/hrm/skill_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("SkillsManagement"), 0, $user->rights->hrm->all->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'shapes', 'class="paddingright pictofixedwidth"')); // Skills - $newmenu->add("/hrm/skill_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("Skills"), 1, $user->rights->hrm->all->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'shapes', 'class="pictofixedwidth"')); + $newmenu->add("/hrm/skill_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("Skills"), 1, $user->rights->hrm->all->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'shapes', 'class="paddingright pictofixedwidth"')); //$newmenu->add("/hrm/skill_card.php?mainmenu=hrm&leftmenu=hrm_sm&action=create", $langs->trans("NewSkill"), 1, $user->rights->hrm->all->write); //$newmenu->add("/hrm/skill_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("List"), 1, $user->rights->hrm->all->read); // Job (Description of work to do and skills required) - $newmenu->add("/hrm/job_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("JobsPosition"), 1, $user->rights->hrm->all->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'technic', 'class="pictofixedwidth"')); + $newmenu->add("/hrm/job_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("JobsPosition"), 1, $user->rights->hrm->all->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'technic', 'class="paddingright pictofixedwidth"')); //$newmenu->add("/hrm/job_card.php?mainmenu=hrm&leftmenu=hrm_sm&action=create", $langs->transnoentities("NewObject", $langs->trans("Job")), 1, $user->rights->hrm->all->write); //$newmenu->add("/hrm/job_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("List"), 1, $user->rights->hrm->all->read); // Position = Link job - user - $newmenu->add("/hrm/position_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("EmployeePositions"), 1, $user->rights->hrm->all->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'user-cog', 'class="pictofixedwidth"')); + $newmenu->add("/hrm/position_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("EmployeePositions"), 1, $user->rights->hrm->all->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'user-cog', 'class="paddingright pictofixedwidth"')); //$newmenu->add("/hrm/position.php?mainmenu=hrm&leftmenu=hrm_sm&action=create", $langs->transnoentities("NewObject", $langs->trans("Position")), 1, $user->rights->hrm->all->write); //$newmenu->add("/hrm/position_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("List"), 1, $user->rights->hrm->all->read); // Evaluation - $newmenu->add("/hrm/evaluation_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("Evals"), 1, $user->rights->hrm->evaluation->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'user', 'class="pictofixedwidth"')); + $newmenu->add("/hrm/evaluation_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("Evals"), 1, $user->rights->hrm->evaluation->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'user', 'class="paddingright pictofixedwidth"')); //$newmenu->add("/hrm/evaluation_card.php?mainmenu=hrm&leftmenu=hrm_sm&action=create", $langs->trans("NewEval"), 1, $user->rights->hrm->evaluation->write); //$newmenu->add("/hrm/evaluation_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("List"), 1, $user->rights->hrm->evaluation->read); $newmenu->add("/hrm/compare.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("SkillComparison"), 1, $user->rights->hrm->evaluation->read || $user->rights->hrm->compare_advance->read); @@ -2271,7 +2271,7 @@ function get_left_menu_hrm($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = // Load translation files required by the page $langs->loadLangs(array("holiday", "trips")); - $newmenu->add("/holiday/list.php?mainmenu=hrm&leftmenu=holiday", $langs->trans("CPTitreMenu"), 0, $user->rights->holiday->read, '', $mainmenu, 'holiday', 0, '', '', '', img_picto('', 'holiday', 'class="pictofixedwidth"')); + $newmenu->add("/holiday/list.php?mainmenu=hrm&leftmenu=holiday", $langs->trans("CPTitreMenu"), 0, $user->rights->holiday->read, '', $mainmenu, 'holiday', 0, '', '', '', img_picto('', 'holiday', 'class="paddingright pictofixedwidth"')); $newmenu->add("/holiday/card.php?mainmenu=hrm&leftmenu=holiday&action=create", $langs->trans("New"), 1, $user->rights->holiday->write, '', $mainmenu); $newmenu->add("/holiday/list.php?mainmenu=hrm&leftmenu=holiday", $langs->trans("List"), 1, $user->rights->holiday->read, '', $mainmenu); if ($usemenuhider || empty($leftmenu) || $leftmenu == "holiday") { @@ -2289,7 +2289,7 @@ function get_left_menu_hrm($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = // Trips and expenses (old module) if (isModEnabled('deplacement')) { $langs->load("trips"); - $newmenu->add("/compta/deplacement/index.php?leftmenu=tripsandexpenses&mainmenu=hrm", $langs->trans("TripsAndExpenses"), 0, $user->rights->deplacement->lire, '', $mainmenu, 'tripsandexpenses', 0, '', '', '', img_picto('', 'trip', 'class="pictofixedwidth"')); + $newmenu->add("/compta/deplacement/index.php?leftmenu=tripsandexpenses&mainmenu=hrm", $langs->trans("TripsAndExpenses"), 0, $user->rights->deplacement->lire, '', $mainmenu, 'tripsandexpenses', 0, '', '', '', img_picto('', 'trip', 'class="paddingright pictofixedwidth"')); $newmenu->add("/compta/deplacement/card.php?action=create&leftmenu=tripsandexpenses&mainmenu=hrm", $langs->trans("New"), 1, $user->rights->deplacement->creer); $newmenu->add("/compta/deplacement/list.php?leftmenu=tripsandexpenses&mainmenu=hrm", $langs->trans("List"), 1, $user->rights->deplacement->lire); $newmenu->add("/compta/deplacement/stats/index.php?leftmenu=tripsandexpenses&mainmenu=hrm", $langs->trans("Statistics"), 1, $user->rights->deplacement->lire); @@ -2298,7 +2298,7 @@ function get_left_menu_hrm($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = // Expense report if (isModEnabled('expensereport')) { $langs->loadLangs(array("trips", "bills")); - $newmenu->add("/expensereport/index.php?leftmenu=expensereport&mainmenu=hrm", $langs->trans("TripsAndExpenses"), 0, $user->rights->expensereport->lire, '', $mainmenu, 'expensereport', 0, '', '', '', img_picto('', 'trip', 'class="pictofixedwidth"')); + $newmenu->add("/expensereport/index.php?leftmenu=expensereport&mainmenu=hrm", $langs->trans("TripsAndExpenses"), 0, $user->rights->expensereport->lire, '', $mainmenu, 'expensereport', 0, '', '', '', img_picto('', 'trip', 'class="paddingright pictofixedwidth"')); $newmenu->add("/expensereport/card.php?action=create&leftmenu=expensereport&mainmenu=hrm", $langs->trans("New"), 1, $user->rights->expensereport->creer); $newmenu->add("/expensereport/list.php?leftmenu=expensereport&mainmenu=hrm", $langs->trans("List"), 1, $user->rights->expensereport->lire); if ($usemenuhider || empty($leftmenu) || $leftmenu == "expensereport") { @@ -2319,7 +2319,7 @@ function get_left_menu_hrm($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = $search_project_user = GETPOST('search_project_user', 'int'); - $newmenu->add("/projet/activity/perweek.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("NewTimeSpent"), 0, $user->rights->projet->lire, '', $mainmenu, 'timespent', 0, '', '', '', img_picto('', 'timespent', 'class="pictofixedwidth"')); + $newmenu->add("/projet/activity/perweek.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("NewTimeSpent"), 0, $user->rights->projet->lire, '', $mainmenu, 'timespent', 0, '', '', '', img_picto('', 'timespent', 'class="paddingright pictofixedwidth"')); } } } diff --git a/htdocs/core/modules/modFTP.class.php b/htdocs/core/modules/modFTP.class.php index 3e2ccd7d049..7cde492b2c3 100644 --- a/htdocs/core/modules/modFTP.class.php +++ b/htdocs/core/modules/modFTP.class.php @@ -58,7 +58,7 @@ class modFTP extends DolibarrModules // Key used in llx_const table to save module status enabled/disabled (XXX is id value) $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Name of png file (without png) used for this module - $this->picto = 'dir'; + $this->picto = 'folder'; // Data directories to create when module is enabled $this->dirs = array("/ftp/temp"); @@ -114,6 +114,7 @@ class modFTP extends DolibarrModules $this->menu[$r] = array('fk_menu'=>0, 'type'=>'top', 'titre'=>'FTP', + 'prefix' => img_picto('', $this->picto, 'class="paddingright pictofixedwidth em092"'), 'mainmenu'=>'ftp', 'url'=>'/ftp/index.php', 'langs'=>'ftp', diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 8b2cbced058..f3287de4159 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -2310,7 +2310,7 @@ span.widthpictotitle.pictotitle { .pictofixedwidth { text-align: ; width: 20px; - padding-right: 0; + /* padding-right: 0; */ } .colorthumb { @@ -7641,7 +7641,7 @@ div.clipboardCPValue.hidewithsize { } .lilevel1 span.paddingright { - padding-right: 3px; + padding-right: 4px; } } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 065ab494551..975a7d4bb04 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2339,7 +2339,7 @@ img.hideonsmartphone.pictoactionview { .pictofixedwidth { text-align: ; width: 20px; - padding-right: 0; + /* padding-right: 0; */ } .colorthumb { From 915380202c20e8b368117c0b4b90c1a39a69f0c9 Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Thu, 28 Jul 2022 17:09:56 +0200 Subject: [PATCH 085/205] FIX - php V8 pdf lib --- htdocs/core/lib/pdf.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index ff0350a9552..be89f4700b8 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -453,7 +453,7 @@ function pdf_build_address($outputlangs, $sourcecompany, $targetcompany = '', $t if (empty($reshook)) { if ($mode == 'source') { $withCountry = 0; - if (!empty($sourcecompany->country_code) && ($targetcompany->country_code != $sourcecompany->country_code)) { + if (isset($targetcompany->country_code) && !empty($sourcecompany->country_code) && ($targetcompany->country_code != $sourcecompany->country_code)) { $withCountry = 1; } From df727f3b5dd79ac7c3766be7bebe200ddad7add1 Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Thu, 28 Jul 2022 17:22:21 +0200 Subject: [PATCH 086/205] FIX - Add colone last_main_doc in societe for migration Error to generate doc --- htdocs/install/mysql/migration/16.0.0-17.0.0.sql | 1 + htdocs/societe/class/societe.class.php | 1 + 2 files changed, 2 insertions(+) diff --git a/htdocs/install/mysql/migration/16.0.0-17.0.0.sql b/htdocs/install/mysql/migration/16.0.0-17.0.0.sql index 6713d410fc6..24b4e20a7b7 100644 --- a/htdocs/install/mysql/migration/16.0.0-17.0.0.sql +++ b/htdocs/install/mysql/migration/16.0.0-17.0.0.sql @@ -62,4 +62,5 @@ ALTER TABLE llx_inventory ADD COLUMN categories_product VARCHAR(255) DEFAULT NUL ALTER TABLE llx_ticket ADD COLUMN ip varchar(250); +ALTER TABLE llx_societe ADD last_main_doc VARCHAR(255) NULL AFTER model_pdf; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 90766323080..a3f3c45806f 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -232,6 +232,7 @@ class Societe extends CommonObject 'fk_incoterms' =>array('type'=>'integer', 'label'=>'Fk incoterms', 'enabled'=>1, 'visible'=>-1, 'position'=>425), 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'Location incoterms', 'enabled'=>1, 'visible'=>-1, 'position'=>430), 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>435), + 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>-1, 'position'=>270), 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'Fk multicurrency', 'enabled'=>1, 'visible'=>-1, 'position'=>440), 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'Multicurrency code', 'enabled'=>1, 'visible'=>-1, 'position'=>445), 'fk_account' =>array('type'=>'integer', 'label'=>'AccountingAccount', 'enabled'=>1, 'visible'=>-1, 'position'=>450), From 0fe441bc2a9f7ecad8cad7d7403041f86a4b1439 Mon Sep 17 00:00:00 2001 From: Christophe Battarel Date: Thu, 28 Jul 2022 17:29:09 +0200 Subject: [PATCH 087/205] use getDolGlobal... --- htdocs/core/lib/takepos.lib.php | 2 +- htdocs/takepos/admin/terminal.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/takepos.lib.php b/htdocs/core/lib/takepos.lib.php index 66ea16a6123..c2468c98169 100644 --- a/htdocs/core/lib/takepos.lib.php +++ b/htdocs/core/lib/takepos.lib.php @@ -56,7 +56,7 @@ function takepos_admin_prepare_head() $numterminals = max(1, $conf->global->TAKEPOS_NUM_TERMINALS); for ($i = 1; $i <= $numterminals; $i++) { $head[$h][0] = DOL_URL_ROOT.'/takepos/admin/terminal.php?terminal='.$i; - $head[$h][1] = (! empty($conf->global->{"TAKEPOS_TERMINAL_NAME_".$i}) ? $conf->global->{"TAKEPOS_TERMINAL_NAME_".$i} : $langs->trans("TerminalName", $i)); + $head[$h][1] = getDolGlobalString('TAKEPOS_TERMINAL_NAME_'.$i, $langs->trans("TerminalName", $i)); $head[$h][2] = 'terminal'.$i; $h++; } diff --git a/htdocs/takepos/admin/terminal.php b/htdocs/takepos/admin/terminal.php index 29bc7fa5712..0bfe4ebd080 100644 --- a/htdocs/takepos/admin/terminal.php +++ b/htdocs/takepos/admin/terminal.php @@ -152,7 +152,7 @@ print "\n"; print ''.$langs->trans("TerminalNameDesc").''; print ''; -print 'global->{"TAKEPOS_TERMINAL_NAME_".$terminal} : $langs->trans("TerminalName", $terminal)).'" >'; +print 'trans("TerminalName", $terminal)).'" >'; print ''; print ''.$langs->trans("CashDeskThirdPartyForSell").''; From 4b3fdcc9f60fb92e0f3f4722ec5408bf06203753 Mon Sep 17 00:00:00 2001 From: Christophe Battarel Date: Thu, 28 Jul 2022 17:36:58 +0200 Subject: [PATCH 088/205] use getDolGlobal... --- htdocs/takepos/index.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index 8cbdd7adb13..e9717e7c992 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -955,7 +955,7 @@ if (empty($conf->global->TAKEPOS_HIDE_HEAD_BAR)) { - global->{"TAKEPOS_TERMINAL_NAME_".$_SESSION["takeposterminal"]}) ? $conf->global->{"TAKEPOS_TERMINAL_NAME_".$_SESSION["takeposterminal"]} : $langs->trans("TerminalName", $_SESSION["takeposterminal"])); ?> + trans("TerminalName", $_SESSION["takeposterminal"])); ?> - '.dol_print_date(dol_now(), "day").''; @@ -1014,11 +1014,11 @@ if (empty($conf->global->TAKEPOS_HIDE_HEAD_BAR)) {

trans("TerminalSelect"); ?>

From 3da20beeb543cf242e2c844ad1dcaafea5563ec7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 28 Jul 2022 18:06:37 +0200 Subject: [PATCH 089/205] Fix warning --- htdocs/bom/class/bom.class.php | 2 +- htdocs/core/ajax/selectsearchbox.php | 41 +++++++++++++-------------- htdocs/fichinter/list.php | 6 ++-- htdocs/main.inc.php | 2 +- htdocs/projet/class/project.class.php | 2 +- 5 files changed, 26 insertions(+), 27 deletions(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 655af8b0a1f..8adcac855c2 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -96,7 +96,7 @@ class BOM extends CommonObject public $fields = array( 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",), 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=> 1, 'default'=>1, 'index'=>1, 'position'=>5), - 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'noteditable'=>1, 'visible'=>4, 'position'=>10, 'notnull'=>1, 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of BOM", 'showoncombobox'=>'1',), + 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'noteditable'=>1, 'visible'=>4, 'position'=>10, 'notnull'=>1, 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of BOM", 'showoncombobox'=>'1', 'csslist'=>'nowraponall'), 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'notnull'=>1, 'searchall'=>1, 'showoncombobox'=>'2', 'autofocusoncreate'=>1, 'css'=>'minwidth300 maxwidth400', 'csslist'=>'tdoverflowmax200'), 'bomtype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>1, 'position'=>33, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing', 1=>'Disassemble'), 'css'=>'minwidth175', 'csslist'=>'minwidth175 center'), //'bomtype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>-1, 'position'=>32, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing')), diff --git a/htdocs/core/ajax/selectsearchbox.php b/htdocs/core/ajax/selectsearchbox.php index c1199477f58..090fc52cb4f 100644 --- a/htdocs/core/ajax/selectsearchbox.php +++ b/htdocs/core/ajax/selectsearchbox.php @@ -64,7 +64,7 @@ $arrayresult = array(); // Define $searchform -if (!empty($conf->adherent->enabled) && empty($conf->global->MAIN_SEARCHFORM_ADHERENT_DISABLED) && $user->rights->adherent->lire) { +if (isModEnabled('adherent') && empty($conf->global->MAIN_SEARCHFORM_ADHERENT_DISABLED) && $user->rights->adherent->lire) { $arrayresult['searchintomember'] = array('position'=>8, 'shortcut'=>'M', 'img'=>'object_member', 'label'=>$langs->trans("SearchIntoMembers", $search_boxvalue), 'text'=>img_picto('', 'object_member', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoMembers", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/adherents/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } @@ -72,44 +72,43 @@ if (((!empty($conf->societe->enabled) && (empty($conf->global->SOCIETE_DISABLE_P $arrayresult['searchintothirdparty'] = array('position'=>10, 'shortcut'=>'T', 'img'=>'object_company', 'label'=>$langs->trans("SearchIntoThirdparties", $search_boxvalue), 'text'=>img_picto('', 'object_company', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoThirdparties", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/societe/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (!empty($conf->societe->enabled) && empty($conf->global->MAIN_SEARCHFORM_CONTACT_DISABLED) && $user->rights->societe->lire) { +if (isModEnabled('societe') && empty($conf->global->MAIN_SEARCHFORM_CONTACT_DISABLED) && $user->hasRight('societe', 'lire')) { $arrayresult['searchintocontact'] = array('position'=>15, 'shortcut'=>'A', 'img'=>'object_contact', 'label'=>$langs->trans("SearchIntoContacts", $search_boxvalue), 'text'=>img_picto('', 'object_contact', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoContacts", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/contact/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (((!empty($conf->product->enabled) && $user->rights->produit->lire) || (!empty($conf->service->enabled) && $user->rights->service->lire)) -&& empty($conf->global->MAIN_SEARCHFORM_PRODUITSERVICE_DISABLED)) { +if (((!empty($conf->product->enabled) && $user->hasRight('produit', 'lire')) || (!empty($conf->service->enabled) && $user->hasRight('service', 'lire'))) && empty($conf->global->MAIN_SEARCHFORM_PRODUITSERVICE_DISABLED)) { $arrayresult['searchintoproduct'] = array('position'=>30, 'shortcut'=>'P', 'img'=>'object_product', 'label'=>$langs->trans("SearchIntoProductsOrServices", $search_boxvalue), 'text'=>img_picto('', 'object_product', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoProductsOrServices", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/product/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); // search on lot/serial numbers - if ( ! empty($conf->productbatch->enabled) ) { + if (isModEnabled('productbatch')) { $arrayresult['searchintobatch'] = array('position'=>32, 'shortcut'=>'B', 'img'=>'object_lot', 'label'=>$langs->trans("SearchIntoBatch", $search_boxvalue), 'text'=>img_picto('', 'object_lot', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoBatch", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/product/stock/productlot_list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } } -if (!empty($conf->mrp->enabled) && $user->rights->mrp->read && empty($conf->global->MAIN_SEARCHFORM_MRP_DISABLED)) { +if (isModEnabled('mrp') && $user->hasRight('mrp', 'read') && empty($conf->global->MAIN_SEARCHFORM_MRP_DISABLED)) { $arrayresult['searchintomo'] = array('position'=>35, 'shortcut'=>'', 'img'=>'object_mrp', 'label'=>$langs->trans("SearchIntoMO", $search_boxvalue), 'text'=>img_picto('', 'object_mrp', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoMO", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/mrp/mo_list.php'.($search_boxvalue ? '?search_all='.urlencode($search_boxvalue) : '')); } -if (!empty($conf->project->enabled) && empty($conf->global->MAIN_SEARCHFORM_PROJECT_DISABLED) && $user->rights->projet->lire) { +if (isModEnabled('project') && empty($conf->global->MAIN_SEARCHFORM_PROJECT_DISABLED) && $user->hasRight('projet', 'lire')) { $arrayresult['searchintoprojects'] = array('position'=>40, 'shortcut'=>'Q', 'img'=>'object_project', 'label'=>$langs->trans("SearchIntoProjects", $search_boxvalue), 'text'=>img_picto('', 'object_project', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoProjects", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/projet/list.php'.($search_boxvalue ? '?search_all='.urlencode($search_boxvalue) : '')); } -if (!empty($conf->project->enabled) && empty($conf->global->MAIN_SEARCHFORM_TASK_DISABLED) && $user->rights->projet->lire) { +if (isModEnabled('project') && empty($conf->global->MAIN_SEARCHFORM_TASK_DISABLED) && $user->hasRight('projet', 'lire')) { $arrayresult['searchintotasks'] = array('position'=>45, 'img'=>'object_projecttask', 'label'=>$langs->trans("SearchIntoTasks", $search_boxvalue), 'text'=>img_picto('', 'object_projecttask', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoTasks", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/projet/tasks/list.php'.($search_boxvalue ? '?search_all='.urlencode($search_boxvalue) : '')); } -if (!empty($conf->propal->enabled) && empty($conf->global->MAIN_SEARCHFORM_CUSTOMER_PROPAL_DISABLED) && $user->rights->propal->lire) { +if (isModEnabled('propal') && empty($conf->global->MAIN_SEARCHFORM_CUSTOMER_PROPAL_DISABLED) && $user->hasRight('propal', 'lire')) { $arrayresult['searchintopropal'] = array('position'=>60, 'img'=>'object_propal', 'label'=>$langs->trans("SearchIntoCustomerProposals", $search_boxvalue), 'text'=>img_picto('', 'object_propal', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoCustomerProposals", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/comm/propal/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (!empty($conf->commande->enabled) && empty($conf->global->MAIN_SEARCHFORM_CUSTOMER_ORDER_DISABLED) && $user->rights->commande->lire) { +if (isModEnabled('commande') && empty($conf->global->MAIN_SEARCHFORM_CUSTOMER_ORDER_DISABLED) && $user->hasRight('commande', 'lire')) { $arrayresult['searchintoorder'] = array('position'=>70, 'img'=>'object_order', 'label'=>$langs->trans("SearchIntoCustomerOrders", $search_boxvalue), 'text'=>img_picto('', 'object_order', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoCustomerOrders", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/commande/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (!empty($conf->expedition->enabled) && empty($conf->global->MAIN_SEARCHFORM_CUSTOMER_SHIPMENT_DISABLED) && $user->rights->expedition->lire) { +if (isModEnabled('expedition') && empty($conf->global->MAIN_SEARCHFORM_CUSTOMER_SHIPMENT_DISABLED) && $user->hasRight('expedition', 'lire')) { $arrayresult['searchintoshipment'] = array('position'=>80, 'img'=>'object_shipment', 'label'=>$langs->trans("SearchIntoCustomerShipments", $search_boxvalue), 'text'=>img_picto('', 'object_shipment', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoCustomerShipments", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/expedition/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (isModEnabled('facture') && empty($conf->global->MAIN_SEARCHFORM_CUSTOMER_INVOICE_DISABLED) && $user->rights->facture->lire) { +if (isModEnabled('facture') && empty($conf->global->MAIN_SEARCHFORM_CUSTOMER_INVOICE_DISABLED) && $user->hasRight('facture', 'lire')) { $arrayresult['searchintoinvoice'] = array('position'=>90, 'img'=>'object_bill', 'label'=>$langs->trans("SearchIntoCustomerInvoices", $search_boxvalue), 'text'=>img_picto('', 'object_bill', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoCustomerInvoices", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/compta/facture/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (!empty($conf->supplier_proposal->enabled) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_PROPAL_DISABLED) && $user->rights->supplier_proposal->lire) { +if (isModEnabled('supplier_proposal') && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_PROPAL_DISABLED) && $user->rights->supplier_proposal->lire) { $arrayresult['searchintosupplierpropal'] = array('position'=>100, 'img'=>'object_supplier_proposal', 'label'=>$langs->trans("SearchIntoSupplierProposals", $search_boxvalue), 'text'=>img_picto('', 'object_supplier_proposal', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoSupplierProposals", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/supplier_proposal/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->commande->lire) || (!empty($conf->supplier_order->enabled) && $user->rights->supplier_order->lire)) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_ORDER_DISABLED)) { @@ -120,7 +119,7 @@ if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_S } // Customer payments -if (isModEnabled('facture') && empty($conf->global->MAIN_SEARCHFORM_CUSTOMER_INVOICE_DISABLED) && $user->rights->facture->lire) { +if (isModEnabled('facture') && empty($conf->global->MAIN_SEARCHFORM_CUSTOMER_INVOICE_DISABLED) && $user->hasRight('facture', 'lire')) { $arrayresult['searchintocustomerpayments'] = array( 'position'=>170, 'img'=>'object_payment', @@ -140,7 +139,7 @@ if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_S } // Miscellaneous payments -if (!empty($conf->banque->enabled) && empty($conf->global->MAIN_SEARCHFORM_MISC_PAYMENTS_DISABLED) && $user->rights->banque->lire) { +if (isModEnabled('banque') && empty($conf->global->MAIN_SEARCHFORM_MISC_PAYMENTS_DISABLED) && $user->rights->banque->lire) { $arrayresult['searchintomiscpayments'] = array( 'position'=>180, 'img'=>'object_payment', @@ -149,24 +148,24 @@ if (!empty($conf->banque->enabled) && empty($conf->global->MAIN_SEARCHFORM_MISC_ 'url'=>DOL_URL_ROOT.'/compta/bank/various_payment/list.php?leftmenu=tax_various'.($search_boxvalue ? '&sall='.urlencode($search_boxvalue) : '')); } -if (!empty($conf->contrat->enabled) && empty($conf->global->MAIN_SEARCHFORM_CONTRACT_DISABLED) && $user->rights->contrat->lire) { +if (isModEnabled('contrat') && empty($conf->global->MAIN_SEARCHFORM_CONTRACT_DISABLED) && $user->rights->contrat->lire) { $arrayresult['searchintocontract'] = array('position'=>130, 'img'=>'object_contract', 'label'=>$langs->trans("SearchIntoContracts", $search_boxvalue), 'text'=>img_picto('', 'object_contract', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoContracts", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/contrat/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (!empty($conf->ficheinter->enabled) && empty($conf->global->MAIN_SEARCHFORM_FICHINTER_DISABLED) && $user->rights->ficheinter->lire) { +if (isModEnabled('ficheinter') && empty($conf->global->MAIN_SEARCHFORM_FICHINTER_DISABLED) && $user->rights->ficheinter->lire) { $arrayresult['searchintointervention'] = array('position'=>140, 'img'=>'object_intervention', 'label'=>$langs->trans("SearchIntoInterventions", $search_boxvalue), 'text'=>img_picto('', 'object_intervention', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoInterventions", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/fichinter/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (!empty($conf->ticket->enabled) && empty($conf->global->MAIN_SEARCHFORM_TICKET_DISABLED) && $user->rights->ticket->read) { +if (isModEnabled('ticket') && empty($conf->global->MAIN_SEARCHFORM_TICKET_DISABLED) && $user->rights->ticket->read) { $arrayresult['searchintotickets'] = array('position'=>145, 'img'=>'object_ticket', 'label'=>$langs->trans("SearchIntoTickets", $search_boxvalue), 'text'=>img_picto('', 'object_ticket', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoTickets", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/ticket/list.php?mainmenu=ticket'.($search_boxvalue ? '&sall='.urlencode($search_boxvalue) : '')); } // HR -if (!empty($conf->user->enabled) && empty($conf->global->MAIN_SEARCHFORM_USER_DISABLED) && $user->rights->user->user->lire) { +if (isModEnabled('user') && empty($conf->global->MAIN_SEARCHFORM_USER_DISABLED) && $user->rights->user->user->lire) { $arrayresult['searchintouser'] = array('position'=>200, 'shortcut'=>'U', 'img'=>'object_user', 'label'=>$langs->trans("SearchIntoUsers", $search_boxvalue), 'text'=>img_picto('', 'object_user', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoUsers", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/user/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (!empty($conf->expensereport->enabled) && empty($conf->global->MAIN_SEARCHFORM_EXPENSEREPORT_DISABLED) && $user->rights->expensereport->lire) { +if (isModEnabled('expensereport') && empty($conf->global->MAIN_SEARCHFORM_EXPENSEREPORT_DISABLED) && $user->rights->expensereport->lire) { $arrayresult['searchintoexpensereport'] = array('position'=>210, 'img'=>'object_trip', 'label'=>$langs->trans("SearchIntoExpenseReports", $search_boxvalue), 'text'=>img_picto('', 'object_trip', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoExpenseReports", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/expensereport/list.php?mainmenu=hrm'.($search_boxvalue ? '&sall='.urlencode($search_boxvalue) : '')); } -if (!empty($conf->holiday->enabled) && empty($conf->global->MAIN_SEARCHFORM_HOLIDAY_DISABLED) && $user->rights->holiday->read) { +if (isModEnabled('holiday') && empty($conf->global->MAIN_SEARCHFORM_HOLIDAY_DISABLED) && $user->rights->holiday->read) { $arrayresult['searchintoleaves'] = array('position'=>220, 'img'=>'object_holiday', 'label'=>$langs->trans("SearchIntoLeaves", $search_boxvalue), 'text'=>img_picto('', 'object_holiday', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoLeaves", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/holiday/list.php?mainmenu=hrm'.($search_boxvalue ? '&sall='.urlencode($search_boxvalue) : '')); } diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index ef71f01e228..d8bb62f6b5d 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -316,7 +316,7 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; // Add GroupBy from hooks -$parameters = array('all' => $all, 'fieldstosearchall' => $fieldstosearchall); +$parameters = array('search_all' => $sall, 'fieldstosearchall' => $fieldstosearchall); $reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; @@ -692,7 +692,7 @@ while ($i < $imaxinloop) { print ''; // Picto + Ref - print ''; // Warning @@ -726,7 +726,7 @@ while ($i < $imaxinloop) { if (!empty($arrayfields['f.ref_client']['checked'])) { // Customer ref print ''; if (!$i) { $totalarray['nbfield']++; diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 091c6fb1266..49c427ace71 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -2818,7 +2818,7 @@ function left_menu($menu_array_before, $helppagename = '', $notused = '', $menu_ } else { if (is_array($arrayresult)) { foreach ($arrayresult as $key => $val) { - $searchform .= printSearchForm($val['url'], $val['url'], $val['label'], 'maxwidth125', 'sall', $val['shortcut'], 'searchleft'.$key, $val['img']); + $searchform .= printSearchForm($val['url'], $val['url'], $val['label'], 'maxwidth125', 'sall', (empty($val['shortcut']) ? '' : $val['shortcut']), 'searchleft'.$key, $val['img']); } } } diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 8c48b7b1ae6..f395173b327 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -1272,7 +1272,7 @@ class Project extends CommonObject } $linkclose = ''; - if (empty($notooltip) && $user->rights->projet->lire) { + if (empty($notooltip) && $user->hasRight('projet', 'lire')) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowProject"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; From ce87eea3ec842358de9664a42eb53717a8c78af3 Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Thu, 28 Jul 2022 18:18:04 +0200 Subject: [PATCH 090/205] ErrorFTPNodisconnect --- htdocs/core/lib/ftp.lib.php | 153 +++++++++++++++++++++++++++++++++ htdocs/ftp/admin/ftpclient.php | 2 +- htdocs/ftp/index.php | 126 ++------------------------- htdocs/langs/en_US/ftp.lang | 15 ++++ htdocs/langs/en_US/other.lang | 15 ---- 5 files changed, 176 insertions(+), 135 deletions(-) create mode 100644 htdocs/core/lib/ftp.lib.php create mode 100644 htdocs/langs/en_US/ftp.lang diff --git a/htdocs/core/lib/ftp.lib.php b/htdocs/core/lib/ftp.lib.php new file mode 100644 index 00000000000..1730a439bcb --- /dev/null +++ b/htdocs/core/lib/ftp.lib.php @@ -0,0 +1,153 @@ + + * Copyright (C) 2022 Anthony Berton + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/core/lib/ftp.lib.php + * \brief Set of functions used for FTP + * \ingroup core + */ + + + + +/** + * Connect to FTP server + * + * @param string $ftp_server Server name + * @param string $ftp_port Server port + * @param string $ftp_user FTP user + * @param string $ftp_password FTP password + * @param string $section Directory + * @param integer $ftp_passive Use a passive mode + * @return int <0 if OK, >0 if KO + */ +function dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $section, $ftp_passive = 0) +{ + global $langs, $conf; + + $ok = 1; + $error = 0; + $conn_id = null; + $newsectioniso = ''; + $mesg=""; + + if (!is_numeric($ftp_port)) { + $mesg = $langs->transnoentitiesnoconv("FailedToConnectToFTPServer", $ftp_server, $ftp_port); + $ok = 0; + } + + if ($ok) { + $connecttimeout = (empty($conf->global->FTP_CONNECT_TIMEOUT) ? 40 : $conf->global->FTP_CONNECT_TIMEOUT); + if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { + dol_syslog('Try to connect with ssh2_connect'); + $tmp_conn_id = ssh2_connect($ftp_server, $ftp_port); + } elseif (!empty($conf->global->FTP_CONNECT_WITH_SSL)) { + dol_syslog('Try to connect with ftp_ssl_connect'); + $conn_id = ftp_ssl_connect($ftp_server, $ftp_port, $connecttimeout); + } else { + dol_syslog('Try to connect with ftp_connect'); + $conn_id = ftp_connect($ftp_server, $ftp_port, $connecttimeout); + } + if (!empty($conn_id) || !empty($tmp_conn_id)) { + if ($ftp_user) { + if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { + dol_syslog('Try to authenticate with ssh2_auth_password'); + if (ssh2_auth_password($tmp_conn_id, $ftp_user, $ftp_password)) { + // Turn on passive mode transfers (must be after a successful login + //if ($ftp_passive) ftp_pasv($conn_id, true); + + // Change the dir + $newsectioniso = utf8_decode($section); + //ftp_chdir($conn_id, $newsectioniso); + $conn_id = ssh2_sftp($tmp_conn_id); + if (!$conn_id) { + dol_syslog('Failed to connect to SFTP after sssh authentication', LOG_DEBUG); + $mesg = $langs->transnoentitiesnoconv("FailedToConnectToSFTPAfterSSHAuthentication"); + $ok = 0; + $error++; + } + } else { + dol_syslog('Failed to connect to FTP with login '.$ftp_user, LOG_DEBUG); + $mesg = $langs->transnoentitiesnoconv("FailedToConnectToFTPServerWithCredentials"); + $ok = 0; + $error++; + } + } else { + if (ftp_login($conn_id, $ftp_user, $ftp_password)) { + // Turn on passive mode transfers (must be after a successful login + if ($ftp_passive) { + ftp_pasv($conn_id, true); + } + + // Change the dir + $newsectioniso = utf8_decode($section); + ftp_chdir($conn_id, $newsectioniso); + } else { + $mesg = $langs->transnoentitiesnoconv("FailedToConnectToFTPServerWithCredentials"); + $ok = 0; + $error++; + } + } + } + } else { + dol_syslog('FailedToConnectToFTPServer '.$ftp_server.' '.$ftp_port, LOG_ERR); + $mesg = $langs->transnoentitiesnoconv("FailedToConnectToFTPServer", $ftp_server, $ftp_port); + $ok = 0; + } + } + + $arrayresult = array('conn_id'=>$conn_id, 'ok'=>$ok, 'mesg'=>$mesg, 'curdir'=>$section, 'curdiriso'=>$newsectioniso); + return $arrayresult; +} + + +/** + * Tell if an entry is a FTP directory + * + * @param resource $connect_id Connection handler + * @param string $dir Directory + * @return int 1=directory, 0=not a directory + */ +function ftp_isdir($connect_id, $dir) +{ + if (@ftp_chdir($connect_id, $dir)) { + ftp_cdup($connect_id); + return 1; + } else { + return 0; + } +} + +/** + * Tell if an entry is a FTP directory + * + * @param resource $connect_id Connection handler + */ +function dol_ftp_close($connect_id) +{ + // Close FTP connection + if ($connect_id) { + if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { + } elseif (!empty($conf->global->FTP_CONNECT_WITH_SSL)) { + return ftp_close($connect_id); + } else { + return ftp_close($connect_id); + } + } +} \ No newline at end of file diff --git a/htdocs/ftp/admin/ftpclient.php b/htdocs/ftp/admin/ftpclient.php index c3d5509aa36..f914c835b37 100644 --- a/htdocs/ftp/admin/ftpclient.php +++ b/htdocs/ftp/admin/ftpclient.php @@ -25,7 +25,7 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -$langs->loadLangs(array("admin", "other")); +$langs->loadLangs(array('ftp', "admin", "other")); $def = array(); $lastftpentry = 0; diff --git a/htdocs/ftp/index.php b/htdocs/ftp/index.php index 626703d4b68..54e66e845d4 100644 --- a/htdocs/ftp/index.php +++ b/htdocs/ftp/index.php @@ -27,9 +27,10 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/treeview.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/ftp.lib.php'; // Load translation files required by the page -$langs->loadLangs(array('companies', 'other')); +$langs->loadLangs(array('ftp', 'companies', 'other')); // Security check if ($user->socid) { @@ -665,127 +666,14 @@ if (!function_exists('ftp_connect')) { print '
'; -// Close FTP connection -if ($conn_id) { - if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { - } elseif (!empty($conf->global->FTP_CONNECT_WITH_SSL)) { - ftp_close($conn_id); - } else { - ftp_close($conn_id); +if (!empty($conn_id)) { + $disconnect = dol_ftp_close($conn_id); + + if ($disconnect == false) { + setEventMessages($langs->trans("ErrorFTPNodisconnect"), null, 'errors'); } } // End of page llxFooter(); $db->close(); - - - -/** - * Connect to FTP server - * - * @param string $ftp_server Server name - * @param string $ftp_port Server port - * @param string $ftp_user FTP user - * @param string $ftp_password FTP password - * @param string $section Directory - * @param integer $ftp_passive Use a passive mode - * @return int <0 if OK, >0 if KO - */ -function dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $section, $ftp_passive = 0) -{ - global $langs, $conf; - - $ok = 1; - $error = 0; - $conn_id = null; - $newsectioniso = ''; - $mesg=""; - - if (!is_numeric($ftp_port)) { - $mesg = $langs->transnoentitiesnoconv("FailedToConnectToFTPServer", $ftp_server, $ftp_port); - $ok = 0; - } - - if ($ok) { - $connecttimeout = (empty($conf->global->FTP_CONNECT_TIMEOUT) ? 40 : $conf->global->FTP_CONNECT_TIMEOUT); - if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { - dol_syslog('Try to connect with ssh2_connect'); - $tmp_conn_id = ssh2_connect($ftp_server, $ftp_port); - } elseif (!empty($conf->global->FTP_CONNECT_WITH_SSL)) { - dol_syslog('Try to connect with ftp_ssl_connect'); - $conn_id = ftp_ssl_connect($ftp_server, $ftp_port, $connecttimeout); - } else { - dol_syslog('Try to connect with ftp_connect'); - $conn_id = ftp_connect($ftp_server, $ftp_port, $connecttimeout); - } - if (!empty($conn_id) || !empty($tmp_conn_id)) { - if ($ftp_user) { - if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { - dol_syslog('Try to authenticate with ssh2_auth_password'); - if (ssh2_auth_password($tmp_conn_id, $ftp_user, $ftp_password)) { - // Turn on passive mode transfers (must be after a successful login - //if ($ftp_passive) ftp_pasv($conn_id, true); - - // Change the dir - $newsectioniso = utf8_decode($section); - //ftp_chdir($conn_id, $newsectioniso); - $conn_id = ssh2_sftp($tmp_conn_id); - if (!$conn_id) { - dol_syslog('Failed to connect to SFTP after sssh authentication', LOG_DEBUG); - $mesg = $langs->transnoentitiesnoconv("FailedToConnectToSFTPAfterSSHAuthentication"); - $ok = 0; - $error++; - } - } else { - dol_syslog('Failed to connect to FTP with login '.$ftp_user, LOG_DEBUG); - $mesg = $langs->transnoentitiesnoconv("FailedToConnectToFTPServerWithCredentials"); - $ok = 0; - $error++; - } - } else { - if (ftp_login($conn_id, $ftp_user, $ftp_password)) { - // Turn on passive mode transfers (must be after a successful login - if ($ftp_passive) { - ftp_pasv($conn_id, true); - } - - // Change the dir - $newsectioniso = utf8_decode($section); - ftp_chdir($conn_id, $newsectioniso); - } else { - $mesg = $langs->transnoentitiesnoconv("FailedToConnectToFTPServerWithCredentials"); - $ok = 0; - $error++; - } - } - } - } else { - dol_syslog('FailedToConnectToFTPServer '.$ftp_server.' '.$ftp_port, LOG_ERR); - $mesg = $langs->transnoentitiesnoconv("FailedToConnectToFTPServer", $ftp_server, $ftp_port); - $ok = 0; - } - } - - $arrayresult = array('conn_id'=>$conn_id, 'ok'=>$ok, 'mesg'=>$mesg, 'curdir'=>$section, 'curdiriso'=>$newsectioniso); - return $arrayresult; -} - - -/** - * Tell if an entry is a FTP directory - * - * @param resource $connect_id Connection handler - * @param string $dir Directory - * @return int 1=directory, 0=not a directory - */ -function ftp_isdir($connect_id, $dir) -{ - if (@ftp_chdir($connect_id, $dir)) { - ftp_cdup($connect_id); - return 1; - } else { - return 0; - } -} - diff --git a/htdocs/langs/en_US/ftp.lang b/htdocs/langs/en_US/ftp.lang new file mode 100644 index 00000000000..26791d63918 --- /dev/null +++ b/htdocs/langs/en_US/ftp.lang @@ -0,0 +1,15 @@ +# FTP +FTPClientSetup=FTP or SFTP Client module setup +NewFTPClient=New FTP/SFTP connection setup +FTPArea=FTP/SFTP Area +FTPAreaDesc=This screen shows a view of an FTP et SFTP server. +SetupOfFTPClientModuleNotComplete=The setup of the FTP or SFTP client module seems to be incomplete +FTPFeatureNotSupportedByYourPHP=Your PHP does not support FTP or SFTP functions +FailedToConnectToFTPServer=Failed to connect to server (server %s, port %s) +FailedToConnectToFTPServerWithCredentials=Failed to login to server with defined login/password +FTPFailedToRemoveFile=Failed to remove file %s. +FTPFailedToRemoveDir=Failed to remove directory %s: check permissions and that the directory is empty. +FTPPassiveMode=Passive mode +ChooseAFTPEntryIntoMenu=Choose a FTP/SFTP site from the menu... +FailedToGetFile=Failed to get files %s +ErrorFTPNodisconnect=Error to disconnect FTP/SFTP server \ No newline at end of file diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index e533dc71fa5..2bb316f648f 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -310,18 +310,3 @@ ExternalSiteSetup=Setup link to external website ExternalSiteURL=External Site URL of HTML iframe content ExternalSiteModuleNotComplete=Module ExternalSite was not configured properly. ExampleMyMenuEntry=My menu entry - -# FTP -FTPClientSetup=FTP or SFTP Client module setup -NewFTPClient=New FTP/FTPS connection setup -FTPArea=FTP/FTPS Area -FTPAreaDesc=This screen shows a view of an FTP et SFTP server. -SetupOfFTPClientModuleNotComplete=The setup of the FTP or SFTP client module seems to be incomplete -FTPFeatureNotSupportedByYourPHP=Your PHP does not support FTP or SFTP functions -FailedToConnectToFTPServer=Failed to connect to server (server %s, port %s) -FailedToConnectToFTPServerWithCredentials=Failed to login to server with defined login/password -FTPFailedToRemoveFile=Failed to remove file %s. -FTPFailedToRemoveDir=Failed to remove directory %s: check permissions and that the directory is empty. -FTPPassiveMode=Passive mode -ChooseAFTPEntryIntoMenu=Choose a FTP/SFTP site from the menu... -FailedToGetFile=Failed to get files %s From f54b4baee0daa216c80a565eea7fc35fd5c17bde Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 28 Jul 2022 16:21:53 +0000 Subject: [PATCH 091/205] Fixing style errors. --- htdocs/core/lib/ftp.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/ftp.lib.php b/htdocs/core/lib/ftp.lib.php index 1730a439bcb..d7ce0435c0d 100644 --- a/htdocs/core/lib/ftp.lib.php +++ b/htdocs/core/lib/ftp.lib.php @@ -150,4 +150,4 @@ function dol_ftp_close($connect_id) return ftp_close($connect_id); } } -} \ No newline at end of file +} From eac926e01d0f333f49ecf1e6b0109a9c13dba98a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 28 Jul 2022 18:30:26 +0200 Subject: [PATCH 092/205] Fix phpv8 --- htdocs/admin/barcode.php | 4 ++-- htdocs/barcode/codeinit.php | 11 +++++++---- htdocs/core/class/html.formactions.class.php | 4 ++-- .../barcode/mod_barcode_product_standard.php | 2 +- htdocs/core/photos_resize.php | 17 +++++++++-------- htdocs/user/bank.php | 6 +++--- 6 files changed, 24 insertions(+), 20 deletions(-) diff --git a/htdocs/admin/barcode.php b/htdocs/admin/barcode.php index ee0fcd5d130..5e2451f2ce6 100644 --- a/htdocs/admin/barcode.php +++ b/htdocs/admin/barcode.php @@ -326,7 +326,7 @@ if ($resql) { } } } else { - print $langs->trans("ChooseABarCode"); + print ''.$langs->trans("ChooseABarCode").''; } print ''; @@ -369,7 +369,7 @@ if (!isset($_SERVER['WINDIR'])) { print '
'; print ''; print ''; + print ''; } if ($max && $num > $max) { - print ''; + print ''; } print '
'; + print ''; print $objectstatic->getNomUrl(1); print ''; - print $obj->ref_client; + print dol_escape_htmltag($obj->ref_client); print '
'.$langs->trans("GenbarcodeLocation").''; - print ''; + print ''; if (!empty($conf->global->GENBARCODE_LOCATION) && !@file_exists($conf->global->GENBARCODE_LOCATION)) { $langs->load("errors"); print '
'.$langs->trans("ErrorFileNotFound", $conf->global->GENBARCODE_LOCATION).''; diff --git a/htdocs/barcode/codeinit.php b/htdocs/barcode/codeinit.php index b4e365fe018..48ef2f8a2cd 100644 --- a/htdocs/barcode/codeinit.php +++ b/htdocs/barcode/codeinit.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2014-2022 Laurent Destailleur * Copyright (C) 2018 Ferran Marcet * * This program is free software; you can redistribute it and/or modify @@ -21,6 +21,7 @@ * \ingroup member * \brief Page to make mass init of barcode */ + require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; @@ -264,23 +265,25 @@ if ($conf->product->enabled || $conf->product->service) { dol_print_error($db); } - print $langs->trans("CurrentlyNWithoutBarCode", $nbno, $nbtotal, $langs->transnoentitiesnoconv("ProductsOrServices")).'
'."\n"; + print $langs->trans("CurrentlyNWithoutBarCode", $nbno, $nbtotal, $langs->transnoentitiesnoconv("ProductsOrServices"))."\n"; if (is_object($modBarCodeProduct)) { print $langs->trans("BarCodeNumberManager").": "; $objproduct = new Product($db); print ''.(isset($modBarCodeProduct->name) ? $modBarCodeProduct->name : $modBarCodeProduct->nom).' - '.$langs->trans("NextValue").': '.$modBarCodeProduct->getNextValue($objproduct).'
'; $disabled = 0; + print '
'; } else { $disabled = 1; $titleno = $langs->trans("NoBarcodeNumberingTemplateDefined"); - print ''.$langs->trans("NoBarcodeNumberingTemplateDefined").' ('.$langs->trans("ToGenerateCodeDefineAutomaticRuleFirst").')
'; + print '
'.$langs->trans("NoBarcodeNumberingTemplateDefined"); + print '
'.$langs->trans("ToGenerateCodeDefineAutomaticRuleFirst").''; + print '
'; } if (empty($nbno)) { $disabled1 = 1; } - print '
'; //print ' '.$langs->trans("ResetBarcodeForAllRecords").'
'; $moretags1 = (($disabled || $disabled1) ? ' disabled title="'.dol_escape_htmltag($titleno).'"' : ''); print ''; diff --git a/htdocs/core/class/html.formactions.class.php b/htdocs/core/class/html.formactions.class.php index 242c1476736..99003f00276 100644 --- a/htdocs/core/class/html.formactions.class.php +++ b/htdocs/core/class/html.formactions.class.php @@ -327,11 +327,11 @@ class FormActions $cursorevent++; } } else { - print '
'.$langs->trans("None").'
'.$langs->trans("None").'
'.$langs->trans("More").'...
'.$langs->trans("More").'...
'; diff --git a/htdocs/core/modules/barcode/mod_barcode_product_standard.php b/htdocs/core/modules/barcode/mod_barcode_product_standard.php index 17b5a9bb16a..f4bf05afb3b 100644 --- a/htdocs/core/modules/barcode/mod_barcode_product_standard.php +++ b/htdocs/core/modules/barcode/mod_barcode_product_standard.php @@ -109,7 +109,7 @@ class mod_barcode_product_standard extends ModeleNumRefBarCode //$texte.= ''.$langs->trans("Mask").' ('.$langs->trans("BarCodeModel").'):'; $texte .= ''.$langs->trans("Mask").':'; $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; - $texte .= '  '; + $texte .= '  '; $texte .= ''; $texte .= ''; diff --git a/htdocs/core/photos_resize.php b/htdocs/core/photos_resize.php index 65a3275dab7..6bedf368e97 100644 --- a/htdocs/core/photos_resize.php +++ b/htdocs/core/photos_resize.php @@ -474,6 +474,7 @@ if ($action == 'confirm_crop') { * View */ +$head = ''; $title = $langs->trans("ImageEditor"); $morejs = array('/includes/jquery/plugins/jcrop/js/jquery.Jcrop.min.js', '/core/js/lib_photosresize.js'); $morecss = array('/includes/jquery/plugins/jcrop/css/jquery.Jcrop.css'); @@ -505,8 +506,8 @@ print ''; print '
'; print ''.$langs->trans("Resize").''; print $langs->trans("ResizeDesc").'
'; -print $langs->trans("NewLength").': px   '.$langs->trans("or").'   '; -print $langs->trans("NewHeight").': px  
'; +print $langs->trans("NewLength").': px   '.$langs->trans("or").'   '; +print $langs->trans("NewHeight").': px  
'; print ''; print ''; @@ -564,12 +565,12 @@ if (!empty($conf->use_javascript_ajax)) { print '
'.$langs->trans("NewSizeAfterCropping").': - - - - - - +   +   +   +   +   +  
diff --git a/htdocs/user/bank.php b/htdocs/user/bank.php index cdcfb33af72..0f4fd988f48 100644 --- a/htdocs/user/bank.php +++ b/htdocs/user/bank.php @@ -830,7 +830,7 @@ if ($action != 'edit' && $action != 'create') { // If not bank account yet, $ac if ($account->id == 0) { $colspan = 6; - print ''.$langs->trans("NoBANRecord").''; + print ''.$langs->trans("NoBANRecord").''; } print ''; @@ -891,7 +891,7 @@ if ($id && ($action == 'edit' || $action == 'create') && $user->rights->user->us print ''.$langs->trans("BankAccountDomiciliation").''; print '"; print ''.$langs->trans("BankAccountOwner").''; @@ -900,7 +900,7 @@ if ($id && ($action == 'edit' || $action == 'create') && $user->rights->user->us print ''.$langs->trans("BankAccountOwnerAddress").''; print '"; print ''; From 0f154fa60ce4cd5a276a98b6313effef858d78eb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 28 Jul 2022 18:36:50 +0200 Subject: [PATCH 093/205] CSS --- htdocs/core/class/html.formactions.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/html.formactions.class.php b/htdocs/core/class/html.formactions.class.php index 242c1476736..99003f00276 100644 --- a/htdocs/core/class/html.formactions.class.php +++ b/htdocs/core/class/html.formactions.class.php @@ -327,11 +327,11 @@ class FormActions $cursorevent++; } } else { - print ''.$langs->trans("None").''; + print ''.$langs->trans("None").''; } if ($max && $num > $max) { - print ''.$langs->trans("More").'...'; + print ''.$langs->trans("More").'...'; } print ''; From 455f286ac12f5e7002b259c10a08123afde61eed Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 28 Jul 2022 18:54:45 +0200 Subject: [PATCH 094/205] Debug v17 --- htdocs/core/modules/barcode/mod_barcode_thirdparty_standard.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/barcode/mod_barcode_thirdparty_standard.php b/htdocs/core/modules/barcode/mod_barcode_thirdparty_standard.php index fd0a87efe5b..e25cd1dd115 100644 --- a/htdocs/core/modules/barcode/mod_barcode_thirdparty_standard.php +++ b/htdocs/core/modules/barcode/mod_barcode_thirdparty_standard.php @@ -110,7 +110,7 @@ class mod_barcode_thirdparty_standard extends ModeleNumRefBarCode //$texte.= ''.$langs->trans("Mask").' ('.$langs->trans("BarCodeModel").'):'; $texte .= ''.$langs->trans("Mask").':'; $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; - $texte .= '  '; + $texte .= '  '; $texte .= ''; $texte .= ''; From 482f80d14a2a001802ae14253dcf4540297cf645 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 28 Jul 2022 19:00:17 +0200 Subject: [PATCH 095/205] Close #21612 --- htdocs/core/class/commonobject.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index bf32aca2f57..a85a801717e 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -5470,7 +5470,7 @@ abstract class CommonObject // We save charset_output to restore it because write_file can change it if needed for // output format that does not support UTF8. - $sav_charset_output = $outputlangs->charset_output; + $sav_charset_output = empty($outputlangs->charset_output) ? '' : $outputlangs->charset_output; if (in_array(get_class($this), array('Adherent'))) { $resultwritefile = $obj->write_file($this, $outputlangs, $srctemplatepath, 'member', 1, 'tmp_cards', $moreparams); From 4bc54fc845078746597e0beae71422f2ccab2a5f Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Thu, 28 Jul 2022 19:43:58 +0200 Subject: [PATCH 096/205] Fix picto on stripe charge.php --- htdocs/stripe/charge.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/htdocs/stripe/charge.php b/htdocs/stripe/charge.php index 2cd61bfe5d0..7f17d51800d 100644 --- a/htdocs/stripe/charge.php +++ b/htdocs/stripe/charge.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2018-2022 Thibault FOUCART * Copyright (C) 2019 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -251,16 +251,15 @@ if (!$rowid) { $object = new Commande($db); $object->fetch($charge->metadata->dol_id); if ($object->id > 0) { - print "
".img_picto('', 'object_order')." ".$object->ref.""; + print "".img_picto('', 'order')." ".$object->ref.""; } else { print $FULLTAG; } } elseif ($charge->metadata->dol_type == "invoice" || $charge->metadata->dol_type == "facture") { - print $charge->metadata->dol_type.' '.$charge->metadata->dol_id.' - '; $object = new Facture($db); $object->fetch($charge->metadata->dol_id); if ($object->id > 0) { - print "".img_picto('', 'object_invoice')." ".$object->ref.""; + print "".img_picto('', 'bill')." ".$object->ref.""; } else { print $FULLTAG; } From 77b3e511bedcaa04f4c550df326b4c3eff6462f8 Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Fri, 29 Jul 2022 08:51:57 +0200 Subject: [PATCH 097/205] Del file lang --- htdocs/ftp/admin/ftpclient.php | 2 +- htdocs/ftp/index.php | 2 +- htdocs/langs/en_US/ftp.lang | 15 --------------- htdocs/langs/en_US/other.lang | 16 ++++++++++++++++ 4 files changed, 18 insertions(+), 17 deletions(-) delete mode 100644 htdocs/langs/en_US/ftp.lang diff --git a/htdocs/ftp/admin/ftpclient.php b/htdocs/ftp/admin/ftpclient.php index f914c835b37..c3d5509aa36 100644 --- a/htdocs/ftp/admin/ftpclient.php +++ b/htdocs/ftp/admin/ftpclient.php @@ -25,7 +25,7 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -$langs->loadLangs(array('ftp', "admin", "other")); +$langs->loadLangs(array("admin", "other")); $def = array(); $lastftpentry = 0; diff --git a/htdocs/ftp/index.php b/htdocs/ftp/index.php index 54e66e845d4..7fc13259cdc 100644 --- a/htdocs/ftp/index.php +++ b/htdocs/ftp/index.php @@ -30,7 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/treeview.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/ftp.lib.php'; // Load translation files required by the page -$langs->loadLangs(array('ftp', 'companies', 'other')); +$langs->loadLangs(array('companies', 'other')); // Security check if ($user->socid) { diff --git a/htdocs/langs/en_US/ftp.lang b/htdocs/langs/en_US/ftp.lang deleted file mode 100644 index 26791d63918..00000000000 --- a/htdocs/langs/en_US/ftp.lang +++ /dev/null @@ -1,15 +0,0 @@ -# FTP -FTPClientSetup=FTP or SFTP Client module setup -NewFTPClient=New FTP/SFTP connection setup -FTPArea=FTP/SFTP Area -FTPAreaDesc=This screen shows a view of an FTP et SFTP server. -SetupOfFTPClientModuleNotComplete=The setup of the FTP or SFTP client module seems to be incomplete -FTPFeatureNotSupportedByYourPHP=Your PHP does not support FTP or SFTP functions -FailedToConnectToFTPServer=Failed to connect to server (server %s, port %s) -FailedToConnectToFTPServerWithCredentials=Failed to login to server with defined login/password -FTPFailedToRemoveFile=Failed to remove file %s. -FTPFailedToRemoveDir=Failed to remove directory %s: check permissions and that the directory is empty. -FTPPassiveMode=Passive mode -ChooseAFTPEntryIntoMenu=Choose a FTP/SFTP site from the menu... -FailedToGetFile=Failed to get files %s -ErrorFTPNodisconnect=Error to disconnect FTP/SFTP server \ No newline at end of file diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 2bb316f648f..0918bf54ac7 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -310,3 +310,19 @@ ExternalSiteSetup=Setup link to external website ExternalSiteURL=External Site URL of HTML iframe content ExternalSiteModuleNotComplete=Module ExternalSite was not configured properly. ExampleMyMenuEntry=My menu entry + +# ftp +FTPClientSetup=FTP or SFTP Client module setup +NewFTPClient=New FTP/SFTP connection setup +FTPArea=FTP/SFTP Area +FTPAreaDesc=This screen shows a view of an FTP et SFTP server. +SetupOfFTPClientModuleNotComplete=The setup of the FTP or SFTP client module seems to be incomplete +FTPFeatureNotSupportedByYourPHP=Your PHP does not support FTP or SFTP functions +FailedToConnectToFTPServer=Failed to connect to server (server %s, port %s) +FailedToConnectToFTPServerWithCredentials=Failed to login to server with defined login/password +FTPFailedToRemoveFile=Failed to remove file %s. +FTPFailedToRemoveDir=Failed to remove directory %s: check permissions and that the directory is empty. +FTPPassiveMode=Passive mode +ChooseAFTPEntryIntoMenu=Choose a FTP/SFTP site from the menu... +FailedToGetFile=Failed to get files %s +ErrorFTPNodisconnect=Error to disconnect FTP/SFTP server \ No newline at end of file From 05c37bb1e9e3c4b41693dc79dbe05b51e7555ad5 Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Fri, 29 Jul 2022 10:05:54 +0200 Subject: [PATCH 098/205] Add functions --- htdocs/core/lib/ftp.lib.php | 117 ++++++++++++++++++++++++++++++++---- htdocs/ftp/index.php | 67 +++------------------ 2 files changed, 114 insertions(+), 70 deletions(-) diff --git a/htdocs/core/lib/ftp.lib.php b/htdocs/core/lib/ftp.lib.php index d7ce0435c0d..db4b6abccf0 100644 --- a/htdocs/core/lib/ftp.lib.php +++ b/htdocs/core/lib/ftp.lib.php @@ -39,11 +39,12 @@ */ function dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $section, $ftp_passive = 0) { + global $langs, $conf; $ok = 1; $error = 0; - $conn_id = null; + $connect_id = null; $newsectioniso = ''; $mesg=""; @@ -59,24 +60,24 @@ function dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $sect $tmp_conn_id = ssh2_connect($ftp_server, $ftp_port); } elseif (!empty($conf->global->FTP_CONNECT_WITH_SSL)) { dol_syslog('Try to connect with ftp_ssl_connect'); - $conn_id = ftp_ssl_connect($ftp_server, $ftp_port, $connecttimeout); + $connect_id = ftp_ssl_connect($ftp_server, $ftp_port, $connecttimeout); } else { dol_syslog('Try to connect with ftp_connect'); - $conn_id = ftp_connect($ftp_server, $ftp_port, $connecttimeout); + $connect_id = ftp_connect($ftp_server, $ftp_port, $connecttimeout); } - if (!empty($conn_id) || !empty($tmp_conn_id)) { + if (!empty($connect_id) || !empty($tmp_conn_id)) { if ($ftp_user) { if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { dol_syslog('Try to authenticate with ssh2_auth_password'); if (ssh2_auth_password($tmp_conn_id, $ftp_user, $ftp_password)) { // Turn on passive mode transfers (must be after a successful login - //if ($ftp_passive) ftp_pasv($conn_id, true); + //if ($ftp_passive) ftp_pasv($connect_id, true); // Change the dir $newsectioniso = utf8_decode($section); - //ftp_chdir($conn_id, $newsectioniso); - $conn_id = ssh2_sftp($tmp_conn_id); - if (!$conn_id) { + //ftp_chdir($connect_id, $newsectioniso); + $connect_id = ssh2_sftp($tmp_conn_id); + if (!$connect_id) { dol_syslog('Failed to connect to SFTP after sssh authentication', LOG_DEBUG); $mesg = $langs->transnoentitiesnoconv("FailedToConnectToSFTPAfterSSHAuthentication"); $ok = 0; @@ -89,15 +90,15 @@ function dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $sect $error++; } } else { - if (ftp_login($conn_id, $ftp_user, $ftp_password)) { + if (ftp_login($connect_id, $ftp_user, $ftp_password)) { // Turn on passive mode transfers (must be after a successful login if ($ftp_passive) { - ftp_pasv($conn_id, true); + ftp_pasv($connect_id, true); } // Change the dir $newsectioniso = utf8_decode($section); - ftp_chdir($conn_id, $newsectioniso); + ftp_chdir($connect_id, $newsectioniso); } else { $mesg = $langs->transnoentitiesnoconv("FailedToConnectToFTPServerWithCredentials"); $ok = 0; @@ -112,7 +113,7 @@ function dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $sect } } - $arrayresult = array('conn_id'=>$conn_id, 'ok'=>$ok, 'mesg'=>$mesg, 'curdir'=>$section, 'curdiriso'=>$newsectioniso); + $arrayresult = array('conn_id'=>$connect_id, 'ok'=>$ok, 'mesg'=>$mesg, 'curdir'=>$section, 'curdiriso'=>$newsectioniso); return $arrayresult; } @@ -126,6 +127,7 @@ function dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $sect */ function ftp_isdir($connect_id, $dir) { + if (@ftp_chdir($connect_id, $dir)) { ftp_cdup($connect_id); return 1; @@ -138,9 +140,13 @@ function ftp_isdir($connect_id, $dir) * Tell if an entry is a FTP directory * * @param resource $connect_id Connection handler + * @return result */ function dol_ftp_close($connect_id) { + + global $conf; + // Close FTP connection if ($connect_id) { if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { @@ -151,3 +157,90 @@ function dol_ftp_close($connect_id) } } } + +/** + * Delete a FTP file + * + * @param resource $connect_id Connection handler + * @param string $file File + * @param string $newsection $newsection + */ +function dol_ftp_delete($connect_id, $file, $newsection) +{ + + global $conf; + + if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { + $newsection = ssh2_sftp_realpath($connect_id, ".").'/./'; // workaround for bug https://bugs.php.net/bug.php?id=64169 + } + + // Remote file + $filename = $file; + $remotefile = $newsection.(preg_match('@[\\\/]$@', $newsection) ? '' : '/').$file; + $newremotefileiso = utf8_decode($remotefile); + + //print "x".$newremotefileiso; + dol_syslog("ftp/index.php ftp_delete ".$newremotefileiso); + if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { + return ssh2_sftp_unlink($connect_id, $newremotefileiso); + } else { + var_dump($newremotefileiso); + return @ftp_delete($connect_id, $newremotefileiso); + } +} + +/** + * Download a FTP file + * + * @param resource $connect_id Connection handler + * @param string $file File + * @param string $newsection $newsection + */ +function dol_ftp_get($connect_id, $file, $newsection) +{ + + global $conf; + + if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { + $newsection = ssh2_sftp_realpath($connect_id, ".").'/./'; // workaround for bug https://bugs.php.net/bug.php?id=64169 + } + + // Remote file + $filename = $file; + $remotefile = $newsection.(preg_match('@[\\\/]$@', $newsection) ? '' : '/').$file; + $newremotefileiso = utf8_decode($remotefile); + + if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { + return fopen('ssh2.sftp://'.intval($connect_id).$newremotefileiso, 'r'); + } else { + return ftp_get($connect_id, $localfile, $newremotefileiso, FTP_BINARY); + } +} + +/** + * Remove FTP directory + * + * @param resource $connect_id Connection handler + * @param string $file File + * @param string $newsection $newsection + */ +function dol_ftp_rmdir($connect_id, $file, $newsection) +{ + + global $conf; + + if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { + $newsection = ssh2_sftp_realpath($connect_id, ".").'/./'; // workaround for bug https://bugs.php.net/bug.php?id=64169 + } + + // Remote file + $filename = $file; + $remotefile = $newsection.(preg_match('@[\\\/]$@', $newsection) ? '' : '/').$file; + $newremotefileiso = utf8_decode($remotefile); + + if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { + $result = ssh2_sftp_rmdir($connect_id, $newremotefileiso); + } else { + $result = @ftp_rmdir($connect_id, $newremotefileiso); + } +} diff --git a/htdocs/ftp/index.php b/htdocs/ftp/index.php index 7fc13259cdc..324e3b27a38 100644 --- a/htdocs/ftp/index.php +++ b/htdocs/ftp/index.php @@ -160,24 +160,8 @@ if ($action == 'confirm_deletefile' && GETPOST('confirm') == 'yes') { if ($conn_id && $ok && !$mesg) { $newsection = $section; - if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { - $newsection = ssh2_sftp_realpath($conn_id, ".").'/./'; // workaround for bug https://bugs.php.net/bug.php?id=64169 - } + $result = dol_ftp_delete($conn_id, $file, $newsection); - $langs->load("other"); - - // Remote file - $filename = $file; - $remotefile = $newsection.(preg_match('@[\\\/]$@', $newsection) ? '' : '/').$file; - $newremotefileiso = utf8_decode($remotefile); - - //print "x".$newremotefileiso; - dol_syslog("ftp/index.php ftp_delete ".$newremotefileiso); - if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { - $result = ssh2_sftp_unlink($conn_id, $newremotefileiso); - } else { - $result = @ftp_delete($conn_id, $newremotefileiso); - } if ($result) { setEventMessages($langs->trans("FileWasRemoved", $file), null, 'mesgs'); } else { @@ -185,8 +169,6 @@ if ($action == 'confirm_deletefile' && GETPOST('confirm') == 'yes') { setEventMessages($langs->trans("FTPFailedToRemoveFile", $file), null, 'errors'); } - //ftp_close($conn_id); Close later - $action = ''; } else { dol_print_error('', $mesg); @@ -206,25 +188,17 @@ if (GETPOST("const", 'array') && GETPOST("delete") && GETPOST("delete") == $lang if ($conn_id && $ok && !$mesg) { foreach (GETPOST('const', 'array') as $const) { - if ($const["check"]) { // Is checkbox checked + var_dump($const); + if (isset($const["check"])) { // Is checkbox checked $langs->load("other"); // Remote file $file = $const["file"]; $newsection = $const["section"]; - if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { - $newsection = ssh2_sftp_realpath($conn_id, ".").'/./'; // workaround for bug https://bugs.php.net/bug.php?id=64169 - } - $remotefile = $newsection.(preg_match('@[\\\/]$@', $newsection) ? '' : '/').$file; - $newremotefileiso = utf8_decode($remotefile); + $newsection = $section; - //print "x".$newremotefileiso; - dol_syslog("ftp/index.php ftp_delete n files for ".$newremotefileiso); - if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { - $result = ssh2_sftp_unlink($conn_id, $newremotefileiso); - } else { - $result = @ftp_delete($conn_id, $newremotefileiso); - } + $result = dol_ftp_delete($conn_id, $file, $newsection); + var_dump($newsection); if ($result) { setEventMessages($langs->trans("FileWasRemoved", $file), null, 'mesgs'); } else { @@ -255,20 +229,9 @@ if ($action == 'confirm_deletesection' && $confirm == 'yes') { if ($conn_id && $ok && !$mesg) { $newsection = $section; - if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { - $newsection = ssh2_sftp_realpath($conn_id, ".").'/./'; // workaround for bug https://bugs.php.net/bug.php?id=64169 - } - // Remote file - $filename = $file; - $remotefile = $newsection.(preg_match('@[\\\/]$@', $newsection) ? '' : '/').$file; - $newremotefileiso = utf8_decode($remotefile); + $result = dol_ftp_rmdir($connect_id, $file, $newsection); - if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { - $result = ssh2_sftp_rmdir($conn_id, $newremotefileiso); - } else { - $result = @ftp_rmdir($conn_id, $newremotefileiso); - } if ($result) { setEventMessages($langs->trans("DirWasRemoved", $file), null, 'mesgs'); } else { @@ -299,20 +262,10 @@ if ($action == 'download') { $localfile = tempnam($download_dir, 'dol_'); $newsection = $section; - if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { - $newsection = ssh2_sftp_realpath($conn_id, ".").'/./'; // workaround for bug https://bugs.php.net/bug.php?id=64169 - } - // Remote file - $filename = $file; - $remotefile = $newsection.(preg_match('@[\\\/]$@', $newsection) ? '' : '/').$file; - $newremotefileiso = utf8_decode($remotefile); + $result = dol_ftp_get($connect_id, $file, $newsection); + - if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { - $result = fopen('ssh2.sftp://'.intval($conn_id).$newremotefileiso, 'r'); - } else { - $result = ftp_get($conn_id, $localfile, $newremotefileiso, FTP_BINARY); - } if ($result) { if (!empty($conf->global->MAIN_UMASK)) { @chmod($localfile, octdec($conf->global->MAIN_UMASK)); @@ -345,8 +298,6 @@ if ($action == 'download') { readfile($localfile); - ftp_close($conn_id); - exit; } else { setEventMessages($langs->transnoentitiesnoconv('FailedToGetFile', $remotefile), null, 'errors'); From cb59edb58b28ef015f6c50f873da1ddf7e1843dd Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Fri, 29 Jul 2022 10:06:19 +0200 Subject: [PATCH 099/205] Fix --- htdocs/core/lib/ftp.lib.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/core/lib/ftp.lib.php b/htdocs/core/lib/ftp.lib.php index db4b6abccf0..19dacfdea76 100644 --- a/htdocs/core/lib/ftp.lib.php +++ b/htdocs/core/lib/ftp.lib.php @@ -164,6 +164,7 @@ function dol_ftp_close($connect_id) * @param resource $connect_id Connection handler * @param string $file File * @param string $newsection $newsection + * @return result */ function dol_ftp_delete($connect_id, $file, $newsection) { @@ -195,6 +196,7 @@ function dol_ftp_delete($connect_id, $file, $newsection) * @param resource $connect_id Connection handler * @param string $file File * @param string $newsection $newsection + * @return result */ function dol_ftp_get($connect_id, $file, $newsection) { @@ -223,6 +225,7 @@ function dol_ftp_get($connect_id, $file, $newsection) * @param resource $connect_id Connection handler * @param string $file File * @param string $newsection $newsection + * @return result */ function dol_ftp_rmdir($connect_id, $file, $newsection) { From 0b568aebadeae939fe25eab062cb874a3aaa1161 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 10:41:09 +0200 Subject: [PATCH 100/205] Fix missing link to vcal for some tabs of user --- htdocs/contact/card.php | 2 +- htdocs/hrm/skill_tab.php | 8 +++----- htdocs/user/agenda_extsites.php | 6 +++++- htdocs/user/bank.php | 6 +++++- htdocs/user/clicktodial.php | 7 ++++++- htdocs/user/document.php | 6 +++++- htdocs/user/info.php | 6 +++++- htdocs/user/note.php | 6 +++++- htdocs/user/notify/card.php | 6 +++++- htdocs/user/param_ihm.php | 6 +++++- htdocs/user/perms.php | 6 +++++- 11 files changed, 50 insertions(+), 15 deletions(-) diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index 6650cd140d7..921cc36e807 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -1532,7 +1532,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { } else { //print ''.$langs->trans("NoDolibarrAccess").''; if (!$object->user_id && $user->rights->user->user->creer) { - print ''.img_picto($langs->trans("CreateDolibarrLogin"), 'add').' '.$langs->trans("CreateDolibarrLogin").''; + print ''.img_picto($langs->trans("CreateDolibarrLogin"), 'add', 'class="pictofixedwidth"').$langs->trans("CreateDolibarrLogin").''; } } print ''; diff --git a/htdocs/hrm/skill_tab.php b/htdocs/hrm/skill_tab.php index b2ac9e6bce1..52c45c72848 100644 --- a/htdocs/hrm/skill_tab.php +++ b/htdocs/hrm/skill_tab.php @@ -152,8 +152,6 @@ if (empty($reshook)) { /* * View - * - * Put here all code to build page */ $form = new Form($db); @@ -216,9 +214,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // ------------------------------------------------------------ $linkback = '' . $langs->trans("BackToList") . ''; - $morehtmlref = '
'; - if (isset($object->label)) $morehtmlref.= $object->label; - $morehtmlref .= '
'; + $morehtmlref = ''; + $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); + $morehtmlref .= ''; dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $morehtmlref, '&objecttype='.$objecttype); diff --git a/htdocs/user/agenda_extsites.php b/htdocs/user/agenda_extsites.php index b7d66d2677c..1ea4b88acdd 100644 --- a/htdocs/user/agenda_extsites.php +++ b/htdocs/user/agenda_extsites.php @@ -165,7 +165,11 @@ if ($user->rights->user->user->lire || $user->admin) { $linkback = ''.$langs->trans("BackToList").''; } -dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); +$morehtmlref = ''; +$morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); +$morehtmlref .= ''; + +dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; diff --git a/htdocs/user/bank.php b/htdocs/user/bank.php index 0f4fd988f48..9c84f95f6ee 100644 --- a/htdocs/user/bank.php +++ b/htdocs/user/bank.php @@ -307,7 +307,11 @@ if ($action != 'edit' && $action != 'create') { // If not bank account yet, $ac $linkback = ''.$langs->trans("BackToList").''; } - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); + $morehtmlref = ''; + $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); + $morehtmlref .= ''; + + dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; diff --git a/htdocs/user/clicktodial.php b/htdocs/user/clicktodial.php index 0dd38cc057b..3a2599b8da6 100644 --- a/htdocs/user/clicktodial.php +++ b/htdocs/user/clicktodial.php @@ -43,6 +43,7 @@ $result = restrictedArea($user, 'user', $id, 'user&user', $feature2); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('usercard', 'globalcard')); + /* * Actions */ @@ -104,7 +105,11 @@ if ($id > 0) { $linkback = ''.$langs->trans("BackToList").''; } - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); + $morehtmlref = ''; + $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); + $morehtmlref .= ''; + + dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; print '
'; diff --git a/htdocs/user/document.php b/htdocs/user/document.php index 142c44d85fe..5baa2af8c11 100644 --- a/htdocs/user/document.php +++ b/htdocs/user/document.php @@ -147,7 +147,11 @@ if ($object->id) { $linkback = ''.$langs->trans("BackToList").''; } - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); + $morehtmlref = ''; + $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); + $morehtmlref .= ''; + + dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; print '
'; diff --git a/htdocs/user/info.php b/htdocs/user/info.php index f6a0c731e14..f85028927db 100644 --- a/htdocs/user/info.php +++ b/htdocs/user/info.php @@ -76,7 +76,11 @@ if ($user->rights->user->user->lire || $user->admin) { $linkback = ''.$langs->trans("BackToList").''; } -dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); +$morehtmlref = ''; +$morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); +$morehtmlref .= ''; + +dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); $object->info($id); // This overwrite ->ref with login instead of id diff --git a/htdocs/user/note.php b/htdocs/user/note.php index 801cafbbd52..f121a8f1bf1 100644 --- a/htdocs/user/note.php +++ b/htdocs/user/note.php @@ -101,7 +101,11 @@ if ($id) { $linkback = ''.$langs->trans("BackToList").''; } - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); + $morehtmlref = ''; + $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); + $morehtmlref .= ''; + + dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; diff --git a/htdocs/user/notify/card.php b/htdocs/user/notify/card.php index 3337d846f0b..e047ab74d51 100644 --- a/htdocs/user/notify/card.php +++ b/htdocs/user/notify/card.php @@ -154,7 +154,11 @@ if ($result > 0) { $linkback = ''.$langs->trans("BackToList").''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', '', '', 0, '', '', 0, ''); + $morehtmlref = ''; + $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); + $morehtmlref .= ''; + + dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref, '', 0, '', '', 0, ''); print '
'; diff --git a/htdocs/user/param_ihm.php b/htdocs/user/param_ihm.php index 7916f4650d2..810955eecf7 100644 --- a/htdocs/user/param_ihm.php +++ b/htdocs/user/param_ihm.php @@ -339,7 +339,11 @@ if ($action == 'edit') { $linkback = ''.$langs->trans("BackToList").''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); + $morehtmlref = ''; + $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); + $morehtmlref .= ''; + + dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; diff --git a/htdocs/user/perms.php b/htdocs/user/perms.php index e8a4ed41a1c..4248605f53a 100644 --- a/htdocs/user/perms.php +++ b/htdocs/user/perms.php @@ -250,7 +250,11 @@ if ($user->rights->user->user->lire || $user->admin) { $linkback = ''.$langs->trans("BackToList").''; } -dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); +$morehtmlref = ''; +$morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); +$morehtmlref .= ''; + +dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; From f66dfb1c087a6ed64555fea86d300526cb0dadb7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 11:08:04 +0200 Subject: [PATCH 101/205] phpv8 --- .../box_accountancy_last_manual_entries.php | 2 +- .../box_accountancy_suspense_account.php | 2 +- htdocs/core/boxes/box_actions.php | 2 +- htdocs/core/boxes/box_activity.php | 4 +- htdocs/core/boxes/box_boms.php | 2 +- htdocs/core/boxes/box_bookmarks.php | 2 +- htdocs/core/boxes/box_commandes.php | 2 +- htdocs/core/boxes/box_comptes.php | 2 +- htdocs/core/boxes/box_contracts.php | 2 +- .../core/boxes/box_dolibarr_state_board.php | 42 +++++++++---------- htdocs/core/boxes/box_factures.php | 2 +- htdocs/core/boxes/box_factures_fourn.php | 2 +- htdocs/core/boxes/box_factures_fourn_imp.php | 2 +- htdocs/core/boxes/box_factures_imp.php | 2 +- htdocs/core/boxes/box_ficheinter.php | 2 +- htdocs/core/boxes/box_goodcustomers.php | 2 +- .../boxes/box_graph_invoices_permonth.php | 2 +- .../core/boxes/box_graph_invoices_peryear.php | 2 +- .../box_graph_invoices_supplier_permonth.php | 2 +- .../core/boxes/box_graph_orders_permonth.php | 2 +- .../box_graph_orders_supplier_permonth.php | 2 +- .../boxes/box_graph_product_distribution.php | 4 +- .../boxes/box_graph_propales_permonth.php | 2 +- htdocs/core/boxes/box_mos.php | 2 +- htdocs/core/boxes/box_project.php | 2 +- htdocs/core/boxes/box_propales.php | 2 +- htdocs/core/boxes/box_services_expired.php | 2 +- htdocs/core/boxes/box_shipments.php | 2 +- htdocs/core/boxes/box_supplier_orders.php | 2 +- ...box_supplier_orders_awaiting_reception.php | 2 +- htdocs/core/boxes/box_task.php | 2 +- htdocs/core/boxes/box_validated_projects.php | 2 +- htdocs/core/class/vcard.class.php | 6 +-- htdocs/index.php | 32 +++++++------- htdocs/user/vcard.php | 2 +- 35 files changed, 74 insertions(+), 74 deletions(-) diff --git a/htdocs/core/boxes/box_accountancy_last_manual_entries.php b/htdocs/core/boxes/box_accountancy_last_manual_entries.php index 96abd8699f3..a15728a04f0 100644 --- a/htdocs/core/boxes/box_accountancy_last_manual_entries.php +++ b/htdocs/core/boxes/box_accountancy_last_manual_entries.php @@ -60,7 +60,7 @@ class box_accountancy_last_manual_entries extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->accounting->mouvements->lire); + $this->hidden = empty($user->rights->accounting->mouvements->lire); } /** diff --git a/htdocs/core/boxes/box_accountancy_suspense_account.php b/htdocs/core/boxes/box_accountancy_suspense_account.php index f40c6e8a41b..3ea5b191799 100644 --- a/htdocs/core/boxes/box_accountancy_suspense_account.php +++ b/htdocs/core/boxes/box_accountancy_suspense_account.php @@ -60,7 +60,7 @@ class box_accountancy_suspense_account extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->accounting->mouvements->lire); + $this->hidden = empty($user->rights->accounting->mouvements->lire); } /** diff --git a/htdocs/core/boxes/box_actions.php b/htdocs/core/boxes/box_actions.php index ee41df3cdd2..21fa3b330a5 100644 --- a/htdocs/core/boxes/box_actions.php +++ b/htdocs/core/boxes/box_actions.php @@ -62,7 +62,7 @@ class box_actions extends ModeleBoxes $this->enabled = $conf->agenda->enabled; - $this->hidden = !($user->rights->agenda->myactions->read); + $this->hidden = empty($user->rights->agenda->myactions->read); } /** diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php index ea43eff12fc..49690dc893e 100644 --- a/htdocs/core/boxes/box_activity.php +++ b/htdocs/core/boxes/box_activity.php @@ -63,8 +63,8 @@ class box_activity extends ModeleBoxes $this->enabled = ($conf->global->MAIN_FEATURES_LEVEL); // Not enabled by default due to bugs (see previous comments) $this->hidden = !((isModEnabled('facture') && $user->rights->facture->lire) - || (!empty($conf->commande->enabled) && $user->rights->commande->lire) - || (!empty($conf->propal->enabled) && $user->rights->propale->lire) + || (isModEnabled('commande') && $user->rights->commande->lire) + || (isModEnabled('propal') && $user->rights->propale->lire) ); } diff --git a/htdocs/core/boxes/box_boms.php b/htdocs/core/boxes/box_boms.php index a9a4f8746da..2ace554eb55 100644 --- a/htdocs/core/boxes/box_boms.php +++ b/htdocs/core/boxes/box_boms.php @@ -60,7 +60,7 @@ class box_boms extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->bom->read); + $this->hidden = empty($user->rights->bom->read); } /** diff --git a/htdocs/core/boxes/box_bookmarks.php b/htdocs/core/boxes/box_bookmarks.php index 1a3a1183032..3e8abd587c0 100644 --- a/htdocs/core/boxes/box_bookmarks.php +++ b/htdocs/core/boxes/box_bookmarks.php @@ -56,7 +56,7 @@ class box_bookmarks extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->bookmark->lire); + $this->hidden = empty($user->rights->bookmark->lire); } /** diff --git a/htdocs/core/boxes/box_commandes.php b/htdocs/core/boxes/box_commandes.php index b5656c36292..f4aec2075d7 100644 --- a/htdocs/core/boxes/box_commandes.php +++ b/htdocs/core/boxes/box_commandes.php @@ -60,7 +60,7 @@ class box_commandes extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->commande->lire); + $this->hidden = empty($user->rights->commande->lire); } /** diff --git a/htdocs/core/boxes/box_comptes.php b/htdocs/core/boxes/box_comptes.php index 5570051a065..606f8409161 100644 --- a/htdocs/core/boxes/box_comptes.php +++ b/htdocs/core/boxes/box_comptes.php @@ -68,7 +68,7 @@ class box_comptes extends ModeleBoxes $this->enabled = 0; // disabled for external users } - $this->hidden = !($user->rights->banque->lire); + $this->hidden = empty($user->rights->banque->lire); } /** diff --git a/htdocs/core/boxes/box_contracts.php b/htdocs/core/boxes/box_contracts.php index dddafffdc02..3399304563b 100644 --- a/htdocs/core/boxes/box_contracts.php +++ b/htdocs/core/boxes/box_contracts.php @@ -59,7 +59,7 @@ class box_contracts extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->contrat->lire); + $this->hidden = empty($user->rights->contrat->lire); } /** diff --git a/htdocs/core/boxes/box_dolibarr_state_board.php b/htdocs/core/boxes/box_dolibarr_state_board.php index 4b85ce9d396..83615c17fd3 100644 --- a/htdocs/core/boxes/box_dolibarr_state_board.php +++ b/htdocs/core/boxes/box_dolibarr_state_board.php @@ -112,32 +112,32 @@ class box_dolibarr_state_board extends ModeleBoxes 'dolresource' ); $conditions = array( - 'users' => $user->rights->user->user->lire, - 'members' => !empty($conf->adherent->enabled) && $user->rights->adherent->lire, - 'customers' => !empty($conf->societe->enabled) && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS_STATS), - 'prospects' => !empty($conf->societe->enabled) && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS_STATS), + 'users' => $user->hasRight('user', 'user', 'lire'), + 'members' => isModEnabled('adherent') && $user->rights->adherent->lire, + 'customers' => isModEnabled('societe') && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS_STATS), + 'prospects' => isModEnabled('societe') && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS_STATS), 'suppliers' => ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->lire) || (!empty($conf->supplier_order->enabled) && $user->rights->supplier_order->lire) || (!empty($conf->supplier_invoice->enabled) && $user->rights->supplier_invoice->lire) ) && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_STATS), - 'contacts' => !empty($conf->societe->enabled) && $user->rights->societe->contact->lire, - 'products' => !empty($conf->product->enabled) && $user->rights->produit->lire, - 'services' => !empty($conf->service->enabled) && $user->rights->service->lire, - 'proposals' => !empty($conf->propal->enabled) && $user->rights->propale->lire, - 'orders' => !empty($conf->commande->enabled) && $user->rights->commande->lire, - 'invoices' => isModEnabled('facture') && $user->rights->facture->lire, - 'donations' => !empty($conf->don->enabled) && $user->rights->don->lire, - 'contracts' => !empty($conf->contrat->enabled) && $user->rights->contrat->lire, - 'interventions' => !empty($conf->ficheinter->enabled) && $user->rights->ficheinter->lire, - 'supplier_orders' => !empty($conf->supplier_order->enabled) && $user->rights->fournisseur->commande->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_ORDERS_STATS), - 'supplier_invoices' => !empty($conf->supplier_invoice->enabled) && $user->rights->fournisseur->facture->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_INVOICES_STATS), - 'supplier_proposals' => !empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_PROPOSAL_STATS), - 'projects' => !empty($conf->project->enabled) && $user->rights->projet->lire, - 'expensereports' => !empty($conf->expensereport->enabled) && $user->rights->expensereport->lire, - 'holidays' => !empty($conf->holiday->enabled) && $user->rights->holiday->read, - 'ticket' => !empty($conf->ticket->enabled) && $user->rights->ticket->read, - 'dolresource' => !empty($conf->resource->enabled) && $user->rights->resource->read + 'contacts' => isModEnabled('societe') && $user->hasRight('societe', 'contact', 'lire'), + 'products' => isModEnabled('product') && $user->hasRight('produit', 'lire'), + 'services' => isModEnabled('service') && $user->hasRight('service', 'lire'), + 'proposals' => isModEnabled('propal') && $user->hasRight('propale', 'lire'), + 'orders' => isModEnabled('commande') && $user->hasRight('commande', 'lire'), + 'invoices' => isModEnabled('facture') && $user->hasRight('facture', 'lire'), + 'donations' => isModEnabled('don') && $user->hasRight('don', 'lire'), + 'contracts' => isModEnabled('contrat') && $user->hasRight('contrat', 'lire'), + 'interventions' => isModEnabled('ficheinter') && $user->hasRight('ficheinter', 'lire'), + 'supplier_orders' => isModEnabled('supplier_order') && $user->rights->fournisseur->commande->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_ORDERS_STATS), + 'supplier_invoices' => isModEnabled('supplier_invoice') && $user->rights->fournisseur->facture->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_INVOICES_STATS), + 'supplier_proposals' => isModEnabled('supplier_proposal') && $user->rights->supplier_proposal->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_PROPOSAL_STATS), + 'projects' => isModEnabled('project') && $user->hasRight('projet', 'lire'), + 'expensereports' => isModEnabled('expensereport') && $user->hasRight('expensereport', 'lire'), + 'holidays' => isModEnabled('holiday') && $user->hasRight('holiday', 'read'), + 'ticket' => isModEnabled('ticket') && $user->hasRight('ticket', 'read'), + 'dolresource' => isModEnabled('resource') && $user->hasRight('resource', 'read') ); $classes = array( 'users' => 'User', diff --git a/htdocs/core/boxes/box_factures.php b/htdocs/core/boxes/box_factures.php index 43087949e47..e34e89c97eb 100644 --- a/htdocs/core/boxes/box_factures.php +++ b/htdocs/core/boxes/box_factures.php @@ -58,7 +58,7 @@ class box_factures extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->facture->lire); + $this->hidden = empty($user->rights->facture->lire); } /** diff --git a/htdocs/core/boxes/box_factures_fourn.php b/htdocs/core/boxes/box_factures_fourn.php index 5fc3bdafa38..d6c96ed1e2f 100644 --- a/htdocs/core/boxes/box_factures_fourn.php +++ b/htdocs/core/boxes/box_factures_fourn.php @@ -59,7 +59,7 @@ class box_factures_fourn extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->fournisseur->facture->lire); + $this->hidden = empty($user->rights->fournisseur->facture->lire); } /** diff --git a/htdocs/core/boxes/box_factures_fourn_imp.php b/htdocs/core/boxes/box_factures_fourn_imp.php index d8c9321411d..89ce6e677d7 100644 --- a/htdocs/core/boxes/box_factures_fourn_imp.php +++ b/htdocs/core/boxes/box_factures_fourn_imp.php @@ -58,7 +58,7 @@ class box_factures_fourn_imp extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->fournisseur->facture->lire); + $this->hidden = empty($user->rights->fournisseur->facture->lire); } /** diff --git a/htdocs/core/boxes/box_factures_imp.php b/htdocs/core/boxes/box_factures_imp.php index 6d6893f8ae2..a6103c26257 100644 --- a/htdocs/core/boxes/box_factures_imp.php +++ b/htdocs/core/boxes/box_factures_imp.php @@ -61,7 +61,7 @@ class box_factures_imp extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->facture->lire); + $this->hidden = empty($user->rights->facture->lire); } /** diff --git a/htdocs/core/boxes/box_ficheinter.php b/htdocs/core/boxes/box_ficheinter.php index b0f0e691471..02d7ca8e31b 100644 --- a/htdocs/core/boxes/box_ficheinter.php +++ b/htdocs/core/boxes/box_ficheinter.php @@ -59,7 +59,7 @@ class box_ficheinter extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->ficheinter->lire); + $this->hidden = empty($user->rights->ficheinter->lire); } /** diff --git a/htdocs/core/boxes/box_goodcustomers.php b/htdocs/core/boxes/box_goodcustomers.php index ab425ceac87..3341e08107d 100644 --- a/htdocs/core/boxes/box_goodcustomers.php +++ b/htdocs/core/boxes/box_goodcustomers.php @@ -69,7 +69,7 @@ class box_goodcustomers extends ModeleBoxes $this->enabled = 0; // not enabled by default. Very slow on large database } - $this->hidden = !($user->rights->societe->lire); + $this->hidden = empty($user->rights->societe->lire); } /** diff --git a/htdocs/core/boxes/box_graph_invoices_permonth.php b/htdocs/core/boxes/box_graph_invoices_permonth.php index 8179e134bcf..03b0e1d087b 100644 --- a/htdocs/core/boxes/box_graph_invoices_permonth.php +++ b/htdocs/core/boxes/box_graph_invoices_permonth.php @@ -56,7 +56,7 @@ class box_graph_invoices_permonth extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->facture->lire); + $this->hidden = empty($user->rights->facture->lire); } /** diff --git a/htdocs/core/boxes/box_graph_invoices_peryear.php b/htdocs/core/boxes/box_graph_invoices_peryear.php index 9126cfcfb37..5a9b84829f2 100644 --- a/htdocs/core/boxes/box_graph_invoices_peryear.php +++ b/htdocs/core/boxes/box_graph_invoices_peryear.php @@ -54,7 +54,7 @@ class box_graph_invoices_peryear extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->facture->lire); + $this->hidden = empty($user->rights->facture->lire); } /** diff --git a/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php b/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php index fc91cb692c1..75e51e071f8 100644 --- a/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php +++ b/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php @@ -56,7 +56,7 @@ class box_graph_invoices_supplier_permonth extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->fournisseur->facture->lire); + $this->hidden = empty($user->rights->fournisseur->facture->lire); } /** diff --git a/htdocs/core/boxes/box_graph_orders_permonth.php b/htdocs/core/boxes/box_graph_orders_permonth.php index 885ec469632..c4205901528 100644 --- a/htdocs/core/boxes/box_graph_orders_permonth.php +++ b/htdocs/core/boxes/box_graph_orders_permonth.php @@ -56,7 +56,7 @@ class box_graph_orders_permonth extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->commande->lire); + $this->hidden = empty($user->rights->commande->lire); } /** diff --git a/htdocs/core/boxes/box_graph_orders_supplier_permonth.php b/htdocs/core/boxes/box_graph_orders_supplier_permonth.php index db7400c1c5a..433ba660365 100644 --- a/htdocs/core/boxes/box_graph_orders_supplier_permonth.php +++ b/htdocs/core/boxes/box_graph_orders_supplier_permonth.php @@ -56,7 +56,7 @@ class box_graph_orders_supplier_permonth extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->fournisseur->commande->lire); + $this->hidden = empty($user->rights->fournisseur->commande->lire); } /** diff --git a/htdocs/core/boxes/box_graph_product_distribution.php b/htdocs/core/boxes/box_graph_product_distribution.php index afed778912f..44f94fd48d1 100644 --- a/htdocs/core/boxes/box_graph_product_distribution.php +++ b/htdocs/core/boxes/box_graph_product_distribution.php @@ -61,8 +61,8 @@ class box_graph_product_distribution extends ModeleBoxes $this->hidden = !( (isModEnabled('facture') && !empty($user->rights->facture->lire)) - || (!empty($conf->commande->enabled) && !empty($user->rights->commande->lire)) - || (!empty($conf->propal->enabled) && !empty($user->rights->propale->lire)) + || (isModEnabled('commande') && !empty($user->rights->commande->lire)) + || (isModEnabled('propal') && !empty($user->rights->propale->lire)) ); } diff --git a/htdocs/core/boxes/box_graph_propales_permonth.php b/htdocs/core/boxes/box_graph_propales_permonth.php index cb9a543bc19..13f3a29ec16 100644 --- a/htdocs/core/boxes/box_graph_propales_permonth.php +++ b/htdocs/core/boxes/box_graph_propales_permonth.php @@ -56,7 +56,7 @@ class box_graph_propales_permonth extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->propale->lire); + $this->hidden = empty($user->rights->propale->lire); } /** diff --git a/htdocs/core/boxes/box_mos.php b/htdocs/core/boxes/box_mos.php index cff19388c17..812fcab7b64 100644 --- a/htdocs/core/boxes/box_mos.php +++ b/htdocs/core/boxes/box_mos.php @@ -60,7 +60,7 @@ class box_mos extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->bom->read); + $this->hidden = empty($user->rights->bom->read); } /** diff --git a/htdocs/core/boxes/box_project.php b/htdocs/core/boxes/box_project.php index 909ff32acb9..80d465f0f87 100644 --- a/htdocs/core/boxes/box_project.php +++ b/htdocs/core/boxes/box_project.php @@ -62,7 +62,7 @@ class box_project extends ModeleBoxes $this->db = $db; $this->boxlabel = "OpenedProjects"; - $this->hidden = !($user->rights->projet->lire); + $this->hidden = empty($user->rights->projet->lire); } /** diff --git a/htdocs/core/boxes/box_propales.php b/htdocs/core/boxes/box_propales.php index cdaf629ae3f..b010779e52a 100644 --- a/htdocs/core/boxes/box_propales.php +++ b/htdocs/core/boxes/box_propales.php @@ -61,7 +61,7 @@ class box_propales extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->propale->lire); + $this->hidden = empty($user->rights->propale->lire); } /** diff --git a/htdocs/core/boxes/box_services_expired.php b/htdocs/core/boxes/box_services_expired.php index e9cca792de1..3fbad6c1656 100644 --- a/htdocs/core/boxes/box_services_expired.php +++ b/htdocs/core/boxes/box_services_expired.php @@ -58,7 +58,7 @@ class box_services_expired extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->contrat->lire); + $this->hidden = empty($user->rights->contrat->lire); } /** diff --git a/htdocs/core/boxes/box_shipments.php b/htdocs/core/boxes/box_shipments.php index ba95fe14356..4e54f3c5992 100644 --- a/htdocs/core/boxes/box_shipments.php +++ b/htdocs/core/boxes/box_shipments.php @@ -60,7 +60,7 @@ class box_shipments extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->expedition->lire); + $this->hidden = empty($user->rights->expedition->lire); } /** diff --git a/htdocs/core/boxes/box_supplier_orders.php b/htdocs/core/boxes/box_supplier_orders.php index 6ee0c5ef8a3..b6924af4123 100644 --- a/htdocs/core/boxes/box_supplier_orders.php +++ b/htdocs/core/boxes/box_supplier_orders.php @@ -58,7 +58,7 @@ class box_supplier_orders extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->fournisseur->commande->lire); + $this->hidden = empty($user->rights->fournisseur->commande->lire); } /** diff --git a/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php b/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php index 32151828b83..bfbaa9abf0c 100644 --- a/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php +++ b/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php @@ -58,7 +58,7 @@ class box_supplier_orders_awaiting_reception extends ModeleBoxes $this->db = $db; - $this->hidden = !($user->rights->fournisseur->commande->lire); + $this->hidden = empty($user->rights->fournisseur->commande->lire); } /** diff --git a/htdocs/core/boxes/box_task.php b/htdocs/core/boxes/box_task.php index 82e917b102a..3f3c9d83a62 100644 --- a/htdocs/core/boxes/box_task.php +++ b/htdocs/core/boxes/box_task.php @@ -64,7 +64,7 @@ class box_task extends ModeleBoxes $this->boxlabel = "Tasks"; $this->db = $db; - $this->hidden = (!empty($conf->global->PROJECT_HIDE_TASKS) || !($user->rights->projet->lire)); + $this->hidden = (!empty($conf->global->PROJECT_HIDE_TASKS) || empty($user->rights->projet->lire)); } /** diff --git a/htdocs/core/boxes/box_validated_projects.php b/htdocs/core/boxes/box_validated_projects.php index e57bb1f14d9..bab64d5a000 100644 --- a/htdocs/core/boxes/box_validated_projects.php +++ b/htdocs/core/boxes/box_validated_projects.php @@ -66,7 +66,7 @@ class box_validated_projects extends ModeleBoxes $this->db = $db; $this->boxlabel = "ProjectTasksWithoutTimeSpent"; - $this->hidden = !($user->rights->projet->lire); + $this->hidden = empty($user->rights->projet->lire); if ($conf->global->MAIN_FEATURES_LEVEL < 2) { $this->enabled = 0; diff --git a/htdocs/core/class/vcard.class.php b/htdocs/core/class/vcard.class.php index d513262b871..dbe505a894b 100644 --- a/htdocs/core/class/vcard.class.php +++ b/htdocs/core/class/vcard.class.php @@ -195,14 +195,14 @@ class vCard // $type may be DOM | INTL | POSTAL | PARCEL | HOME | WORK or any combination of these: e.g. "WORK;PARCEL;POSTAL" $key = "ADR"; if ($type != "") { - $key .= ";$type"; + $key .= ";".$type; } $key .= ";CHARSET=".$this->encoding; $this->properties[$key] = ";".encode($extended).";".encode($street).";".encode($city).";".encode($region).";".encode($zip).";".encode($country); - if ($this->properties["LABEL;$type;CHARSET=".$this->encoding] == "") { + //if ($this->properties["LABEL;".$type.";CHARSET=".$this->encoding] == '') { //$this->setLabel($postoffice, $extended, $street, $city, $region, $zip, $country, $type); - } + //} } /** diff --git a/htdocs/index.php b/htdocs/index.php index 6ada359cee6..6715577e615 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -162,21 +162,21 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { } // Number of project opened - if (!empty($conf->project->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_PROJECT) && $user->rights->projet->lire) { + if (!empty($conf->project->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_PROJECT) && $user->hasRight('projet', 'lire')) { include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; $board = new Project($db); $dashboardlines[$board->element] = $board->load_board($user); } // Number of tasks to do (late) - if (!empty($conf->project->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_PROJECT) && empty($conf->global->PROJECT_HIDE_TASKS) && $user->rights->projet->lire) { + if (isModEnabled('project') && empty($conf->global->MAIN_DISABLE_BLOCK_PROJECT) && empty($conf->global->PROJECT_HIDE_TASKS) && $user->hasRight('projet', 'lire')) { include_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; $board = new Task($db); $dashboardlines[$board->element] = $board->load_board($user); } // Number of commercial customer proposals open (expired) - if (!empty($conf->propal->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_CUSTOMER) && $user->rights->propale->lire) { + if (isModEnabled('propal') && empty($conf->global->MAIN_DISABLE_BLOCK_CUSTOMER) && $user->hasRight('propale', 'lire')) { include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; $board = new Propal($db); $dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened"); @@ -185,7 +185,7 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { } // Number of supplier proposals open (expired) - if (!empty($conf->supplier_proposal->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_SUPPLIER) && $user->rights->supplier_proposal->lire) { + if (isModEnabled('supplier_proposal') && empty($conf->global->MAIN_DISABLE_BLOCK_SUPPLIER) && $user->hasRight('supplier_proposal', 'lire')) { $langs->load("supplier_proposal"); include_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php'; $board = new SupplierProposal($db); @@ -195,14 +195,14 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { } // Number of customer orders a deal - if (!empty($conf->commande->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_CUSTOMER) && $user->rights->commande->lire) { + if (isModEnabled('commande') && empty($conf->global->MAIN_DISABLE_BLOCK_CUSTOMER) && $user->hasRight('commande', 'lire')) { include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; $board = new Commande($db); $dashboardlines[$board->element] = $board->load_board($user); } // Number of suppliers orders a deal - if (!empty($conf->supplier_order->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_SUPPLIER) && $user->rights->fournisseur->commande->lire) { + if (isModEnabled('supplier_order') && empty($conf->global->MAIN_DISABLE_BLOCK_SUPPLIER) && $user->rights->fournisseur->commande->lire) { include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; $board = new CommandeFournisseur($db); $dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened"); @@ -210,7 +210,7 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { } // Number of contract / services enabled (delayed) - if (!empty($conf->contrat->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_CONTRACT) && $user->rights->contrat->lire) { + if (isModEnabled('contrat') && empty($conf->global->MAIN_DISABLE_BLOCK_CONTRACT) && $user->hasRight('contrat', 'lire')) { include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; $board = new Contrat($db); $dashboardlines[$board->element.'_inactive'] = $board->load_board($user, "inactive"); @@ -219,7 +219,7 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { } // Number of tickets open - if (!empty($conf->ticket->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_TICKET) && $user->rights->ticket->read) { + if (isModEnabled('ticket') && empty($conf->global->MAIN_DISABLE_BLOCK_TICKET) && $user->hasRight('ticket', 'read')) { include_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php'; $board = new Ticket($db); $dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened"); @@ -228,21 +228,21 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { } // Number of invoices customers (paid) - if (isModEnabled('facture') && empty($conf->global->MAIN_DISABLE_BLOCK_CUSTOMER) && $user->rights->facture->lire) { + if (isModEnabled('facture') && empty($conf->global->MAIN_DISABLE_BLOCK_CUSTOMER) && $user->hasRight('facture', 'lire')) { include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; $board = new Facture($db); $dashboardlines[$board->element] = $board->load_board($user); } // Number of supplier invoices (paid) - if (!empty($conf->supplier_invoice->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_SUPPLIER) && !empty($user->rights->fournisseur->facture->lire)) { + if (isModEnabled('supplier_invoice') && empty($conf->global->MAIN_DISABLE_BLOCK_SUPPLIER) && !empty($user->rights->fournisseur->facture->lire)) { include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; $board = new FactureFournisseur($db); $dashboardlines[$board->element] = $board->load_board($user); } // Number of transactions to conciliate - if (!empty($conf->banque->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_BANK) && $user->rights->banque->lire && !$user->socid) { + if (isModEnabled('banque') && empty($conf->global->MAIN_DISABLE_BLOCK_BANK) && $user->hasRight('banque', 'lire') && !$user->socid) { include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; $board = new Account($db); $nb = $board->countAccountToReconcile(); // Get nb of account to reconciliate @@ -253,7 +253,7 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { // Number of cheque to send - if (!empty($conf->banque->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_BANK) && $user->rights->banque->lire && !$user->socid) { + if (isModEnabled('banque') && empty($conf->global->MAIN_DISABLE_BLOCK_BANK) && $user->hasRight('banque', 'lire') && !$user->socid) { if (empty($conf->global->BANK_DISABLE_CHECK_DEPOSIT)) { include_once DOL_DOCUMENT_ROOT.'/compta/paiement/cheque/class/remisecheque.class.php'; $board = new RemiseCheque($db); @@ -272,7 +272,7 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { } // Number of foundation members - if (!empty($conf->adherent->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_ADHERENT) && $user->rights->adherent->lire && !$user->socid) { + if (isModEnabled('adherent') && empty($conf->global->MAIN_DISABLE_BLOCK_ADHERENT) && $user->hasRight('adherent', 'lire') && !$user->socid) { include_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; $board = new Adherent($db); $dashboardlines[$board->element.'_shift'] = $board->load_board($user, 'shift'); @@ -280,21 +280,21 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { } // Number of expense reports to approve - if (!empty($conf->expensereport->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_EXPENSEREPORT) && $user->rights->expensereport->approve) { + if (isModEnabled('expensereport') && empty($conf->global->MAIN_DISABLE_BLOCK_EXPENSEREPORT) && $user->hasRight('expensereport', 'approve')) { include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; $board = new ExpenseReport($db); $dashboardlines[$board->element.'_toapprove'] = $board->load_board($user, 'toapprove'); } // Number of expense reports to pay - if (!empty($conf->expensereport->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_EXPENSEREPORT) && $user->rights->expensereport->to_paid) { + if (isModEnabled('expensereport') && empty($conf->global->MAIN_DISABLE_BLOCK_EXPENSEREPORT) && $user->hasRight('expensereport', 'to_paid')) { include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; $board = new ExpenseReport($db); $dashboardlines[$board->element.'_topay'] = $board->load_board($user, 'topay'); } // Number of holidays to approve - if (!empty($conf->holiday->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_HOLIDAY) && $user->rights->holiday->approve) { + if (isModEnabled('holiday') && empty($conf->global->MAIN_DISABLE_BLOCK_HOLIDAY) && $user->hasRight('holiday', 'approve')) { include_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php'; $board = new Holiday($db); $dashboardlines[$board->element] = $board->load_board($user); diff --git a/htdocs/user/vcard.php b/htdocs/user/vcard.php index 0f9085d0b52..6796d11f7aa 100644 --- a/htdocs/user/vcard.php +++ b/htdocs/user/vcard.php @@ -113,7 +113,7 @@ if ($company->id) { } // Si user lie a un tiers non de type "particulier" - if ($user2->typent_code != 'TE_PRIVATE') { + if ($company->typent_code != 'TE_PRIVATE') { $v->setOrg($company->name); } } From 8e7fa102b85030e63ee7c50636d35e4f118e3716 Mon Sep 17 00:00:00 2001 From: Anthony Berton Date: Fri, 29 Jul 2022 11:14:28 +0200 Subject: [PATCH 102/205] Clean --- htdocs/core/lib/ftp.lib.php | 5 ++--- htdocs/ftp/index.php | 13 ++++--------- htdocs/langs/en_US/companies.lang | 2 +- htdocs/langs/fr_FR/companies.lang | 2 +- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/htdocs/core/lib/ftp.lib.php b/htdocs/core/lib/ftp.lib.php index 19dacfdea76..42f5806fba5 100644 --- a/htdocs/core/lib/ftp.lib.php +++ b/htdocs/core/lib/ftp.lib.php @@ -185,7 +185,6 @@ function dol_ftp_delete($connect_id, $file, $newsection) if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { return ssh2_sftp_unlink($connect_id, $newremotefileiso); } else { - var_dump($newremotefileiso); return @ftp_delete($connect_id, $newremotefileiso); } } @@ -242,8 +241,8 @@ function dol_ftp_rmdir($connect_id, $file, $newsection) $newremotefileiso = utf8_decode($remotefile); if (!empty($conf->global->FTP_CONNECT_WITH_SFTP)) { - $result = ssh2_sftp_rmdir($connect_id, $newremotefileiso); + return ssh2_sftp_rmdir($connect_id, $newremotefileiso); } else { - $result = @ftp_rmdir($connect_id, $newremotefileiso); + return @ftp_rmdir($connect_id, $newremotefileiso); } } diff --git a/htdocs/ftp/index.php b/htdocs/ftp/index.php index 324e3b27a38..cf647929ac8 100644 --- a/htdocs/ftp/index.php +++ b/htdocs/ftp/index.php @@ -188,17 +188,15 @@ if (GETPOST("const", 'array') && GETPOST("delete") && GETPOST("delete") == $lang if ($conn_id && $ok && !$mesg) { foreach (GETPOST('const', 'array') as $const) { - var_dump($const); if (isset($const["check"])) { // Is checkbox checked $langs->load("other"); // Remote file $file = $const["file"]; $newsection = $const["section"]; - $newsection = $section; $result = dol_ftp_delete($conn_id, $file, $newsection); - var_dump($newsection); + if ($result) { setEventMessages($langs->trans("FileWasRemoved", $file), null, 'mesgs'); } else { @@ -230,7 +228,7 @@ if ($action == 'confirm_deletesection' && $confirm == 'yes') { if ($conn_id && $ok && !$mesg) { $newsection = $section; - $result = dol_ftp_rmdir($connect_id, $file, $newsection); + $result = dol_ftp_rmdir($conn_id, $file, $newsection); if ($result) { setEventMessages($langs->trans("DirWasRemoved", $file), null, 'mesgs'); @@ -361,12 +359,12 @@ if (!function_exists('ftp_connect')) { if (!empty($ftp_server)) { // Confirm remove file if ($action == 'delete') { - print $form->formconfirm($_SERVER["PHP_SELF"].'?numero_ftp='.$numero_ftp.'§ion='.urlencode(GETPOST('section')).'&file='.urlencode(GETPOST('file')), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', '', 1); + print $form->formconfirm($_SERVER["PHP_SELF"].'?numero_ftp='.$numero_ftp.'§ion='.urlencode(GETPOST('section')).'&file='.urlencode(GETPOST('file')), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile', GETPOST('file')), 'confirm_deletefile', '', '', 1); } // Confirmation de la suppression d'une ligne categorie if ($action == 'delete_section') { - print $form->formconfirm($_SERVER["PHP_SELF"].'?numero_ftp='.$numero_ftp.'§ion='.urlencode(GETPOST('section')).'&file='.urlencode(GETPOST('file')), $langs->trans('DeleteSection'), $langs->trans('ConfirmDeleteSection', $ecmdir->label), 'confirm_deletesection', '', '', 1); + print $form->formconfirm($_SERVER["PHP_SELF"].'?numero_ftp='.$numero_ftp.'§ion='.urlencode(GETPOST('section')).'&file='.urlencode(GETPOST('file')), $langs->trans('DeleteSection'), $langs->trans('ConfirmDeleteSection', GETPOST('file')), 'confirm_deletesection', '', '', 1); } print $langs->trans("Server").': '.$ftp_server.'
'; @@ -456,8 +454,6 @@ if (!function_exists('ftp_connect')) { } else { $buff = ftp_rawlist($conn_id, $newsectioniso); $contents = ftp_nlist($conn_id, $newsectioniso); // Sometimes rawlist fails but never nlist - //var_dump($contents); - //var_dump($buff); } $nboflines = count($contents); @@ -467,7 +463,6 @@ if (!function_exists('ftp_connect')) { while ($i < $nboflines && $i < 1000) { $vals = preg_split('@ +@', utf8_encode($buff[$i]), 9); //$vals=preg_split('@ +@','drwxr-xr-x 2 root root 4096 Aug 30 2008 backup_apollon1',9); - //var_dump($vals); $file = $vals[8]; if (empty($file)) { $rawlisthasfailed = true; diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index 71b16f24506..996c98c203a 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -444,7 +444,7 @@ AddAddress=Add address SupplierCategory=Vendor category JuridicalStatus200=Independent DeleteFile=Delete file -ConfirmDeleteFile=Are you sure you want to delete this file? +ConfirmDeleteFile=Are you sure you want to delete this file %s? AllocateCommercial=Assigned to sales representative Organization=Organization FiscalYearInformation=Fiscal Year diff --git a/htdocs/langs/fr_FR/companies.lang b/htdocs/langs/fr_FR/companies.lang index 889f16b3f75..3359131aa51 100644 --- a/htdocs/langs/fr_FR/companies.lang +++ b/htdocs/langs/fr_FR/companies.lang @@ -443,7 +443,7 @@ AddAddress=Créer adresse SupplierCategory=Catégorie du fournisseur JuridicalStatus200=Indépendant DeleteFile=Suppression d'un fichier -ConfirmDeleteFile=Êtes-vous sûr de vouloir supprimer ce fichier ? +ConfirmDeleteFile=Êtes-vous sûr de vouloir supprimer ce fichier %s? AllocateCommercial=Affecter un commercial Organization=Organisme FiscalYearInformation=Exercice fiscal From 79e0d59978b765bf18a4b77b28cd821e0fc9dd62 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 11:48:17 +0200 Subject: [PATCH 103/205] Fix regression --- htdocs/contact/card.php | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index 649fcc00fb4..0ef31fe36a4 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -567,19 +567,22 @@ $form = new Form($db); $formadmin = new FormAdmin($db); $formcompany = new FormCompany($db); +$objsoc = new Societe($db); +if ($socid > 0) { + $objsoc->fetch($socid); +} + $title = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("Contacts") : $langs->trans("ContactsAddresses")); if (!empty($conf->global->MAIN_HTML_TITLE) && preg_match('/contactnameonly/', $conf->global->MAIN_HTML_TITLE) && $object->lastname) { $title = $object->lastname; } $help_url = 'EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; +$title = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("NewContact") : $langs->trans("NewContactAddress")); + +llxHeader('', $title, $help_url); $countrynotdefined = $langs->trans("ErrorSetACountryFirst").' ('.$langs->trans("SeeAbove").')'; -$objsoc = new Societe($db); -if ($socid > 0) { - $objsoc->fetch($socid); -} - if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { // ----------------------------------------- // When used with CANVAS @@ -621,8 +624,6 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { // Show tabs $head = contact_prepare_head($object); - - llxHeader('', $title, $help_url); } if ($user->rights->societe->contact->creer) { @@ -643,9 +644,6 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { } $linkback = ''; - $title = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("NewContact") : $langs->trans("NewContactAddress")); - - llxHeader('', $title, $help_url); print load_fiche_titre($title, $linkback, 'address'); From 31fa326615af01987b962af4394691e09533925e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 11:54:56 +0200 Subject: [PATCH 104/205] Fix missing import key --- htdocs/contact/list.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 1e497b0ab2e..8d60b37611f 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -373,6 +373,7 @@ $sql = "SELECT s.rowid as socid, s.nom as name,"; $sql .= " p.rowid, p.lastname as lastname, p.statut, p.firstname, p.address, p.zip, p.town, p.poste, p.email,"; $sql .= " p.socialnetworks, p.photo,"; $sql .= " p.phone as phone_pro, p.phone_mobile, p.phone_perso, p.fax, p.fk_pays, p.priv, p.datec as date_creation, p.tms as date_update,"; +$sql .= " p.import_key,"; $sql .= " st.libelle as stcomm, st.picto as stcomm_picto, p.fk_stcommcontact as stcomm_id, p.fk_prospectcontactlevel,"; $sql .= " co.label as country, co.code as country_code"; // Add fields from extrafields @@ -1074,6 +1075,7 @@ while ($i < min($num, $limit)) { $contactstatic->country = $obj->country; $contactstatic->country_code = $obj->country_code; $contactstatic->photo = $obj->photo; + $contactstatic->import_key = $obj->import_key; $contactstatic->fk_prospectlevel = $obj->fk_prospectcontactlevel; @@ -1309,9 +1311,10 @@ while ($i < min($num, $limit)) { $totalarray['nbfield']++; } } + // Import key if (!empty($arrayfields['p.import_key']['checked'])) { print ''; - print $obj->import_key; + print dol_escape_htmltag($obj->import_key); print "\n"; if (!$i) { $totalarray['nbfield']++; From e13d5ea5aa27693aa4c244c3b03d536e4d886a25 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 11:54:56 +0200 Subject: [PATCH 105/205] Fix missing import key --- htdocs/contact/list.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 8a1765118da..97dd6444d0a 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -374,6 +374,7 @@ $sql = "SELECT s.rowid as socid, s.nom as name,"; $sql .= " p.rowid, p.lastname as lastname, p.statut, p.firstname, p.address, p.zip, p.town, p.poste, p.email,"; $sql .= " p.socialnetworks, p.photo,"; $sql .= " p.phone as phone_pro, p.phone_mobile, p.phone_perso, p.fax, p.fk_pays, p.priv, p.datec as date_creation, p.tms as date_update,"; +$sql .= " p.import_key,"; $sql .= " st.libelle as stcomm, st.picto as stcomm_picto, p.fk_stcommcontact as stcomm_id, p.fk_prospectcontactlevel,"; $sql .= " co.label as country, co.code as country_code"; // Add fields from extrafields @@ -1062,6 +1063,7 @@ while ($i < min($num, $limit)) { $contactstatic->country = $obj->country; $contactstatic->country_code = $obj->country_code; $contactstatic->photo = $obj->photo; + $contactstatic->import_key = $obj->import_key; $contactstatic->fk_prospectlevel = $obj->fk_prospectcontactlevel; @@ -1285,9 +1287,10 @@ while ($i < min($num, $limit)) { $totalarray['nbfield']++; } } + // Import key if (!empty($arrayfields['p.import_key']['checked'])) { print ''; - print $obj->import_key; + print dol_escape_htmltag($obj->import_key); print "\n"; if (!$i) { $totalarray['nbfield']++; From 64fc74087bab2020d851ce3622f57c4bc766cc1f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 12:31:51 +0200 Subject: [PATCH 106/205] NEW Add link to create an element from the category page --- htdocs/adherents/card.php | 5 +++++ htdocs/categories/viewcat.php | 41 ++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index 2e04a29b69f..44a12293e67 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -621,6 +621,11 @@ if (empty($reshook)) { } } $action = ($result < 0 || !$error) ? '' : 'create'; + + if (!$error && $backtopage) { + header("Location: ".$backtopage); + exit; + } } if ($user->rights->adherent->supprimer && $action == 'confirm_delete' && $confirm == 'yes') { diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php index 7e8a1252095..5450127bff3 100644 --- a/htdocs/categories/viewcat.php +++ b/htdocs/categories/viewcat.php @@ -103,7 +103,7 @@ if ($confirm == 'no') { $parameters = array(); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks // Remove element from category -if ($id > 0 && $removeelem > 0) { +if ($id > 0 && $removeelem > 0 && $action == 'unlink') { if ($type == Categorie::TYPE_PRODUCT && ($user->rights->produit->creer || $user->rights->service->creer)) { require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; $tmpobject = new Product($db); @@ -521,7 +521,8 @@ if ($type == Categorie::TYPE_PRODUCT) { print ''; print '
'; - $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($prods); $nbtotalofrecords = ''; $newcardbutton = ''; + $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($prods); $nbtotalofrecords = ''; + $newcardbutton = dolGetButtonTitle($langs->trans("AddProduct"), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/product/card.php?action=create&categories[]='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id), '', $user->rights->societe->creer); print_barre_liste($langs->trans("ProductsAndServices"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'products', 0, $newcardbutton, '', $limit); @@ -544,7 +545,7 @@ if ($type == Categorie::TYPE_PRODUCT) { // Link to delete from category print ''; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -597,7 +598,8 @@ if ($type == Categorie::TYPE_CUSTOMER) { print ''; print '
'; - $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($socs); $nbtotalofrecords = ''; $newcardbutton = ''; + $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($socs); $nbtotalofrecords = ''; + $newcardbutton = dolGetButtonTitle($langs->trans("AddThirdParty"), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/societe/card.php?action=create&client=3&custcats[]='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id), '', $user->rights->societe->creer); print_barre_liste($langs->trans("Customers"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'companies', 0, $newcardbutton, '', $limit); print ''."\n"; @@ -618,7 +620,7 @@ if ($type == Categorie::TYPE_CUSTOMER) { // Link to delete from category print '
'; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -671,7 +673,8 @@ if ($type == Categorie::TYPE_SUPPLIER) { print ''; print '
'; - $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($socs); $nbtotalofrecords = ''; $newcardbutton = ''; + $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($socs); $nbtotalofrecords = ''; + $newcardbutton = dolGetButtonTitle($langs->trans("AddSupplier"), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/societe/card.php?action=create&fournisseur=1&suppcats[]='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id), '', $user->rights->societe->creer); print_barre_liste($langs->trans("Suppliers"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'companies', 0, $newcardbutton, '', $limit); print ''."\n"; @@ -692,7 +695,7 @@ if ($type == Categorie::TYPE_SUPPLIER) { // Link to delete from category print '
'; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -748,7 +751,8 @@ if ($type == Categorie::TYPE_MEMBER) { print ''; print '
'; - $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($prods); $nbtotalofrecords = ''; $newcardbutton = ''; + $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($prods); $nbtotalofrecords = ''; + $newcardbutton = dolGetButtonTitle($langs->trans("AddMember"), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/adherents/card.php?action=create&memcats[]='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id), '', $user->rights->adherent->creer); print_barre_liste($langs->trans("Member"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'members', 0, $newcardbutton, '', $limit); print "\n"; @@ -772,7 +776,7 @@ if ($type == Categorie::TYPE_MEMBER) { // Link to delete from category print '
'; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -788,7 +792,7 @@ if ($type == Categorie::TYPE_MEMBER) { } } -// Categorie contact +// List of contacts if ($type == Categorie::TYPE_CONTACT) { $permission = $user->rights->societe->creer; @@ -808,7 +812,7 @@ if ($type == Categorie::TYPE_CONTACT) { print ''; print ''; print ''; print ''; @@ -826,7 +830,7 @@ if ($type == Categorie::TYPE_CONTACT) { $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($contacts); $nbtotalofrecords = ''; - $newcardbutton = ''; + $newcardbutton = dolGetButtonTitle($langs->trans("AddContact"), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/contact/card.php?action=create&contcats[]='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id), '', $user->rights->societe->creer); $objsoc = new Societe($db); print_barre_liste($langs->trans("Contact"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'contact', 0, $newcardbutton, '', $limit); @@ -853,7 +857,7 @@ if ($type == Categorie::TYPE_CONTACT) { // Link to delete from category print ''; - print ''; + print ''; print '\n"; From 7ff956a1e237121e0baef90f818e3e8cf6bac9c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?This=20Charl=C3=A8ne?= <1179011+defrance@users.noreply.github.com> Date: Fri, 29 Jul 2022 14:24:29 +0200 Subject: [PATCH 111/205] PHP V8 warning --- htdocs/fourn/commande/list.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 6d026272cc7..8d03dbb387c 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -7,7 +7,7 @@ * Copyright (C) 2014 Juanjo Menent * Copyright (C) 2016 Ferran Marcet * Copyright (C) 2018-2021 Frédéric France - * Copyright (C) 2018-2020 Charlene Benke + * Copyright (C) 2018-2022 Charlene Benke * Copyright (C) 2019 Nicolas Zabouri * Copyright (C) 2021 Alexandre Spangaro * @@ -1557,6 +1557,7 @@ if ($resql) { $totalarray = array('nbfield' => 0, 'val' => array(), 'pos' => array()); $totalarray['val']['cf.total_ht'] = 0; $totalarray['val']['cf.total_ttc'] = 0; + $totalarray['val']['cf.total_tva'] = 0; $imaxinloop = ($limit ? min($num, $limit) : $num); while ($i < $imaxinloop) { From 7404e8fb75567fb06c754f88f0ac21f8c2c01956 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 14:50:21 +0200 Subject: [PATCH 112/205] Debug v16 --- htdocs/compta/index.php | 25 +++++++++++++++---------- htdocs/core/lib/invoice.lib.php | 4 +++- htdocs/langs/en_US/admin.lang | 2 +- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/htdocs/compta/index.php b/htdocs/compta/index.php index e7cb0b1d4b5..55ee99f4cb6 100644 --- a/htdocs/compta/index.php +++ b/htdocs/compta/index.php @@ -102,19 +102,24 @@ print load_fiche_titre($langs->trans("AccountancyTreasuryArea"), '', 'bill'); print '
'; -print getNumberInvoicesPieChart('customers'); -print '
'; +if (isModEnabled('facture')) { + print getNumberInvoicesPieChart('customers'); + print '
'; +} -if (!empty($conf->fournisseur->enabled)) { +if (isModEnabled('fournisseur') || isModEnabled('supplier_invoice')) { print getNumberInvoicesPieChart('fourn'); print '
'; } -print getCustomerInvoiceDraftTable($max, $socid); - -if (!empty($conf->fournisseur->enabled)) { +if (isModEnabled('facture')) { + print getCustomerInvoiceDraftTable($max, $socid); print '
'; +} + +if (isModEnabled('fournisseur') || isModEnabled('supplier_invoice')) { print getDraftSupplierTable($max, $socid); + print '
'; } print '
'; @@ -273,7 +278,7 @@ if (isModEnabled('facture') && !empty($user->rights->facture->lire)) { // Last modified supplier invoices -if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire) || (!empty($conf->supplier_invoice->enabled) && $user->rights->supplier_invoice->lire)) { +if ((isModEnabled('fournisseur') && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire) || (isModEnabled('supplier_invoice') && $user->rights->supplier_invoice->lire)) { $langs->load("boxes"); $facstatic = new FactureFournisseur($db); @@ -400,7 +405,7 @@ if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SU // Latest donations -if (!empty($conf->don->enabled) && !empty($user->rights->don->lire)) { +if (isModEnabled('don') && !empty($user->rights->don->lire)) { include_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php'; $langs->load("boxes"); @@ -490,7 +495,7 @@ if (!empty($conf->don->enabled) && !empty($user->rights->don->lire)) { /** * Social contributions to pay */ -if (!empty($conf->tax->enabled) && !empty($user->rights->tax->charges->lire)) { +if (isModEnabled('tax') && !empty($user->rights->tax->charges->lire)) { if (!$socid) { $chargestatic = new ChargeSociales($db); @@ -582,7 +587,7 @@ if (!empty($conf->tax->enabled) && !empty($user->rights->tax->charges->lire)) { /* * Customers orders to be billed */ -if (isModEnabled('facture') && !empty($conf->commande->enabled) && $user->rights->commande->lire && empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) { +if (isModEnabled('facture') && isModEnabled('commande') && $user->rights->commande->lire && empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) { $commandestatic = new Commande($db); $langs->load("orders"); diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index ea53ae065e3..52daea0f150 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -254,7 +254,9 @@ function supplier_invoice_rec_prepare_head($object) function getNumberInvoicesPieChart($mode) { global $conf, $db, $langs, $user; - if (isModEnabled('facture') && !empty($user->rights->facture->lire)) { + if (($mode == 'customers' && isModEnabled('facture') && !empty($user->rights->facture->lire)) + || ($mode = 'suppliers') && (isModEnabled('fournisseur') || isModEnabled('supplier_invoice')) && !empty($user->rights->facture->lire) + ) { include DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/theme_vars.inc.php'; $now = date_create(date('Y-m-d', dol_now())); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index c720c3be8a7..c1f01ae85d9 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1130,7 +1130,7 @@ ValueOfConstantKey=Value of a configuration constant ConstantIsOn=Option %s is on NbOfDays=No. of days AtEndOfMonth=At end of month -CurrentNext=Current/Next +CurrentNext=A given day in month Offset=Offset AlwaysActive=Always active Upgrade=Upgrade From f0c85237137f701a68f7d56d1e717c99aa4976c9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 14:50:21 +0200 Subject: [PATCH 113/205] Debug v16 --- htdocs/compta/index.php | 25 +++++++++++++++---------- htdocs/core/lib/invoice.lib.php | 4 +++- htdocs/langs/en_US/admin.lang | 2 +- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/htdocs/compta/index.php b/htdocs/compta/index.php index e7cb0b1d4b5..55ee99f4cb6 100644 --- a/htdocs/compta/index.php +++ b/htdocs/compta/index.php @@ -102,19 +102,24 @@ print load_fiche_titre($langs->trans("AccountancyTreasuryArea"), '', 'bill'); print '
'; -print getNumberInvoicesPieChart('customers'); -print '
'; +if (isModEnabled('facture')) { + print getNumberInvoicesPieChart('customers'); + print '
'; +} -if (!empty($conf->fournisseur->enabled)) { +if (isModEnabled('fournisseur') || isModEnabled('supplier_invoice')) { print getNumberInvoicesPieChart('fourn'); print '
'; } -print getCustomerInvoiceDraftTable($max, $socid); - -if (!empty($conf->fournisseur->enabled)) { +if (isModEnabled('facture')) { + print getCustomerInvoiceDraftTable($max, $socid); print '
'; +} + +if (isModEnabled('fournisseur') || isModEnabled('supplier_invoice')) { print getDraftSupplierTable($max, $socid); + print '
'; } print '
'; @@ -273,7 +278,7 @@ if (isModEnabled('facture') && !empty($user->rights->facture->lire)) { // Last modified supplier invoices -if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire) || (!empty($conf->supplier_invoice->enabled) && $user->rights->supplier_invoice->lire)) { +if ((isModEnabled('fournisseur') && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire) || (isModEnabled('supplier_invoice') && $user->rights->supplier_invoice->lire)) { $langs->load("boxes"); $facstatic = new FactureFournisseur($db); @@ -400,7 +405,7 @@ if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SU // Latest donations -if (!empty($conf->don->enabled) && !empty($user->rights->don->lire)) { +if (isModEnabled('don') && !empty($user->rights->don->lire)) { include_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php'; $langs->load("boxes"); @@ -490,7 +495,7 @@ if (!empty($conf->don->enabled) && !empty($user->rights->don->lire)) { /** * Social contributions to pay */ -if (!empty($conf->tax->enabled) && !empty($user->rights->tax->charges->lire)) { +if (isModEnabled('tax') && !empty($user->rights->tax->charges->lire)) { if (!$socid) { $chargestatic = new ChargeSociales($db); @@ -582,7 +587,7 @@ if (!empty($conf->tax->enabled) && !empty($user->rights->tax->charges->lire)) { /* * Customers orders to be billed */ -if (isModEnabled('facture') && !empty($conf->commande->enabled) && $user->rights->commande->lire && empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) { +if (isModEnabled('facture') && isModEnabled('commande') && $user->rights->commande->lire && empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) { $commandestatic = new Commande($db); $langs->load("orders"); diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index ea53ae065e3..52daea0f150 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -254,7 +254,9 @@ function supplier_invoice_rec_prepare_head($object) function getNumberInvoicesPieChart($mode) { global $conf, $db, $langs, $user; - if (isModEnabled('facture') && !empty($user->rights->facture->lire)) { + if (($mode == 'customers' && isModEnabled('facture') && !empty($user->rights->facture->lire)) + || ($mode = 'suppliers') && (isModEnabled('fournisseur') || isModEnabled('supplier_invoice')) && !empty($user->rights->facture->lire) + ) { include DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/theme_vars.inc.php'; $now = date_create(date('Y-m-d', dol_now())); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 5b43bc2b457..c8d7d48ff1c 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1129,7 +1129,7 @@ ValueOfConstantKey=Value of a configuration constant ConstantIsOn=Option %s is on NbOfDays=No. of days AtEndOfMonth=At end of month -CurrentNext=Current/Next +CurrentNext=A given day in month Offset=Offset AlwaysActive=Always active Upgrade=Upgrade From cc9cc7f832750ad94c241a7bf559f161f23ce4be Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 13:58:30 +0200 Subject: [PATCH 114/205] Picto --- htdocs/product/stock/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/stock/index.php b/htdocs/product/stock/index.php index 9aad5f382cc..6efe9f0d9e8 100644 --- a/htdocs/product/stock/index.php +++ b/htdocs/product/stock/index.php @@ -141,7 +141,7 @@ print '
'; $max = 10; $sql = "SELECT p.rowid, p.label as produit, p.tobatch, p.tosell, p.tobuy,"; $sql .= " e.ref as warehouse_ref, e.rowid as warehouse_id, e.ref as warehouse_label, e.lieu, e.statut as warehouse_status,"; -$sql .= " m.value as qty, m.datem, m.batch, m.eatby, m.sellby"; +$sql .= " m.rowid as mid, m.value as qty, m.datem, m.batch, m.eatby, m.sellby"; $sql .= " FROM ".MAIN_DB_PREFIX."entrepot as e"; $sql .= ", ".MAIN_DB_PREFIX."stock_mouvement as m"; $sql .= ", ".MAIN_DB_PREFIX."product as p"; @@ -200,7 +200,7 @@ if ($resql) { $tmplotstatic->eatby = $objp->eatby; print '
'; - print ''; + print ''; print '\n"; From d1d5e0836f1ca86da8301c6ce794eed48a3414c5 Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Fri, 29 Jul 2022 13:04:04 +0200 Subject: [PATCH 115/205] Fix : HasRight on user.class.php for $permlevel2 --- htdocs/user/class/user.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index fcd1505a402..b8c19ea28f1 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -775,16 +775,16 @@ class User extends CommonObject // For backward compatibility with old permissions called "lire", "creer", "create", "supprimer" // instead of "read", "write", "delete" if ($permlevel2 == 'read' && !empty($this->rights->$rightsPath->$permlevel1->lire)) { - return $this->rights->$rightsPath->lire; + return $this->rights->$rightsPath->$permlevel1->lire; } if ($permlevel2 == 'write' && !empty($this->rights->$rightsPath->$permlevel1->creer)) { - return $this->rights->$rightsPath->create; + return $this->rights->$rightsPath->$permlevel1->create; } if ($permlevel2 == 'write' && !empty($this->rights->$rightsPath->$permlevel1->create)) { - return $this->rights->$rightsPath->create; + return $this->rights->$rightsPath->$permlevel1->create; } if ($permlevel2 == 'delete' && !empty($this->rights->$rightsPath->$permlevel1->supprimer)) { - return $this->rights->$rightsPath->supprimer; + return $this->rights->$rightsPath->$permlevel1->supprimer; } } } else { From b27e8582f173ca17f179b7c76fee75c2a5ce35e5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 15:22:16 +0200 Subject: [PATCH 116/205] Log --- ChangeLog | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3c8e78fe83b..c93a61a15c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,7 +9,9 @@ English Dolibarr ChangeLog For users: --------------- -NEW: PHP 8.1 compatibility +NEW: PHP 8.1 compatibility. + Warning: Application works correctly with PHP8 and 8.1 but you may experience a lot of PHP warning into the PHP server log files (depending + on the PHP setup). Removal of all PHP warnings on server side is planned for v17. NEW: Support for recurring purchase invoices. NEW: #20292 Include German public holidays NEW: Can show ZATCA QRCode on PDFs From 6d2219e00c37aa8ad8074dea86bca311c18e65cc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 15:26:34 +0200 Subject: [PATCH 117/205] Update commonobject.class.php --- htdocs/core/class/commonobject.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 13e7cb333b8..ab61d1f3381 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -8189,7 +8189,7 @@ abstract class CommonObject $("select[name=\""+child_list+"\"] option[parent]").remove(); $("select[name=\""+child_list+"\"]").append(options); } - } else if(val > 0) { + } elseif(val > 0) { var options = orig_select.find("option[parent=\""+parentVal+"\"]").clone(); $("select[name=\""+child_list+"\"] option[parent]").remove(); $("select[name=\""+child_list+"\"]").append(options); @@ -8212,7 +8212,7 @@ abstract class CommonObject if ($("#"+child_list).val() == 0 && $("#"+parent_list).val() == 0){ $("#"+child_list).hide(); //Show mother lists - } else if ($("#"+parent_list).val() != 0){ + } elseif ($("#"+parent_list).val() != 0){ $("#"+parent_list).show(); } //Show the child list if the parent list value is selected @@ -8320,8 +8320,8 @@ abstract class CommonObject /** * Get buy price to use for margin calculation. This function is called when buy price is unknown. * Set buy price = sell price if ForceBuyingPriceIfNull configured, - * else if calculation MARGIN_TYPE = 'costprice' and costprice is defined, use costprice as buyprice - * else if calculation MARGIN_TYPE = 'pmp' and pmp is calculated, use pmp as buyprice + * elseif calculation MARGIN_TYPE = 'costprice' and costprice is defined, use costprice as buyprice + * elseif calculation MARGIN_TYPE = 'pmp' and pmp is calculated, use pmp as buyprice * else set min buy price as buy price * * @param float $unitPrice Product unit price @@ -8934,7 +8934,7 @@ abstract class CommonObject return 'NULL'; } elseif (preg_match('/^(int|double|real|price)/i', $fieldsentry['type'])) { return price2num("$value"); - } else if (preg_match('/int$/i', $fieldsentry['type'])) { + } elseif (preg_match('/int$/i', $fieldsentry['type'])) { return (int)$value; } elseif ($fieldsentry['type'] == 'boolean') { if ($value) { From c181b0bff4d480162efc139e6cbabc5b0112df26 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 15:27:20 +0200 Subject: [PATCH 118/205] Update commonobject.class.php --- htdocs/core/class/commonobject.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index ab61d1f3381..60c986b5531 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -8935,7 +8935,7 @@ abstract class CommonObject } elseif (preg_match('/^(int|double|real|price)/i', $fieldsentry['type'])) { return price2num("$value"); } elseif (preg_match('/int$/i', $fieldsentry['type'])) { - return (int)$value; + return (int) $value; } elseif ($fieldsentry['type'] == 'boolean') { if ($value) { return 'true'; From 5e4ed0dea0940a795cd8a418e8e5d9ca622530d8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 15:28:33 +0200 Subject: [PATCH 119/205] Update commonobject.class.php --- htdocs/core/class/commonobject.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 60c986b5531..ea58d599100 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -8189,7 +8189,7 @@ abstract class CommonObject $("select[name=\""+child_list+"\"] option[parent]").remove(); $("select[name=\""+child_list+"\"]").append(options); } - } elseif(val > 0) { + } else if(val > 0) { var options = orig_select.find("option[parent=\""+parentVal+"\"]").clone(); $("select[name=\""+child_list+"\"] option[parent]").remove(); $("select[name=\""+child_list+"\"]").append(options); @@ -8212,7 +8212,7 @@ abstract class CommonObject if ($("#"+child_list).val() == 0 && $("#"+parent_list).val() == 0){ $("#"+child_list).hide(); //Show mother lists - } elseif ($("#"+parent_list).val() != 0){ + } else if ($("#"+parent_list).val() != 0){ $("#"+parent_list).show(); } //Show the child list if the parent list value is selected From 75a8fdce111730bb1fbdd0ab3b445da93780db76 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Fri, 29 Jul 2022 13:33:16 +0000 Subject: [PATCH 120/205] Fixing style errors. --- htdocs/core/modules/modEventOrganization.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/modEventOrganization.class.php b/htdocs/core/modules/modEventOrganization.class.php index 57b05131025..c70897ae9df 100644 --- a/htdocs/core/modules/modEventOrganization.class.php +++ b/htdocs/core/modules/modEventOrganization.class.php @@ -375,10 +375,10 @@ class modEventOrganization extends DolibarrModules $init = $this->_init($sql, $options); - if(empty($conf->global->EVENTORGANIZATION_CATEG_THIRDPARTY_CONF)) { + if (empty($conf->global->EVENTORGANIZATION_CATEG_THIRDPARTY_CONF)) { $langs->load('eventorganization'); $res = $cat->fetch(null, $langs->trans('ApplicantOrVisitor')); - if($cat->id) { + if ($cat->id) { dolibarr_set_const($this->db, 'EVENTORGANIZATION_CATEG_THIRDPARTY_CONF', $res); } } From 9cc9b841387e8339786e8f7607d03275436e8621 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 15:39:37 +0200 Subject: [PATCH 121/205] Update modEventOrganization.class.php --- htdocs/core/modules/modEventOrganization.class.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/htdocs/core/modules/modEventOrganization.class.php b/htdocs/core/modules/modEventOrganization.class.php index c70897ae9df..5dd212b355d 100644 --- a/htdocs/core/modules/modEventOrganization.class.php +++ b/htdocs/core/modules/modEventOrganization.class.php @@ -368,21 +368,8 @@ class modEventOrganization extends DolibarrModules } } - $langs->load("eventorganization"); - $cat = new Categorie($this->db); - $sql[] = "INSERT IGNORE INTO ".MAIN_DB_PREFIX.$cat->table_element."(label, type, entity, description, visible) VALUES('".$langs->trans('ApplicantOrVisitor')."', 2, 1, '".$langs->trans('EVENTORGANIZATION_CATEG_THIRDPARTY_CONF')."', 1)"; - $sql[] = "INSERT IGNORE INTO ".MAIN_DB_PREFIX."c_type_contact(rowid, element, source, code, libelle, active) VALUES(300, 'conferenceorbooth', 'external', 'SPEAKER', '".$langs->trans('Speaker')."', 1)"; - $init = $this->_init($sql, $options); - if (empty($conf->global->EVENTORGANIZATION_CATEG_THIRDPARTY_CONF)) { - $langs->load('eventorganization'); - $res = $cat->fetch(null, $langs->trans('ApplicantOrVisitor')); - if ($cat->id) { - dolibarr_set_const($this->db, 'EVENTORGANIZATION_CATEG_THIRDPARTY_CONF', $res); - } - } - return $init; } From 05ca9da7e1a63627cdbf9a3967e320740deae9ec Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Fri, 29 Jul 2022 15:46:13 +0200 Subject: [PATCH 122/205] Fix : php 8.1 warnings --- htdocs/core/lib/functions.lib.php | 2 +- htdocs/core/menus/standard/eldy.lib.php | 4 +- htdocs/main.inc.php | 26 ++++++------- htdocs/user/card.php | 50 ++++++++++++------------- htdocs/user/document.php | 24 ++++++------ htdocs/user/group/card.php | 22 +++++------ htdocs/user/group/list.php | 9 +++-- htdocs/user/group/perms.php | 10 ++--- htdocs/user/hierarchy.php | 4 +- htdocs/user/list.php | 28 +++++++------- htdocs/user/note.php | 14 +++---- htdocs/user/param_ihm.php | 14 +++---- htdocs/user/perms.php | 16 ++++---- 13 files changed, 112 insertions(+), 111 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index b286adae481..89ce32b9069 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -10422,7 +10422,7 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = global $hookmanager, $action, $object, $langs; //var_dump($params); - if ($params['isDropdown']) + if (!empty($params['isDropdown'])) $class = "dropdown-item"; else { $class = 'butAction'; diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 3b2a1c1ec50..4707657d3e3 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1154,7 +1154,7 @@ function get_left_menu_home($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = if ($user->rights->user->user->lire) { if ($usemenuhider || empty($leftmenu) || $leftmenu == "users") { $newmenu->add("", $langs->trans("Users"), 1, $user->rights->user->user->lire || $user->admin); - $newmenu->add("/user/card.php?leftmenu=users&action=create", $langs->trans("NewUser"), 2, ($user->rights->user->user->creer || $user->admin) && !(isModEnabled('multicompany') && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE), '', 'home'); + $newmenu->add("/user/card.php?leftmenu=users&action=create", $langs->trans("NewUser"), 2, ($user->hasRight("user", "user", "write") || $user->admin) && !(isModEnabled('multicompany') && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE), '', 'home'); $newmenu->add("/user/list.php?leftmenu=users", $langs->trans("ListOfUsers"), 2, $user->rights->user->user->lire || $user->admin); $newmenu->add("/user/hierarchy.php?leftmenu=users", $langs->trans("HierarchicView"), 2, $user->rights->user->user->lire || $user->admin); if (isModEnabled('categorie')) { @@ -1162,7 +1162,7 @@ function get_left_menu_home($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = $newmenu->add("/categories/index.php?leftmenu=users&type=7", $langs->trans("UsersCategoriesShort"), 2, $user->rights->categorie->lire, '', $mainmenu, 'cat'); } $newmenu->add("", $langs->trans("Groups"), 1, ($user->rights->user->user->lire || $user->admin) && !(isModEnabled('multicompany') && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE)); - $newmenu->add("/user/group/card.php?leftmenu=users&action=create", $langs->trans("NewGroup"), 2, ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) ? $user->rights->user->group_advance->write : $user->rights->user->user->creer) || $user->admin) && !(isModEnabled('multicompany') && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE)); + $newmenu->add("/user/group/card.php?leftmenu=users&action=create", $langs->trans("NewGroup"), 2, ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) ? $user->hasRight("user", "group_advance", "create") : $user->hasRight("user", "user", "create")) || $user->admin) && !(isModEnabled('multicompany') && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE)); $newmenu->add("/user/group/list.php?leftmenu=users", $langs->trans("ListOfGroups"), 2, ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) ? $user->rights->user->group_advance->read : $user->rights->user->user->lire) || $user->admin) && !(isModEnabled('multicompany') && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE)); } } diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 5108a5eb332..782f75b0190 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -2413,7 +2413,7 @@ function printDropdownQuickadd() "title" => "MenuNewMember@members", "name" => "Adherent@members", "picto" => "object_member", - "activation" => !empty($conf->adherent->enabled) && $user->rights->adherent->creer, // vs hooking + "activation" => !empty($conf->adherent->enabled) && $user->hasRight("adherent", "write"), // vs hooking "position" => 5, ), array( @@ -2421,7 +2421,7 @@ function printDropdownQuickadd() "title" => "MenuNewThirdParty@companies", "name" => "ThirdParty@companies", "picto" => "object_company", - "activation" => !empty($conf->societe->enabled) && $user->rights->societe->creer, // vs hooking + "activation" => !empty($conf->societe->enabled) && $user->hasRight("societe", "write"), // vs hooking "position" => 10, ), array( @@ -2429,7 +2429,7 @@ function printDropdownQuickadd() "title" => "NewContactAddress@companies", "name" => "Contact@companies", "picto" => "object_contact", - "activation" => !empty($conf->societe->enabled) && $user->rights->societe->contact->creer, // vs hooking + "activation" => !empty($conf->societe->enabled) && $user->hasRight("societe", "contact", "write"), // vs hooking "position" => 20, ), array( @@ -2437,7 +2437,7 @@ function printDropdownQuickadd() "title" => "NewPropal@propal", "name" => "Proposal@propal", "picto" => "object_propal", - "activation" => !empty($conf->propal->enabled) && $user->rights->propale->creer, // vs hooking + "activation" => !empty($conf->propal->enabled) && $user->hasRight("propale", "write"), // vs hooking "position" => 30, ), @@ -2446,7 +2446,7 @@ function printDropdownQuickadd() "title" => "NewOrder@orders", "name" => "Order@orders", "picto" => "object_order", - "activation" => !empty($conf->commande->enabled) && $user->rights->commande->creer, // vs hooking + "activation" => !empty($conf->commande->enabled) && $user->hasRight("commande", "write"), // vs hooking "position" => 40, ), array( @@ -2454,7 +2454,7 @@ function printDropdownQuickadd() "title" => "NewBill@bills", "name" => "Bill@bills", "picto" => "object_bill", - "activation" => isModEnabled('facture') && $user->rights->facture->creer, // vs hooking + "activation" => isModEnabled('facture') && $user->hasRight("facture", "write"), // vs hooking "position" => 50, ), array( @@ -2462,7 +2462,7 @@ function printDropdownQuickadd() "title" => "NewContractSubscription@contracts", "name" => "Contract@contracts", "picto" => "object_contract", - "activation" => !empty($conf->contrat->enabled) && $user->rights->contrat->creer, // vs hooking + "activation" => !empty($conf->contrat->enabled) && $user->hasRight("contrat", "write"), // vs hooking "position" => 60, ), array( @@ -2470,7 +2470,7 @@ function printDropdownQuickadd() "title" => "SupplierProposalNew@supplier_proposal", "name" => "SupplierProposal@supplier_proposal", "picto" => "supplier_proposal", - "activation" => !empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->creer, // vs hooking + "activation" => !empty($conf->supplier_proposal->enabled) && $user->hasRight("supplier_invoice", "write"), // vs hooking "position" => 70, ), array( @@ -2478,7 +2478,7 @@ function printDropdownQuickadd() "title" => "NewSupplierOrderShort@orders", "name" => "SupplierOrder@orders", "picto" => "supplier_order", - "activation" => (!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->commande->creer) || (!empty($conf->supplier_order->enabled) && $user->rights->supplier_order->creer), // vs hooking + "activation" => (!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "commande", "write")) || (!empty($conf->supplier_order->enabled) && $user->hasRight("supplier_invoice", "write")), // vs hooking "position" => 80, ), array( @@ -2486,7 +2486,7 @@ function printDropdownQuickadd() "title" => "NewBill@bills", "name" => "SupplierBill@bills", "picto" => "supplier_invoice", - "activation" => (!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->creer) || (!empty($conf->supplier_invoice->enabled) && $user->rights->supplier_invoice->creer), // vs hooking + "activation" => (!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "write")) || (!empty($conf->supplier_invoice->enabled) && $user->hasRight("supplier_invoice", "write")), // vs hooking "position" => 90, ), array( @@ -2494,7 +2494,7 @@ function printDropdownQuickadd() "title" => "NewProduct@products", "name" => "Product@products", "picto" => "object_product", - "activation" => !empty($conf->product->enabled) && $user->rights->produit->creer, // vs hooking + "activation" => !empty($conf->product->enabled) && $user->hasRight("produit", "write"), // vs hooking "position" => 100, ), array( @@ -2502,7 +2502,7 @@ function printDropdownQuickadd() "title" => "NewService@products", "name" => "Service@products", "picto" => "object_service", - "activation" => !empty($conf->service->enabled) && $user->rights->service->creer, // vs hooking + "activation" => !empty($conf->service->enabled) && $user->hasRight("service", "write"), // vs hooking "position" => 110, ), array( @@ -2510,7 +2510,7 @@ function printDropdownQuickadd() "title" => "AddUser@users", "name" => "User@users", "picto" => "user", - "activation" => $user->rights->user->user->creer, // vs hooking + "activation" => $user->hasRight("user", "user", "write"), // vs hooking "position" => 500, ), ), diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 5f8a4be0446..8e375933a91 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -76,15 +76,15 @@ $dateendvalidity = dol_mktime(0, 0, 0, GETPOST('dateendvaliditymonth', 'int'), G $dateofbirth = dol_mktime(0, 0, 0, GETPOST('dateofbirthmonth', 'int'), GETPOST('dateofbirthday', 'int'), GETPOST('dateofbirthyear', 'int')); // Define value to know what current user can do on users -$canadduser = (!empty($user->admin) || $user->rights->user->user->creer); -$canreaduser = (!empty($user->admin) || $user->rights->user->user->lire); -$canedituser = (!empty($user->admin) || $user->rights->user->user->creer); -$candisableuser = (!empty($user->admin) || $user->rights->user->user->supprimer); +$canadduser = (!empty($user->admin) || $user->hasRight("user", "user", "write")); +$canreaduser = (!empty($user->admin) || $user->hasRight("user", "user", "read")); +$canedituser = (!empty($user->admin) || $user->hasRight("user", "user", "write")); +$candisableuser = (!empty($user->admin) || $user->hasRight("user", "user", "delete")); $canreadgroup = $canreaduser; $caneditgroup = $canedituser; if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - $canreadgroup = (!empty($user->admin) || $user->rights->user->group_advance->read); - $caneditgroup = (!empty($user->admin) || $user->rights->user->group_advance->write); + $canreadgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "read")); + $caneditgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "write")); } $childids = $user->getAllChildIds(1); // For later, test on salary visibility @@ -92,8 +92,8 @@ $childids = $user->getAllChildIds(1); // For later, test on salary visibility // Define value to know what current user can do on properties of edited user if ($id > 0) { // $user is the current logged user, $id is the user we want to edit - $caneditfield = ((($user->id == $id) && $user->rights->user->self->creer) || (($user->id != $id) && $user->rights->user->user->creer)); - $caneditpassword = ((($user->id == $id) && $user->rights->user->self->password) || (($user->id != $id) && $user->rights->user->user->password)); + $caneditfield = ((($user->id == $id) && $user->hasRight("user", "self", "write")) || (($user->id != $id) && $user->hasRight("user", "user", "write"))); + $caneditpassword = ((($user->id == $id) && $user->hasRight("user", "self", "password")) || (($user->id != $id) && $user->hasRight("user", "user", "password"))); } // Security check @@ -712,7 +712,7 @@ if (empty($reshook)) { // Actions to build doc $upload_dir = $conf->user->dir_output; - $permissiontoadd = $user->rights->user->user->creer; + $permissiontoadd = $user->hasRight("user", "user", "write"); include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; } @@ -1165,7 +1165,7 @@ if ($action == 'create' || $action == 'adduserldap') { } // Categories - if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) { + if (!empty($conf->categorie->enabled) && !empty($user->hasRight("categorie", "read"))) { print ''; - if ((!empty($conf->salaries->enabled) && !empty($user->rights->salaries->read) && in_array($id, $childids)) - || (!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall)) - || (!empty($conf->hrm->enabled) && !empty($user->rights->hrm->employee->read))) { + if ((!empty($conf->salaries->enabled) && !empty($user->hasRight("salaries", "read")) && in_array($id, $childids)) + || (!empty($conf->salaries->enabled) && !empty($user->hasRight("salaries", "readall"))) + || (!empty($conf->hrm->enabled) && !empty($user->hasRight("hrm", "employee", "read")))) { $langs->load("salaries"); // THM @@ -1365,7 +1365,7 @@ if ($action == 'create' || $action == 'adduserldap') { $title = $langs->trans("User"); $linkback = ''; - if ($user->rights->user->user->lire || $user->admin) { + if ($user->hasRight("user", "user", "read") || $user->admin) { $linkback = ''.$langs->trans("BackToList").''; } } @@ -1417,7 +1417,7 @@ if ($action == 'create' || $action == 'adduserldap') { $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); $morehtmlref .= ''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); + dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; print '
'; @@ -1541,8 +1541,8 @@ if ($action == 'create' || $action == 'adduserldap') { // Sensitive salary/value information if ((empty($user->socid) && in_array($id, $childids)) // A user can always see salary/value information for its subordinates - || (!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall)) - || (!empty($conf->hrm->enabled) && !empty($user->rights->hrm->employee->read))) { + || (!empty($conf->salaries->enabled) && !empty($user->hasRight("salaries", "readall"))) + || (!empty($conf->hrm->enabled) && !empty($user->hasRight("hrm", "employee", "read")))) { $langs->load("salaries"); // Salary @@ -1625,7 +1625,7 @@ if ($action == 'create' || $action == 'adduserldap') { } // Categories - if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) { + if (!empty($conf->categorie->enabled) && !empty($user->hasRight("categorie", "read"))) { print '
'; print ''."\n"; // API key - if (!empty($conf->api->enabled) && ($user->id == $id || $user->admin || $user->rights->api->apikey->generate)) { + if (!empty($conf->api->enabled) && ($user->id == $id || $user->admin || $user->hasRight("api", "apikey", "generate"))) { print ''; print '\n"; // API key - if (!empty($conf->api->enabled) && ($user->id == $id || $user->admin || $user->rights->api->apikey->generate)) { + if (!empty($conf->api->enabled) && ($user->id == $id || $user->admin || $user->hasRight("api", "apikey", "generate"))) { print ''; print ''; // Categories - if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) { + if (!empty($conf->categorie->enabled) && !empty($user->hasRight("categorie", "read"))) { print ''; print ''; - $editenabled = (($action == 'edit') && !empty($user->rights->user->user->creer)); + $editenabled = (($action == 'edit') && !empty($user->hasRight("user", "user", "write"))); // Note print ''; @@ -171,7 +171,7 @@ if ($id) { print '
'; - if ($user->rights->user->user->creer && $action != 'edit') { + if ($user->hasRight("user", "user", "write") && $action != 'edit') { print ''.$langs->trans('Modify').""; } diff --git a/htdocs/user/param_ihm.php b/htdocs/user/param_ihm.php index 4c138bfde6e..6a5eea96490 100644 --- a/htdocs/user/param_ihm.php +++ b/htdocs/user/param_ihm.php @@ -32,7 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; $langs->loadLangs(array('companies', 'products', 'admin', 'users', 'languages', 'projects', 'members')); // Defini si peux lire/modifier permisssions -$canreaduser = ($user->admin || $user->rights->user->user->lire); +$canreaduser = ($user->admin || $user->hasRight("user", "user", "read")); $id = GETPOST('id', 'int'); $action = GETPOST('action', 'aZ09'); @@ -40,8 +40,8 @@ $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'use if ($id) { // $user est le user qui edite, $id est l'id de l'utilisateur edite - $caneditfield = ((($user->id == $id) && $user->rights->user->self->creer) - || (($user->id != $id) && $user->rights->user->user->creer)); + $caneditfield = ((($user->id == $id) && $user->hasRight("user", "self", "write")) + || (($user->id != $id) && $user->hasRight("user", "user", "write"))); } // Security check @@ -49,7 +49,7 @@ $socid = 0; if ($user->socid > 0) { $socid = $user->socid; } -$feature2 = (($socid && $user->rights->user->self->creer) ? '' : 'user'); +$feature2 = (($socid && $user->hasRight("user", "self", "write")) ? '' : 'user'); $result = restrictedArea($user, 'user', $id, 'user&user', $feature2); if ($user->id <> $id && !$canreaduser) { @@ -231,11 +231,11 @@ if ($action == 'edit') { $linkback = ''; - if ($user->rights->user->user->lire || $user->admin) { + if ($user->hasRight("user", "user", "read") || $user->admin) { $linkback = ''.$langs->trans("BackToList").''; } - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); + dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin); print '
'; @@ -346,7 +346,7 @@ if ($action == 'edit') { $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); $morehtmlref .= ''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); + dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; diff --git a/htdocs/user/perms.php b/htdocs/user/perms.php index 47d68703d69..bfc234abce1 100644 --- a/htdocs/user/perms.php +++ b/htdocs/user/perms.php @@ -50,13 +50,13 @@ if (!isset($id) || empty($id)) { } // Define if user can read permissions -$canreaduser = ($user->admin || $user->rights->user->user->lire); +$canreaduser = ($user->admin || $user->hasRight("user", "user", "read")); // Define if user can modify other users and permissions -$caneditperms = ($user->admin || $user->rights->user->user->creer); +$caneditperms = ($user->admin || $user->hasRight("user", "user", "write")); // Advanced permissions if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - $canreaduser = ($user->admin || ($user->rights->user->user->lire && $user->rights->user->user_advance->readperms)); - $caneditselfperms = ($user->id == $id && $user->rights->user->self_advance->writeperms); + $canreaduser = ($user->admin || ($user->hasRight("user", "user", "read") && $user->hasRight("user", "user_advance", "readperms"))); + $caneditselfperms = ($user->id == $id && $user->hasRight("user", "self_advance", "writeperms")); $caneditperms = (($caneditperms || $caneditselfperms) ? 1 : 0); } @@ -65,9 +65,9 @@ $socid = 0; if (isset($user->socid) && $user->socid > 0) { $socid = $user->socid; } -$feature2 = (($socid && $user->rights->user->self->creer) ? '' : 'user'); +$feature2 = (($socid && $user->hasRight("user", "self", "write")) ? '' : 'user'); // A user can always read its own card if not advanced perms enabled, or if he has advanced perms, except for admin -if ($user->id == $id && (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->user->self_advance->readperms) && empty($user->admin))) { +if ($user->id == $id && (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->hasRight("user", "self_advance", "readperms")) && empty($user->admin))) { accessforbidden(); } @@ -249,7 +249,7 @@ if ($result) { $linkback = ''; -if ($user->rights->user->user->lire || $user->admin) { +if ($user->hasRight("user", "user", "read") || $user->admin) { $linkback = ''.$langs->trans("BackToList").''; } @@ -257,7 +257,7 @@ $morehtmlref = 'trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); $morehtmlref .= ''; -dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); +dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; From 51d022914b4765f2855483b287941b42ad7481ba Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 16:03:21 +0200 Subject: [PATCH 123/205] Fix missing auto increment key. Fix error duplicate of type of contact. --- htdocs/admin/dict.php | 2 +- .../install/mysql/data/llx_c_type_contact.sql | 113 +++++++++--------- .../install/mysql/migration/15.0.0-16.0.0.sql | 20 ++++ .../mysql/tables/llx_c_type_contact.sql | 2 +- 4 files changed, 79 insertions(+), 58 deletions(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index fa5d6deae97..38fbfec8c87 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -2375,7 +2375,7 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') print '
'; - } elseif (in_array($value, array('element', 'source'))) { //Example: the type and source of the element (for contact types) + } elseif (in_array($value, array('element', 'source'))) { // Example: the type and source of the element (for contact types) print ''; diff --git a/htdocs/install/mysql/data/llx_c_type_contact.sql b/htdocs/install/mysql/data/llx_c_type_contact.sql index 825e21ddf42..5852e295c6b 100644 --- a/htdocs/install/mysql/data/llx_c_type_contact.sql +++ b/htdocs/install/mysql/data/llx_c_type_contact.sql @@ -32,88 +32,89 @@ -- -- The types of contact of an element --- Les types de contact d'un element +-- +-- The unique key is set on (element, source, code) -- -- Contract / Contrat -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (10, 'contrat', 'internal', 'SALESREPSIGN', 'Commercial signataire du contrat', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (11, 'contrat', 'internal', 'SALESREPFOLL', 'Commercial suivi du contrat', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (20, 'contrat', 'external', 'BILLING', 'Contact client facturation contrat', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (21, 'contrat', 'external', 'CUSTOMER', 'Contact client suivi contrat', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (22, 'contrat', 'external', 'SALESREPSIGN', 'Contact client signataire contrat', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('contrat', 'internal', 'SALESREPSIGN', 'Commercial signataire du contrat', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('contrat', 'internal', 'SALESREPFOLL', 'Commercial suivi du contrat', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('contrat', 'external', 'BILLING', 'Contact client facturation contrat', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('contrat', 'external', 'CUSTOMER', 'Contact client suivi contrat', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('contrat', 'external', 'SALESREPSIGN', 'Contact client signataire contrat', 1); -- Proposal / Propal -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (31, 'propal', 'internal', 'SALESREPFOLL', 'Commercial à l''origine de la propale', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (40, 'propal', 'external', 'BILLING', 'Contact client facturation propale', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (41, 'propal', 'external', 'CUSTOMER', 'Contact client suivi propale', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (42, 'propal', 'external', 'SHIPPING', 'Contact client livraison propale', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('propal', 'internal', 'SALESREPFOLL', 'Commercial à l''origine de la propale', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('propal', 'external', 'BILLING', 'Contact client facturation propale', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('propal', 'external', 'CUSTOMER', 'Contact client suivi propale', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('propal', 'external', 'SHIPPING', 'Contact client livraison propale', 1); -- Customer Invoice / Facture -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (50, 'facture', 'internal', 'SALESREPFOLL', 'Responsable suivi du paiement', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (60, 'facture', 'external', 'BILLING', 'Contact client facturation', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (61, 'facture', 'external', 'SHIPPING', 'Contact client livraison', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (62, 'facture', 'external', 'SERVICE', 'Contact client prestation', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('facture', 'internal', 'SALESREPFOLL', 'Responsable suivi du paiement', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('facture', 'external', 'BILLING', 'Contact client facturation', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('facture', 'external', 'SHIPPING', 'Contact client livraison', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('facture', 'external', 'SERVICE', 'Contact client prestation', 1); -- Supplier Invoice -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (70, 'invoice_supplier', 'internal', 'SALESREPFOLL', 'Responsable suivi du paiement', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (71, 'invoice_supplier', 'external', 'BILLING', 'Contact fournisseur facturation', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (72, 'invoice_supplier', 'external', 'SHIPPING', 'Contact fournisseur livraison', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (73, 'invoice_supplier', 'external', 'SERVICE', 'Contact fournisseur prestation', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('invoice_supplier', 'internal', 'SALESREPFOLL', 'Responsable suivi du paiement', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('invoice_supplier', 'external', 'BILLING', 'Contact fournisseur facturation', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('invoice_supplier', 'external', 'SHIPPING', 'Contact fournisseur livraison', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('invoice_supplier', 'external', 'SERVICE', 'Contact fournisseur prestation', 1); -- Agenda -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (80, 'agenda', 'internal', 'ACTOR', 'Responsable', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (81, 'agenda', 'internal', 'GUEST', 'Guest', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (85, 'agenda', 'external', 'ACTOR', 'Responsable', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (86, 'agenda', 'external', 'GUEST', 'Guest', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('agenda', 'internal', 'ACTOR', 'Responsable', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('agenda', 'internal', 'GUEST', 'Guest', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('agenda', 'external', 'ACTOR', 'Responsable', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('agenda', 'external', 'GUEST', 'Guest', 1); -- Customer Order / Commande -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (91, 'commande', 'internal', 'SALESREPFOLL', 'Responsable suivi de la commande', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (100,'commande', 'external', 'BILLING', 'Contact client facturation commande', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (101,'commande', 'external', 'CUSTOMER', 'Contact client suivi commande', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (102,'commande', 'external', 'SHIPPING', 'Contact client livraison commande', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('commande', 'internal', 'SALESREPFOLL', 'Responsable suivi de la commande', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('commande', 'external', 'BILLING', 'Contact client facturation commande', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('commande', 'external', 'CUSTOMER', 'Contact client suivi commande', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('commande', 'external', 'SHIPPING', 'Contact client livraison commande', 1); -- Intervention / Fichinter -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (120, 'fichinter', 'internal', 'INTERREPFOLL', 'Responsable suivi de l''intervention', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (121, 'fichinter', 'internal', 'INTERVENING', 'Intervenant', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (130, 'fichinter', 'external', 'BILLING', 'Contact client facturation intervention', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (131, 'fichinter', 'external', 'CUSTOMER', 'Contact client suivi de l''intervention', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('fichinter', 'internal', 'INTERREPFOLL', 'Responsable suivi de l''intervention', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('fichinter', 'internal', 'INTERVENING', 'Intervenant', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('fichinter', 'external', 'BILLING', 'Contact client facturation intervention', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('fichinter', 'external', 'CUSTOMER', 'Contact client suivi de l''intervention', 1); -- Supplier Order -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (140, 'order_supplier', 'internal', 'SALESREPFOLL', 'Responsable suivi de la commande', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (141, 'order_supplier', 'internal', 'SHIPPING', 'Responsable réception de la commande', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (142, 'order_supplier', 'external', 'BILLING', 'Contact fournisseur facturation commande', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (143, 'order_supplier', 'external', 'CUSTOMER', 'Contact fournisseur suivi commande', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (145, 'order_supplier', 'external', 'SHIPPING', 'Contact fournisseur livraison commande', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('order_supplier', 'internal', 'SALESREPFOLL', 'Responsable suivi de la commande', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('order_supplier', 'internal', 'SHIPPING', 'Responsable réception de la commande', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('order_supplier', 'external', 'BILLING', 'Contact fournisseur facturation commande', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('order_supplier', 'external', 'CUSTOMER', 'Contact fournisseur suivi commande', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('order_supplier', 'external', 'SHIPPING', 'Contact fournisseur livraison commande', 1); -- Resource -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (150, 'dolresource', 'internal', 'USERINCHARGE', 'In charge of resource', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (151, 'dolresource', 'external', 'THIRDINCHARGE', 'In charge of resource', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('dolresource', 'internal', 'USERINCHARGE', 'In charge of resource', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('dolresource', 'external', 'THIRDINCHARGE', 'In charge of resource', 1); -- Tickets -insert into llx_c_type_contact (rowid, element, source, code, libelle, active, module) values (155, 'ticket', 'internal', 'SUPPORTTEC', 'Utilisateur contact support', 1, NULL); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active, module) values (156, 'ticket', 'internal', 'CONTRIBUTOR', 'Intervenant', 1, NULL); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active, module) values (157, 'ticket', 'external', 'SUPPORTCLI', 'Contact client suivi incident', 1, NULL); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active, module) values (158, 'ticket', 'external', 'CONTRIBUTOR', 'Intervenant', 1, NULL); +insert into llx_c_type_contact (element, source, code, libelle, active, module) values ('ticket', 'internal', 'SUPPORTTEC', 'Utilisateur contact support', 1, NULL); +insert into llx_c_type_contact (element, source, code, libelle, active, module) values ('ticket', 'internal', 'CONTRIBUTOR', 'Intervenant', 1, NULL); +insert into llx_c_type_contact (element, source, code, libelle, active, module) values ('ticket', 'external', 'SUPPORTCLI', 'Contact client suivi incident', 1, NULL); +insert into llx_c_type_contact (element, source, code, libelle, active, module) values ('ticket', 'external', 'CONTRIBUTOR', 'Intervenant', 1, NULL); -- Projects / Projet - All project code can start with 'PROJECT' -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (160, 'project', 'internal', 'PROJECTLEADER', 'Chef de Projet', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (161, 'project', 'internal', 'PROJECTCONTRIBUTOR', 'Intervenant', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (170, 'project', 'external', 'PROJECTLEADER', 'Chef de Projet', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (171, 'project', 'external', 'PROJECTCONTRIBUTOR', 'Intervenant', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('project', 'internal', 'PROJECTLEADER', 'Chef de Projet', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('project', 'internal', 'PROJECTCONTRIBUTOR', 'Intervenant', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('project', 'external', 'PROJECTLEADER', 'Chef de Projet', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('project', 'external', 'PROJECTCONTRIBUTOR', 'Intervenant', 1); -- Project Tasks - All task code can start with 'TASK' -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (180, 'project_task', 'internal', 'TASKEXECUTIVE', 'Responsable', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (181, 'project_task', 'internal', 'TASKCONTRIBUTOR', 'Intervenant', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (190, 'project_task', 'external', 'TASKEXECUTIVE', 'Responsable', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (191, 'project_task', 'external', 'TASKCONTRIBUTOR', 'Intervenant', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('project_task', 'internal', 'TASKEXECUTIVE', 'Responsable', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('project_task', 'internal', 'TASKCONTRIBUTOR', 'Intervenant', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('project_task', 'external', 'TASKEXECUTIVE', 'Responsable', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('project_task', 'external', 'TASKCONTRIBUTOR', 'Intervenant', 1); -- Supplier proposal -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (110, 'supplier_proposal', 'internal', 'SALESREPFOLL', 'Responsable suivi de la demande', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (111, 'supplier_proposal', 'external', 'BILLING', 'Contact fournisseur facturation', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (112, 'supplier_proposal', 'external', 'SHIPPING', 'Contact fournisseur livraison', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (113, 'supplier_proposal', 'external', 'SERVICE', 'Contact fournisseur prestation', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('supplier_proposal', 'internal', 'SALESREPFOLL', 'Responsable suivi de la demande', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('supplier_proposal', 'external', 'BILLING', 'Contact fournisseur facturation', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('supplier_proposal', 'external', 'SHIPPING', 'Contact fournisseur livraison', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('supplier_proposal', 'external', 'SERVICE', 'Contact fournisseur prestation', 1); -- Event Organization -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (210, 'conferenceorbooth', 'internal', 'MANAGER', 'Conference or Booth manager', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (211, 'conferenceorbooth', 'external', 'SPEAKER', 'Conference Speaker', 1); -insert into llx_c_type_contact (rowid, element, source, code, libelle, active ) values (212, 'conferenceorbooth', 'external', 'RESPONSIBLE', 'Booth responsible', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('conferenceorbooth', 'internal', 'MANAGER', 'Conference or Booth manager', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('conferenceorbooth', 'external', 'SPEAKER', 'Conference Speaker', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('conferenceorbooth', 'external', 'RESPONSIBLE', 'Booth responsible', 1); diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql index 2131f1a4061..c94b1cfcdaa 100644 --- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -135,8 +135,28 @@ ALTER TABLE llx_partnership ADD UNIQUE INDEX uk_fk_type_fk_member (fk_type, fk_m ALTER TABLE llx_bank ADD COLUMN amount_main_currency double(24,8) NULL; + -- v16 +ALTER TABLE llx_element_contact DROP FOREIGN KEY fk_element_contact_fk_c_type_contact; +ALTER TABLE llx_societe_contacts DROP FOREIGN KEY fk_societe_contacts_fk_c_type_contact; + +--VMYSQL4.3 ALTER TABLE llx_c_type_contact ADD PRIMARY KEY(rowid); +--VMYSQL4.3 ALTER TABLE llx_c_type_contact CHANGE COLUMN rowid rowid INTEGER NOT NULL AUTO_INCREMENT; + +--VPGSQL8.2 CREATE SEQUENCE llx_c_type_contact_rowid_seq OWNED BY llx_c_type_contact.rowid; +--VPGSQL8.2 ALTER TABLE llx_c_type_contact ADD PRIMARY KEY (rowid); +--VPGSQL8.2 ALTER TABLE llx_c_type_contact ALTER COLUMN rowid SET DEFAULT nextval('llx_c_type_contact_rowid_seq'); +--VPGSQL8.2 SELECT setval('llx_c_type_contact_rowid_seq', MAX(rowid)) FROM llx_c_type_contact; + +insert into llx_c_type_contact(element, source, code, libelle, active ) values ('conferenceorbooth', 'internal', 'MANAGER', 'Conference or Booth manager', 1); +insert into llx_c_type_contact(element, source, code, libelle, active ) values ('conferenceorbooth', 'external', 'SPEAKER', 'Conference Speaker', 1); +insert into llx_c_type_contact(element, source, code, libelle, active ) values ('conferenceorbooth', 'external', 'RESPONSIBLE', 'Booth responsible', 1); + +ALTER TABLE llx_element_contact ADD CONSTRAINT fk_element_contact_fk_c_type_contact FOREIGN KEY (fk_c_type_contact) REFERENCES llx_c_type_contact(rowid); +ALTER TABLE llx_societe_contacts ADD CONSTRAINT fk_societe_contacts_fk_c_type_contact FOREIGN KEY (fk_c_type_contact) REFERENCES llx_c_type_contact(rowid); + + DROP TABLE llx_payment_salary_extrafields; DROP TABLE llx_asset_model_extrafields; DROP TABLE llx_asset_type_extrafields; diff --git a/htdocs/install/mysql/tables/llx_c_type_contact.sql b/htdocs/install/mysql/tables/llx_c_type_contact.sql index 4b12661657e..e2275e71e5f 100644 --- a/htdocs/install/mysql/tables/llx_c_type_contact.sql +++ b/htdocs/install/mysql/tables/llx_c_type_contact.sql @@ -29,7 +29,7 @@ create table llx_c_type_contact ( - rowid integer PRIMARY KEY, + rowid integer AUTO_INCREMENT PRIMARY KEY, element varchar(30) NOT NULL, source varchar(8) DEFAULT 'external' NOT NULL, code varchar(32) NOT NULL, From c4323b99a948ae409910fc84ddef028cc7605d57 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 10 Jul 2022 19:47:36 +0200 Subject: [PATCH 124/205] css --- htdocs/core/ajax/selectsearchbox.php | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/htdocs/core/ajax/selectsearchbox.php b/htdocs/core/ajax/selectsearchbox.php index 090fc52cb4f..54e3e1e4470 100644 --- a/htdocs/core/ajax/selectsearchbox.php +++ b/htdocs/core/ajax/selectsearchbox.php @@ -64,11 +64,11 @@ $arrayresult = array(); // Define $searchform -if (isModEnabled('adherent') && empty($conf->global->MAIN_SEARCHFORM_ADHERENT_DISABLED) && $user->rights->adherent->lire) { +if (isModEnabled('adherent') && empty($conf->global->MAIN_SEARCHFORM_ADHERENT_DISABLED) && $user->hasRight('adherent', 'lire')) { $arrayresult['searchintomember'] = array('position'=>8, 'shortcut'=>'M', 'img'=>'object_member', 'label'=>$langs->trans("SearchIntoMembers", $search_boxvalue), 'text'=>img_picto('', 'object_member', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoMembers", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/adherents/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (((!empty($conf->societe->enabled) && (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) || empty($conf->global->SOCIETE_DISABLE_CUSTOMERS))) || ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled))) && empty($conf->global->MAIN_SEARCHFORM_SOCIETE_DISABLED) && $user->rights->societe->lire) { +if (((isModEnabled('societe') && (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) || empty($conf->global->SOCIETE_DISABLE_CUSTOMERS))) || ((isModEnabled('fournisseur') && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled('supplier_order') || isModEnabled('supplier_invoice'))) && empty($conf->global->MAIN_SEARCHFORM_SOCIETE_DISABLED) && $user->hasRight('societe', 'lire')) { $arrayresult['searchintothirdparty'] = array('position'=>10, 'shortcut'=>'T', 'img'=>'object_company', 'label'=>$langs->trans("SearchIntoThirdparties", $search_boxvalue), 'text'=>img_picto('', 'object_company', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoThirdparties", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/societe/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } @@ -76,7 +76,7 @@ if (isModEnabled('societe') && empty($conf->global->MAIN_SEARCHFORM_CONTACT_DISA $arrayresult['searchintocontact'] = array('position'=>15, 'shortcut'=>'A', 'img'=>'object_contact', 'label'=>$langs->trans("SearchIntoContacts", $search_boxvalue), 'text'=>img_picto('', 'object_contact', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoContacts", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/contact/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (((!empty($conf->product->enabled) && $user->hasRight('produit', 'lire')) || (!empty($conf->service->enabled) && $user->hasRight('service', 'lire'))) && empty($conf->global->MAIN_SEARCHFORM_PRODUITSERVICE_DISABLED)) { +if (((isModEnabled('product') && $user->hasRight('produit', 'lire')) || (isModEnabled('service') && $user->hasRight('service', 'lire'))) && empty($conf->global->MAIN_SEARCHFORM_PRODUITSERVICE_DISABLED)) { $arrayresult['searchintoproduct'] = array('position'=>30, 'shortcut'=>'P', 'img'=>'object_product', 'label'=>$langs->trans("SearchIntoProductsOrServices", $search_boxvalue), 'text'=>img_picto('', 'object_product', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoProductsOrServices", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/product/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); // search on lot/serial numbers if (isModEnabled('productbatch')) { @@ -108,13 +108,13 @@ if (isModEnabled('facture') && empty($conf->global->MAIN_SEARCHFORM_CUSTOMER_INV $arrayresult['searchintoinvoice'] = array('position'=>90, 'img'=>'object_bill', 'label'=>$langs->trans("SearchIntoCustomerInvoices", $search_boxvalue), 'text'=>img_picto('', 'object_bill', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoCustomerInvoices", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/compta/facture/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (isModEnabled('supplier_proposal') && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_PROPAL_DISABLED) && $user->rights->supplier_proposal->lire) { +if (isModEnabled('supplier_proposal') && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_PROPAL_DISABLED) && $user->hasRight('supplier_proposal', 'lire')) { $arrayresult['searchintosupplierpropal'] = array('position'=>100, 'img'=>'object_supplier_proposal', 'label'=>$langs->trans("SearchIntoSupplierProposals", $search_boxvalue), 'text'=>img_picto('', 'object_supplier_proposal', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoSupplierProposals", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/supplier_proposal/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->commande->lire) || (!empty($conf->supplier_order->enabled) && $user->rights->supplier_order->lire)) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_ORDER_DISABLED)) { +if (((isModEnabled('fournisseur') && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight('fournisseur', 'commande', 'lire')) || (isModEnabled('supplier_order') && $user->hasRight('supplier_order', 'lire'))) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_ORDER_DISABLED)) { $arrayresult['searchintosupplierorder'] = array('position'=>110, 'img'=>'object_supplier_order', 'label'=>$langs->trans("SearchIntoSupplierOrders", $search_boxvalue), 'text'=>img_picto('', 'object_supplier_order', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoSupplierOrders", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/fourn/commande/list.php'.($search_boxvalue ? '?search_all='.urlencode($search_boxvalue) : '')); } -if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire) || (!empty($conf->supplier_invoice->enabled) && $user->rights->supplier_invoice->lire)) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_INVOICE_DISABLED)) { +if (((isModEnabled('fournisseur') && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight('fournisseur', 'facture', 'lire')) || (isModEnabled('supplier_invoice') && $user->hasRight('supplier_invoice', 'lire'))) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_INVOICE_DISABLED)) { $arrayresult['searchintosupplierinvoice'] = array('position'=>120, 'img'=>'object_supplier_invoice', 'label'=>$langs->trans("SearchIntoSupplierInvoices", $search_boxvalue), 'text'=>img_picto('', 'object_supplier_invoice', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoSupplierInvoices", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/fourn/facture/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } @@ -129,7 +129,7 @@ if (isModEnabled('facture') && empty($conf->global->MAIN_SEARCHFORM_CUSTOMER_INV } // Vendor payments -if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire) || (!empty($conf->supplier_invoice->enabled) && $user->rights->supplier_invoice->lire)) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_INVOICE_DISABLED)) { +if (((isModEnabled('fournisseur') && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight('fournisseur', 'facture', 'lire')) || (isModEnabled('supplier_invoice') && $user->hasRight('supplier_invoice', 'lire'))) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_INVOICE_DISABLED)) { $arrayresult['searchintovendorpayments'] = array( 'position'=>175, 'img'=>'object_payment', @@ -139,7 +139,7 @@ if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_S } // Miscellaneous payments -if (isModEnabled('banque') && empty($conf->global->MAIN_SEARCHFORM_MISC_PAYMENTS_DISABLED) && $user->rights->banque->lire) { +if (isModEnabled('banque') && empty($conf->global->MAIN_SEARCHFORM_MISC_PAYMENTS_DISABLED) && $user->hasRight('banque', 'lire')) { $arrayresult['searchintomiscpayments'] = array( 'position'=>180, 'img'=>'object_payment', @@ -148,24 +148,24 @@ if (isModEnabled('banque') && empty($conf->global->MAIN_SEARCHFORM_MISC_PAYMENTS 'url'=>DOL_URL_ROOT.'/compta/bank/various_payment/list.php?leftmenu=tax_various'.($search_boxvalue ? '&sall='.urlencode($search_boxvalue) : '')); } -if (isModEnabled('contrat') && empty($conf->global->MAIN_SEARCHFORM_CONTRACT_DISABLED) && $user->rights->contrat->lire) { +if (isModEnabled('contrat') && empty($conf->global->MAIN_SEARCHFORM_CONTRACT_DISABLED) && $user->hasRight('contrat', 'lire')) { $arrayresult['searchintocontract'] = array('position'=>130, 'img'=>'object_contract', 'label'=>$langs->trans("SearchIntoContracts", $search_boxvalue), 'text'=>img_picto('', 'object_contract', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoContracts", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/contrat/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (isModEnabled('ficheinter') && empty($conf->global->MAIN_SEARCHFORM_FICHINTER_DISABLED) && $user->rights->ficheinter->lire) { +if (isModEnabled('ficheinter') && empty($conf->global->MAIN_SEARCHFORM_FICHINTER_DISABLED) && $user->hasRight('ficheinter', 'lire')) { $arrayresult['searchintointervention'] = array('position'=>140, 'img'=>'object_intervention', 'label'=>$langs->trans("SearchIntoInterventions", $search_boxvalue), 'text'=>img_picto('', 'object_intervention', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoInterventions", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/fichinter/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (isModEnabled('ticket') && empty($conf->global->MAIN_SEARCHFORM_TICKET_DISABLED) && $user->rights->ticket->read) { +if (isModEnabled('ticket') && empty($conf->global->MAIN_SEARCHFORM_TICKET_DISABLED) && $user->hasRight('ticket', 'read')) { $arrayresult['searchintotickets'] = array('position'=>145, 'img'=>'object_ticket', 'label'=>$langs->trans("SearchIntoTickets", $search_boxvalue), 'text'=>img_picto('', 'object_ticket', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoTickets", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/ticket/list.php?mainmenu=ticket'.($search_boxvalue ? '&sall='.urlencode($search_boxvalue) : '')); } // HR -if (isModEnabled('user') && empty($conf->global->MAIN_SEARCHFORM_USER_DISABLED) && $user->rights->user->user->lire) { +if (isModEnabled('user') && empty($conf->global->MAIN_SEARCHFORM_USER_DISABLED) && $user->hasRight('user', 'user', 'lire')) { $arrayresult['searchintouser'] = array('position'=>200, 'shortcut'=>'U', 'img'=>'object_user', 'label'=>$langs->trans("SearchIntoUsers", $search_boxvalue), 'text'=>img_picto('', 'object_user', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoUsers", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/user/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (isModEnabled('expensereport') && empty($conf->global->MAIN_SEARCHFORM_EXPENSEREPORT_DISABLED) && $user->rights->expensereport->lire) { +if (isModEnabled('expensereport') && empty($conf->global->MAIN_SEARCHFORM_EXPENSEREPORT_DISABLED) && $user->hasRight('expensereport', 'lire')) { $arrayresult['searchintoexpensereport'] = array('position'=>210, 'img'=>'object_trip', 'label'=>$langs->trans("SearchIntoExpenseReports", $search_boxvalue), 'text'=>img_picto('', 'object_trip', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoExpenseReports", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/expensereport/list.php?mainmenu=hrm'.($search_boxvalue ? '&sall='.urlencode($search_boxvalue) : '')); } -if (isModEnabled('holiday') && empty($conf->global->MAIN_SEARCHFORM_HOLIDAY_DISABLED) && $user->rights->holiday->read) { +if (isModEnabled('holiday') && empty($conf->global->MAIN_SEARCHFORM_HOLIDAY_DISABLED) && $user->hasRight('holiday', 'read')) { $arrayresult['searchintoleaves'] = array('position'=>220, 'img'=>'object_holiday', 'label'=>$langs->trans("SearchIntoLeaves", $search_boxvalue), 'text'=>img_picto('', 'object_holiday', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoLeaves", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/holiday/list.php?mainmenu=hrm'.($search_boxvalue ? '&sall='.urlencode($search_boxvalue) : '')); } From 5d2d0384f819af7d5755d6e4d7deeff1048e274b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 17:05:02 +0200 Subject: [PATCH 125/205] Debug v16 --- htdocs/admin/dict.php | 46 ++++++++++--------- .../modules/modEventOrganization.class.php | 2 +- .../conferenceorbooth_card.php | 3 ++ .../conferenceorboothattendee_list.php | 2 +- ...ventorganization_conferenceorbooth.lib.php | 12 ++--- htdocs/projet/card.php | 21 ++++++--- htdocs/public/project/suggestbooth.php | 6 +-- htdocs/public/project/suggestconference.php | 6 +-- 8 files changed, 56 insertions(+), 42 deletions(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 38fbfec8c87..dd29ee1cde3 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -622,34 +622,33 @@ $sourceList = array(); if ($id == 11) { $elementList = array( '' => '', - 'societe' => $langs->trans('ThirdParty'), + 'agenda' => img_picto('', 'action', 'class="pictofixedwidth"').$langs->trans('Agenda'), + 'dolresource' => img_picto('', 'resource', 'class="pictofixedwidth"').$langs->trans('Resource'), + 'societe' => img_picto('', 'company', 'class="pictofixedwidth"').$langs->trans('ThirdParty'), // 'proposal' => $langs->trans('Proposal'), // 'order' => $langs->trans('Order'), // 'invoice' => $langs->trans('Bill'), - 'supplier_proposal' => $langs->trans('SupplierProposal'), - 'order_supplier' => $langs->trans('SupplierOrder'), - 'invoice_supplier' => $langs->trans('SupplierBill'), // 'intervention' => $langs->trans('InterventionCard'), // 'contract' => $langs->trans('Contract'), - 'project' => $langs->trans('Project'), - 'project_task' => $langs->trans('Task'), - 'ticket' => $langs->trans('Ticket'), - 'agenda' => $langs->trans('Agenda'), - 'dolresource' => $langs->trans('Resource'), - // old deprecated - 'propal' => $langs->trans('Proposal'), - 'commande' => $langs->trans('Order'), - 'facture' => $langs->trans('Bill'), - 'fichinter' => $langs->trans('InterventionCard'), - 'contrat' => $langs->trans('Contract'), + 'project' => img_picto('', 'project', 'class="pictofixedwidth"').$langs->trans('Project'), + 'project_task' => img_picto('', 'projecttask', 'class="pictofixedwidth"').$langs->trans('Task'), + 'propal' => img_picto('', 'propal', 'class="pictofixedwidth"').$langs->trans('Proposal'), + 'commande' => img_picto('', 'order', 'class="pictofixedwidth"').$langs->trans('Order'), + 'facture' => img_picto('', 'bill', 'class="pictofixedwidth"').$langs->trans('Bill'), + 'fichinter' => img_picto('', 'intervention', 'class="pictofixedwidth"').$langs->trans('InterventionCard'), + 'contrat' => img_picto('', 'contract', 'class="pictofixedwidth"').$langs->trans('Contract'), + 'ticket' => img_picto('', 'ticket', 'class="pictofixedwidth"').$langs->trans('Ticket'), + 'supplier_proposal' => img_picto('', 'supplier_proposal', 'class="pictofixedwidth"').$langs->trans('SupplierProposal'), + 'order_supplier' => img_picto('', 'supplier_order', 'class="pictofixedwidth"').$langs->trans('SupplierOrder'), + 'invoice_supplier' => img_picto('', 'supplier_invoice', 'class="pictofixedwidth"').$langs->trans('SupplierBill'), ); - if (!empty($conf->global->MAIN_SUPPORT_SHARED_CONTACT_BETWEEN_THIRDPARTIES)) { - $elementList["societe"] = $langs->trans('ThirdParty'); + if (!empty($conf->global->MAIN_FEATURES_LEVEL) && $conf->global->MAIN_FEATURES_LEVEL >= 2) { + $elementList['conferenceorbooth'] = img_picto('', 'eventorganization', 'class="pictofixedwidth"').$langs->trans('ConferenceOrBooth'); } complete_elementList_with_modules($elementList); - asort($elementList); + //asort($elementList); $sourceList = array( 'internal' => $langs->trans('Internal'), 'external' => $langs->trans('External') @@ -1202,7 +1201,6 @@ if (GETPOST('from')) { if ($action == 'delete') { print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'rowid='.urlencode($rowid).'&code='.urlencode($code).$paramwithsearch, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete', '', 0, 1); } -//var_dump($elementList); /* @@ -1960,7 +1958,7 @@ if ($id > 0) { $valuetoshow = price($valuetoshow); } if ($value == 'private') { - $valuetoshow = yn($elementList[$valuetoshow]); + $valuetoshow = yn($valuetoshow); } elseif ($value == 'libelle_facture') { $langs->load("bills"); $key = $langs->trans("PaymentCondition".strtoupper($obj->code)); @@ -2376,8 +2374,14 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'lang'); print ''; } elseif (in_array($value, array('element', 'source'))) { // Example: the type and source of the element (for contact types) + $tmparray = array(); + if ($value == 'element') { + $tmparray = $elementList; + } else { + $tmparray = $sourceList; + } print ''; } elseif (in_array($value, array('public', 'use_default'))) { // Fields 0/1 with a combo select Yes/No diff --git a/htdocs/core/modules/modEventOrganization.class.php b/htdocs/core/modules/modEventOrganization.class.php index 5dd212b355d..a7a6c048a4d 100644 --- a/htdocs/core/modules/modEventOrganization.class.php +++ b/htdocs/core/modules/modEventOrganization.class.php @@ -258,7 +258,7 @@ class modEventOrganization extends DolibarrModules 'fk_menu'=>'fk_mainmenu=project,fk_leftmenu=eventorganization', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'type'=>'left', // This is a Left menu entry 'titre'=>'New', - 'url'=>'/projet/card.php?leftmenu=projects&action=create&usage_organize_event=1', + 'url'=>'/projet/card.php?leftmenu=projects&action=create&usage_organize_event=1&usage_opportunity=0', 'langs'=>'eventorganization@eventorganization', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>1000+$r, 'enabled'=>'$conf->eventorganization->enabled', // Define condition to show or hide menu entry. Use '$conf->eventorganization->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. diff --git a/htdocs/eventorganization/conferenceorbooth_card.php b/htdocs/eventorganization/conferenceorbooth_card.php index 0d5991bb0ac..ac64a16602f 100644 --- a/htdocs/eventorganization/conferenceorbooth_card.php +++ b/htdocs/eventorganization/conferenceorbooth_card.php @@ -185,7 +185,9 @@ if (!empty($withproject)) { // Tabs for project $tab = 'eventorganisation'; $withProjectUrl = "&withproject=1"; + $head = project_prepare_head($projectstatic); + print dol_get_fiche_head($head, $tab, $langs->trans("Project"), -1, ($projectstatic->public ? 'projectpub' : 'project'), 0, '', ''); $param = ($mode == 'mine' ? '&mode=mine' : ''); @@ -468,6 +470,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $res = $object->fetch_optionals(); $head = conferenceorboothPrepareHead($object, $withproject); + print dol_get_fiche_head($head, 'card', $langs->trans("ConferenceOrBooth"), -1, $object->picto); $formconfirm = ''; diff --git a/htdocs/eventorganization/conferenceorboothattendee_list.php b/htdocs/eventorganization/conferenceorboothattendee_list.php index 972e546255f..c1626f7bbf3 100644 --- a/htdocs/eventorganization/conferenceorboothattendee_list.php +++ b/htdocs/eventorganization/conferenceorboothattendee_list.php @@ -947,7 +947,7 @@ if ($num == 0) { $colspan++; } } - print ''; + print ''; } diff --git a/htdocs/eventorganization/lib/eventorganization_conferenceorbooth.lib.php b/htdocs/eventorganization/lib/eventorganization_conferenceorbooth.lib.php index 6a76a14a38c..8d0f442e900 100644 --- a/htdocs/eventorganization/lib/eventorganization_conferenceorbooth.lib.php +++ b/htdocs/eventorganization/lib/eventorganization_conferenceorbooth.lib.php @@ -47,12 +47,12 @@ function conferenceorboothPrepareHead($object, $with_project = 0) $head[$h][2] = 'card'; $h++; - /* - $head[$h][0] = DOL_URL_ROOT.'/eventorganization/conferenceorbooth_contact.php?id='.$object->id.$withProjectUrl; - $head[$h][1] = $langs->trans("ContactsAddresses"); - $head[$h][2] = 'contact'; - $h++; - */ + if (!empty($conf->global->MAIN_FEATURES_LEVEL) && $conf->global->MAIN_FEATURES_LEVEL >= 2) { + $head[$h][0] = DOL_URL_ROOT.'/eventorganization/conferenceorbooth_contact.php?id='.$object->id.$withProjectUrl; + $head[$h][1] = $langs->trans("ContactsAddresses"); + $head[$h][2] = 'contact'; + $h++; + } /* $head[$h][0] = DOL_URL_ROOT.'/eventorganization/conferenceorboothattendee_list.php?conforboothid='.$object->id.$withProjectUrl; diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 1e9fd292c69..aabf14e8655 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -563,7 +563,7 @@ if ($action == 'create' && $user->rights->projet->creer) { print ''; print ''; } // Type of event -print ''."\n"; -print ''; +print ''."\n"; +print ''; // Label print ''."\n"; print ''."\n"; diff --git a/htdocs/public/project/suggestconference.php b/htdocs/public/project/suggestconference.php index ca34a05253d..05cc8e61a82 100644 --- a/htdocs/public/project/suggestconference.php +++ b/htdocs/public/project/suggestconference.php @@ -102,7 +102,7 @@ $extrafields = new ExtraFields($db); $user->loadDefaultValues(); $cactioncomm = new CActionComm($db); -$arrayofeventtype = $cactioncomm->liste_array('', 'id', '', 0, "module='conference@eventorganization'"); +$arrayofconfboothtype = $cactioncomm->liste_array('', 'id', '', 0, "module='conference@eventorganization'"); // Security check if (empty($conf->eventorganization->enabled)) { @@ -546,8 +546,8 @@ if (empty($conf->global->SOCIETE_DISABLE_STATE)) { print ''; } // Type of event -print ''."\n"; -print ''; +print ''."\n"; +print ''; // Label print ''."\n"; print ''."\n"; From 77389b3855d4faf579b87a9c10312651bb837f4e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 17:35:31 +0200 Subject: [PATCH 126/205] Fix trans --- htdocs/core/class/translate.class.php | 5 ++++- htdocs/langs/am_ET/errors.lang | 2 +- htdocs/langs/ar_DZ/errors.lang | 2 +- htdocs/langs/ar_JO/errors.lang | 2 +- htdocs/langs/ar_SA/errors.lang | 2 +- htdocs/langs/ar_SY/errors.lang | 2 +- htdocs/langs/az_AZ/errors.lang | 2 +- htdocs/langs/bg_BG/errors.lang | 2 +- htdocs/langs/bn_BD/errors.lang | 2 +- htdocs/langs/bn_IN/errors.lang | 2 +- htdocs/langs/bs_BA/errors.lang | 2 +- htdocs/langs/ca_ES/errors.lang | 2 +- htdocs/langs/cs_CZ/errors.lang | 2 +- htdocs/langs/cy_GB/errors.lang | 2 +- htdocs/langs/da_DK/errors.lang | 2 +- htdocs/langs/de_DE/errors.lang | 2 +- htdocs/langs/el_GR/errors.lang | 2 +- htdocs/langs/en_US/errors.lang | 2 +- htdocs/langs/es_ES/errors.lang | 2 +- htdocs/langs/et_EE/errors.lang | 2 +- htdocs/langs/eu_ES/errors.lang | 2 +- htdocs/langs/fa_IR/errors.lang | 2 +- htdocs/langs/fi_FI/errors.lang | 2 +- htdocs/langs/fr_FR/errors.lang | 2 +- htdocs/langs/gl_ES/errors.lang | 2 +- htdocs/langs/he_IL/errors.lang | 2 +- htdocs/langs/hi_IN/errors.lang | 2 +- htdocs/langs/hr_HR/errors.lang | 2 +- htdocs/langs/hu_HU/errors.lang | 2 +- htdocs/langs/id_ID/errors.lang | 2 +- htdocs/langs/is_IS/errors.lang | 2 +- htdocs/langs/it_IT/errors.lang | 2 +- htdocs/langs/ja_JP/errors.lang | 2 +- htdocs/langs/ka_GE/errors.lang | 2 +- htdocs/langs/kk_KZ/errors.lang | 2 +- htdocs/langs/km_KH/errors.lang | 2 +- htdocs/langs/kn_IN/errors.lang | 2 +- htdocs/langs/ko_KR/errors.lang | 2 +- htdocs/langs/lo_LA/errors.lang | 2 +- htdocs/langs/lt_LT/errors.lang | 2 +- htdocs/langs/lv_LV/errors.lang | 2 +- htdocs/langs/mk_MK/errors.lang | 2 +- htdocs/langs/mn_MN/errors.lang | 2 +- htdocs/langs/ms_MY/errors.lang | 2 +- htdocs/langs/my_MM/errors.lang | 2 +- htdocs/langs/nb_NO/errors.lang | 2 +- htdocs/langs/ne_NP/errors.lang | 2 +- htdocs/langs/nl_NL/errors.lang | 2 +- htdocs/langs/pl_PL/errors.lang | 2 +- htdocs/langs/pt_PT/errors.lang | 2 +- htdocs/langs/ro_RO/errors.lang | 2 +- htdocs/langs/ru_RU/errors.lang | 2 +- htdocs/langs/sk_SK/errors.lang | 2 +- htdocs/langs/sl_SI/errors.lang | 2 +- htdocs/langs/sq_AL/errors.lang | 2 +- htdocs/langs/sr_RS/errors.lang | 2 +- htdocs/langs/sv_SE/errors.lang | 2 +- htdocs/langs/sw_SW/errors.lang | 2 +- htdocs/langs/ta_IN/errors.lang | 2 +- htdocs/langs/tg_TJ/errors.lang | 2 +- htdocs/langs/th_TH/errors.lang | 2 +- htdocs/langs/tr_TR/errors.lang | 2 +- htdocs/langs/uk_UA/errors.lang | 2 +- htdocs/langs/ur_PK/errors.lang | 2 +- htdocs/langs/uz_UZ/errors.lang | 2 +- htdocs/langs/vi_VN/errors.lang | 2 +- htdocs/langs/zh_CN/errors.lang | 2 +- htdocs/langs/zh_HK/errors.lang | 2 +- htdocs/langs/zh_TW/errors.lang | 2 +- test/phpunit/LangTest.php | 4 ++++ 70 files changed, 76 insertions(+), 69 deletions(-) diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index c11f94fa047..255cdb2fb67 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -637,7 +637,10 @@ class Translate ); if (strpos($key, 'Format') !== 0) { - $str = sprintf($str, $param1, $param2, $param3, $param4); // Replace %s and %d except for FormatXXX strings. + try { + $str = sprintf($str, $param1, $param2, $param3, $param4); // Replace %s and %d except for FormatXXX strings. + } catch (Exception $e) { + } } // Crypt string into HTML diff --git a/htdocs/langs/am_ET/errors.lang b/htdocs/langs/am_ET/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/am_ET/errors.lang +++ b/htdocs/langs/am_ET/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ar_DZ/errors.lang b/htdocs/langs/ar_DZ/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/ar_DZ/errors.lang +++ b/htdocs/langs/ar_DZ/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ar_JO/errors.lang b/htdocs/langs/ar_JO/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/ar_JO/errors.lang +++ b/htdocs/langs/ar_JO/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ar_SA/errors.lang b/htdocs/langs/ar_SA/errors.lang index 0b94eabbb83..436921eaaef 100644 --- a/htdocs/langs/ar_SA/errors.lang +++ b/htdocs/langs/ar_SA/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ar_SY/errors.lang b/htdocs/langs/ar_SY/errors.lang index 0bac7cf07c8..8097d3a5b6f 100644 --- a/htdocs/langs/ar_SY/errors.lang +++ b/htdocs/langs/ar_SY/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/az_AZ/errors.lang b/htdocs/langs/az_AZ/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/az_AZ/errors.lang +++ b/htdocs/langs/az_AZ/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/bg_BG/errors.lang b/htdocs/langs/bg_BG/errors.lang index ceb6c75ae21..f254274c96d 100644 --- a/htdocs/langs/bg_BG/errors.lang +++ b/htdocs/langs/bg_BG/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/bn_BD/errors.lang b/htdocs/langs/bn_BD/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/bn_BD/errors.lang +++ b/htdocs/langs/bn_BD/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/bn_IN/errors.lang b/htdocs/langs/bn_IN/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/bn_IN/errors.lang +++ b/htdocs/langs/bn_IN/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/bs_BA/errors.lang b/htdocs/langs/bs_BA/errors.lang index 864a09e3e63..25fa336f994 100644 --- a/htdocs/langs/bs_BA/errors.lang +++ b/htdocs/langs/bs_BA/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ca_ES/errors.lang b/htdocs/langs/ca_ES/errors.lang index 26ec96567de..1cdc1133512 100644 --- a/htdocs/langs/ca_ES/errors.lang +++ b/htdocs/langs/ca_ES/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Primer heu de configurar el vostre pla ErrorFailedToFindEmailTemplate=No s'ha pogut trobar la plantilla amb el nom de codi %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Durada no definida al servei. No hi ha manera de calcular el preu per hora. ErrorActionCommPropertyUserowneridNotDefined=El propietari de l'usuari és obligatori -ErrorActionCommBadType=El tipus d'esdeveniment seleccionat (identificador: %n, codi: %s) no existeix al diccionari del tipus d'esdeveniment +ErrorActionCommBadType=El tipus d'esdeveniment seleccionat (identificador: %s, codi: %s) no existeix al diccionari del tipus d'esdeveniment CheckVersionFail=Error de comprovació de versió ErrorWrongFileName=El nom del fitxer no pot contenir __COSA__ ErrorNotInDictionaryPaymentConditions=No es troba al Diccionari de condicions de pagament, modifiqueu-lo. diff --git a/htdocs/langs/cs_CZ/errors.lang b/htdocs/langs/cs_CZ/errors.lang index e530b0dbba3..15fdd697542 100644 --- a/htdocs/langs/cs_CZ/errors.lang +++ b/htdocs/langs/cs_CZ/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/cy_GB/errors.lang b/htdocs/langs/cy_GB/errors.lang index 01244d8d8eb..67831088584 100644 --- a/htdocs/langs/cy_GB/errors.lang +++ b/htdocs/langs/cy_GB/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Yn gyntaf rhaid i chi osod eich siart c ErrorFailedToFindEmailTemplate=Wedi methu dod o hyd i dempled gydag enw cod %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Hyd heb ei ddiffinio ar y gwasanaeth. Dim ffordd i gyfrifo'r pris fesul awr. ErrorActionCommPropertyUserowneridNotDefined=Mae angen perchennog y defnyddiwr -ErrorActionCommBadType=Nid yw'r math o ddigwyddiad a ddewiswyd (id: %n, cod: %s) yn bodoli mewn geiriadur Math o Ddigwyddiad +ErrorActionCommBadType=Nid yw'r math o ddigwyddiad a ddewiswyd (id: %s, cod: %s) yn bodoli mewn geiriadur Math o Ddigwyddiad CheckVersionFail=Fersiwn gwirio yn methu ErrorWrongFileName=Ni all enw'r ffeil fod â __SOMETHING__ ynddi ErrorNotInDictionaryPaymentConditions=Ddim yn y Geiriadur Telerau Talu, addaswch. diff --git a/htdocs/langs/da_DK/errors.lang b/htdocs/langs/da_DK/errors.lang index f290ed2774a..eb45404ac14 100644 --- a/htdocs/langs/da_DK/errors.lang +++ b/htdocs/langs/da_DK/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Du skal først konfigurere din kontopla ErrorFailedToFindEmailTemplate=Kunne ikke finde skabelon med kodenavn %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Varighed er ikke defineret i tjenesten. Ingen måde at beregne timeprisen på. ErrorActionCommPropertyUserowneridNotDefined=Brugerens ejer kræves -ErrorActionCommBadType=Den valgte hændelsestype (id: %n, kode: %s) findes ikke i begivenhedstypeordbogen +ErrorActionCommBadType=Den valgte hændelsestype (id: %s, kode: %s) findes ikke i begivenhedstypeordbogen CheckVersionFail=Versionskontrol mislykkedes ErrorWrongFileName=Filens navn kan ikke indeholde __SOMETHING__ ErrorNotInDictionaryPaymentConditions=Ikke i ordbogen om betalingsbetingelser, bedes du ændre. diff --git a/htdocs/langs/de_DE/errors.lang b/htdocs/langs/de_DE/errors.lang index f0dcb3381c3..b871ef62d28 100644 --- a/htdocs/langs/de_DE/errors.lang +++ b/htdocs/langs/de_DE/errors.lang @@ -271,7 +271,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Sie müssen zuerst Ihren Kontenplan ein ErrorFailedToFindEmailTemplate=Vorlage mit Codename %s konnte nicht gefunden werden ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Die Dauer für die Leistung ist nicht definiert. Es besteht keine Möglichkeit, den Stundenpreis zu berechnen. ErrorActionCommPropertyUserowneridNotDefined=Der Besitzer des Benutzers ist erforderlich -ErrorActionCommBadType=Der ausgewählte Ereignistyp (ID: %n, Code: %s) ist im Wörterbuch für den Ereignistyp nicht vorhanden +ErrorActionCommBadType=Der ausgewählte Ereignistyp (ID: %s, Code: %s) ist im Wörterbuch für den Ereignistyp nicht vorhanden CheckVersionFail=Versionsprüfung fehlgeschlagen ErrorWrongFileName=Der Dateiname darf nicht __SOMETHING__ enthalten ErrorNotInDictionaryPaymentConditions=Nicht im Dictionary der Zahlungsbedingungen, bitte ändern. diff --git a/htdocs/langs/el_GR/errors.lang b/htdocs/langs/el_GR/errors.lang index f30e49f7fe7..15d6c44b1c8 100644 --- a/htdocs/langs/el_GR/errors.lang +++ b/htdocs/langs/el_GR/errors.lang @@ -271,7 +271,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Πρέπει πρώτα να ρυθμί ErrorFailedToFindEmailTemplate=Αδυναμία εύρεσης προτύπου με κωδικό όνομα %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Η διάρκεια δεν έχει οριστεί στην υπηρεσία. Δεν υπάρχει τρόπος υπολογισμού της ωριαίας τιμής. ErrorActionCommPropertyUserowneridNotDefined=Απαιτείται το owner id του χρήστη -ErrorActionCommBadType=Ο επιλεγμένος τύπος συμβάντος (αναγνωριστικό: %n, κωδικός: %s) δεν υπάρχει στο λεξικό Τύπου συμβάντος +ErrorActionCommBadType=Ο επιλεγμένος τύπος συμβάντος (αναγνωριστικό: %s, κωδικός: %s) δεν υπάρχει στο λεξικό Τύπου συμβάντος CheckVersionFail=Αποτυχία ελέγχου έκδοσης ErrorWrongFileName=Το όνομα του αρχείου δεν μπορεί να έχει __ΚΑΤΙ__ σε αυτό ErrorNotInDictionaryPaymentConditions=Δεν υπάρχει στο Λεξικό Όρων Πληρωμής, παρακαλώ τροποποιήστε. diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 7e29572c9f5..9d38eab591e 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -271,7 +271,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/es_ES/errors.lang b/htdocs/langs/es_ES/errors.lang index 1c8597c2b51..23f51ef871b 100644 --- a/htdocs/langs/es_ES/errors.lang +++ b/htdocs/langs/es_ES/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Primero debe configurar su plan de cuen ErrorFailedToFindEmailTemplate=No se pudo encontrar la plantilla con el nombre de código %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duración no definida en el servicio. No hay forma de calcular el precio por hora. ErrorActionCommPropertyUserowneridNotDefined=Se requiere el propietario del usuario -ErrorActionCommBadType=El tipo de evento seleccionado (id: %n, código: %s) no existe en el diccionario de tipo de evento +ErrorActionCommBadType=El tipo de evento seleccionado (id: %s, código: %s) no existe en el diccionario de tipo de evento CheckVersionFail=Error de verificación de versión ErrorWrongFileName=El nombre del archivo no puede contener __SOMETHING__ ErrorNotInDictionaryPaymentConditions=No está en el Diccionario de términos de pago, modifíquelo. diff --git a/htdocs/langs/et_EE/errors.lang b/htdocs/langs/et_EE/errors.lang index e6cb1458234..3e4e7b3638a 100644 --- a/htdocs/langs/et_EE/errors.lang +++ b/htdocs/langs/et_EE/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/eu_ES/errors.lang b/htdocs/langs/eu_ES/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/eu_ES/errors.lang +++ b/htdocs/langs/eu_ES/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/fa_IR/errors.lang b/htdocs/langs/fa_IR/errors.lang index 1231bb9e621..4cd240fef47 100644 --- a/htdocs/langs/fa_IR/errors.lang +++ b/htdocs/langs/fa_IR/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/fi_FI/errors.lang b/htdocs/langs/fi_FI/errors.lang index bbbace60e76..9a5148d92c3 100644 --- a/htdocs/langs/fi_FI/errors.lang +++ b/htdocs/langs/fi_FI/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/fr_FR/errors.lang b/htdocs/langs/fr_FR/errors.lang index 234dc56941c..fa0112fc021 100644 --- a/htdocs/langs/fr_FR/errors.lang +++ b/htdocs/langs/fr_FR/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Vous devez d’abord configurer votre p ErrorFailedToFindEmailTemplate=Aucun gabarit trouvé avec le code %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Durée non définie sur le service. Pas moyen de calculer le prix horaire. ErrorActionCommPropertyUserowneridNotDefined=Le propriétaire de l'utilisateur est requis -ErrorActionCommBadType=Le type d'événement sélectionné (id: %n, code: %s) n'existe pas dans le dictionnaire des types d'événement +ErrorActionCommBadType=Le type d'événement sélectionné (id: %s, code: %s) n'existe pas dans le dictionnaire des types d'événement CheckVersionFail=Échec de la vérification de version ErrorWrongFileName=Le nom du fichier ne peut pas contenir __SOMETHING__ ErrorNotInDictionaryPaymentConditions=Pas dans le dictionnaire des conditions de paiement, veuillez modifier. diff --git a/htdocs/langs/gl_ES/errors.lang b/htdocs/langs/gl_ES/errors.lang index eda9523d233..4042618fcf8 100644 --- a/htdocs/langs/gl_ES/errors.lang +++ b/htdocs/langs/gl_ES/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Primeiro debe configurar o seu plan de ErrorFailedToFindEmailTemplate=Fallo ao atopar o modelo co nome de código %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duración non definida no servizo. Non hai forma de calcular o prezo por hora. ErrorActionCommPropertyUserowneridNotDefined=É preciso o supervisor do usuario -ErrorActionCommBadType=O tipo de evento seleccionado (id: %n, código: %s) non existe no diccionario Tipo de Evento +ErrorActionCommBadType=O tipo de evento seleccionado (id: %s, código: %s) non existe no diccionario Tipo de Evento CheckVersionFail=Fallou a comprobación da versión ErrorWrongFileName=O nome do ficheiro non pode conte __SOMETHING__ nel ErrorNotInDictionaryPaymentConditions=Non está no Dicionario de Condicións de Pagamento. Modifíqueo. diff --git a/htdocs/langs/he_IL/errors.lang b/htdocs/langs/he_IL/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/he_IL/errors.lang +++ b/htdocs/langs/he_IL/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/hi_IN/errors.lang b/htdocs/langs/hi_IN/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/hi_IN/errors.lang +++ b/htdocs/langs/hi_IN/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/hr_HR/errors.lang b/htdocs/langs/hr_HR/errors.lang index 1d6bf9b2ee0..31f089cdee2 100644 --- a/htdocs/langs/hr_HR/errors.lang +++ b/htdocs/langs/hr_HR/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Nije uspjelo pronaći predložak s kodnim nazivom %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Trajanje nije definirano na usluzi. Nema načina da se izračuna satnica. ErrorActionCommPropertyUserowneridNotDefined=Potreban je vlasnik korisnika -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Provjera verzije nije uspjela ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/hu_HU/errors.lang b/htdocs/langs/hu_HU/errors.lang index 6e46cdadd26..f9cd488d322 100644 --- a/htdocs/langs/hu_HU/errors.lang +++ b/htdocs/langs/hu_HU/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Először be kell állítania a számla ErrorFailedToFindEmailTemplate=Nem sikerült megtalálni a %s kódnevű sablont ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=A szolgáltatás időtartama nincs meghatározva. Nincs mód az óraárak kiszámítására. ErrorActionCommPropertyUserowneridNotDefined=A felhasználó tulajdonosa kötelező -ErrorActionCommBadType=A kiválasztott eseménytípus (azonosító: %n, kód: %s) nem létezik az Eseménytípus szótárban +ErrorActionCommBadType=A kiválasztott eseménytípus (azonosító: %s, kód: %s) nem létezik az Eseménytípus szótárban CheckVersionFail=A verzióellenőrzés sikertelen ErrorWrongFileName=A fájl nevében nem lehet __SOMETHING__ ErrorNotInDictionaryPaymentConditions=Nem szerepel a Fizetési feltételek szótárban, kérjük módosítsa. diff --git a/htdocs/langs/id_ID/errors.lang b/htdocs/langs/id_ID/errors.lang index bbe8da704b3..869322fa9cc 100644 --- a/htdocs/langs/id_ID/errors.lang +++ b/htdocs/langs/id_ID/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Anda harus terlebih dahulu mengatur bag ErrorFailedToFindEmailTemplate=Gagal menemukan template dengan nama kode %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Durasi tidak ditentukan pada layanan. Tidak ada cara untuk menghitung harga per jam. ErrorActionCommPropertyUserowneridNotDefined=Pemilik pengguna diperlukan -ErrorActionCommBadType=Jenis peristiwa yang dipilih (id: %n, kode: %s) tidak ada di kamus Jenis Peristiwa +ErrorActionCommBadType=Jenis peristiwa yang dipilih (id: %s, kode: %s) tidak ada di kamus Jenis Peristiwa CheckVersionFail=Pemeriksaan versi gagal ErrorWrongFileName=Nama file tidak boleh memiliki __SOMETHING__ di dalamnya ErrorNotInDictionaryPaymentConditions=Tidak ada dalam Kamus Istilah Pembayaran, harap ubah. diff --git a/htdocs/langs/is_IS/errors.lang b/htdocs/langs/is_IS/errors.lang index a6d3ae56134..d8282e3e62a 100644 --- a/htdocs/langs/is_IS/errors.lang +++ b/htdocs/langs/is_IS/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/it_IT/errors.lang b/htdocs/langs/it_IT/errors.lang index f784773bb16..e7d8359baaf 100644 --- a/htdocs/langs/it_IT/errors.lang +++ b/htdocs/langs/it_IT/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Devi prima impostare il tuo piano dei c ErrorFailedToFindEmailTemplate=Impossibile trovare il modello con nome in codice %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Durata non definita in servizio. Non c'è modo di calcolare il prezzo orario. ErrorActionCommPropertyUserowneridNotDefined=Il proprietario dell'utente è obbligatorio -ErrorActionCommBadType=Il tipo di evento selezionato (id: %n, codice: %s) non esiste nel dizionario del tipo di evento +ErrorActionCommBadType=Il tipo di evento selezionato (id: %s, codice: %s) non esiste nel dizionario del tipo di evento CheckVersionFail=Controllo della versione fallito ErrorWrongFileName=Il nome del file non può contenere __SOMETHING__ ErrorNotInDictionaryPaymentConditions=Non nel dizionario dei termini di pagamento, modificare. diff --git a/htdocs/langs/ja_JP/errors.lang b/htdocs/langs/ja_JP/errors.lang index d415243148a..f2e201f1c53 100644 --- a/htdocs/langs/ja_JP/errors.lang +++ b/htdocs/langs/ja_JP/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=最初に勘定科目表を設定する ErrorFailedToFindEmailTemplate=コードネーム%sのテンプレートが見つからない ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=サービスで期間が定義されていない。時給計算する方法がない。 ErrorActionCommPropertyUserowneridNotDefined=ユーザの所有者が必要 -ErrorActionCommBadType=選択したイベント種別 (id: %n, code: %s) がイベント種別辞書に存在しない +ErrorActionCommBadType=選択したイベント種別 (id: %s, code: %s) がイベント種別辞書に存在しない CheckVersionFail=バージョンチェックに失敗する ErrorWrongFileName=ファイル名に__SOMETHING__を含めることはできない ErrorNotInDictionaryPaymentConditions=支払条件辞書にないので、変更すること。 diff --git a/htdocs/langs/ka_GE/errors.lang b/htdocs/langs/ka_GE/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/ka_GE/errors.lang +++ b/htdocs/langs/ka_GE/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/kk_KZ/errors.lang b/htdocs/langs/kk_KZ/errors.lang index e10bb476fff..6792201a546 100644 --- a/htdocs/langs/kk_KZ/errors.lang +++ b/htdocs/langs/kk_KZ/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Алдымен сіз өзіңізді ErrorFailedToFindEmailTemplate=%s коды бар үлгі табылмады ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Қызмет көрсету мерзімі анықталмаған. Сағаттық бағаны есептеуге болмайды. ErrorActionCommPropertyUserowneridNotDefined=Пайдаланушының иесі қажет -ErrorActionCommBadType=Таңдалған оқиға түрі (идентификатор: %n, код: %s) оқиға түрі сөздігінде жоқ +ErrorActionCommBadType=Таңдалған оқиға түрі (идентификатор: %s, код: %s) оқиға түрі сөздігінде жоқ CheckVersionFail=Нұсқаны тексеру сәтсіз аяқталды ErrorWrongFileName=Файл атауында __SOMETHING__ болмайды ErrorNotInDictionaryPaymentConditions=Төлем шарттары сөздігінде жоқ, өзгертіңіз. diff --git a/htdocs/langs/km_KH/errors.lang b/htdocs/langs/km_KH/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/km_KH/errors.lang +++ b/htdocs/langs/km_KH/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/kn_IN/errors.lang b/htdocs/langs/kn_IN/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/kn_IN/errors.lang +++ b/htdocs/langs/kn_IN/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ko_KR/errors.lang b/htdocs/langs/ko_KR/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/ko_KR/errors.lang +++ b/htdocs/langs/ko_KR/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/lo_LA/errors.lang b/htdocs/langs/lo_LA/errors.lang index be5f507a576..8390ff24a66 100644 --- a/htdocs/langs/lo_LA/errors.lang +++ b/htdocs/langs/lo_LA/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=ກ່ອນອື່ນmustົດທ ErrorFailedToFindEmailTemplate=ການຊອກຫາແມ່ແບບທີ່ມີລະຫັດຊື່ %s ລົ້ມເຫລວ ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=ບໍ່ໄດ້ ກຳ ນົດໄລຍະເວລາການບໍລິການ. ບໍ່ມີທາງທີ່ຈະຄິດໄລ່ລາຄາຊົ່ວໂມງ. ErrorActionCommPropertyUserowneridNotDefined=ເຈົ້າຂອງຜູ້ໃຊ້ແມ່ນຕ້ອງການ -ErrorActionCommBadType=ປະເພດເຫດການທີ່ເລືອກ (id: %n, ລະຫັດ: %s) ບໍ່ມີຢູ່ໃນວັດຈະນານຸກົມປະເພດເຫດການ +ErrorActionCommBadType=ປະເພດເຫດການທີ່ເລືອກ (id: %s, ລະຫັດ: %s) ບໍ່ມີຢູ່ໃນວັດຈະນານຸກົມປະເພດເຫດການ CheckVersionFail=ກວດສອບເວີຊັນບໍ່ ສຳ ເລັດ ErrorWrongFileName=ຊື່ຂອງໄຟລ cannot ບໍ່ສາມາດມີ __SOMETHING__ ໃນມັນໄດ້ ErrorNotInDictionaryPaymentConditions=ບໍ່ຢູ່ໃນວັດຈະນານຸກົມເງື່ອນໄຂການຈ່າຍເງິນ, ກະລຸນາແກ້ໄຂ. diff --git a/htdocs/langs/lt_LT/errors.lang b/htdocs/langs/lt_LT/errors.lang index 7155a7694df..cff79292d37 100644 --- a/htdocs/langs/lt_LT/errors.lang +++ b/htdocs/langs/lt_LT/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/lv_LV/errors.lang b/htdocs/langs/lv_LV/errors.lang index e07086a7373..7e63665c0b6 100644 --- a/htdocs/langs/lv_LV/errors.lang +++ b/htdocs/langs/lv_LV/errors.lang @@ -271,7 +271,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Vispirms jums ir jāiestata konta plān ErrorFailedToFindEmailTemplate=Neizdevās atrast veidni ar koda nosaukumu %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Ilgums pakalpojumā nav noteikts. Nav iespējams aprēķināt stundas cenu. ErrorActionCommPropertyUserowneridNotDefined=Nepieciešams lietotāja īpašnieks -ErrorActionCommBadType=Atlasītais notikuma veids (id: %n, kods: %s) nepastāv notikuma veida vārdnīcā +ErrorActionCommBadType=Atlasītais notikuma veids (id: %s, kods: %s) nepastāv notikuma veida vārdnīcā CheckVersionFail=Versijas pārbaude neizdevās ErrorWrongFileName=Faila nosaukumā nedrīkst būt __SOMETHING__ ErrorNotInDictionaryPaymentConditions=Nav Maksājumu nosacījumu vārdnīcā, lūdzu, modificējiet. diff --git a/htdocs/langs/mk_MK/errors.lang b/htdocs/langs/mk_MK/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/mk_MK/errors.lang +++ b/htdocs/langs/mk_MK/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/mn_MN/errors.lang b/htdocs/langs/mn_MN/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/mn_MN/errors.lang +++ b/htdocs/langs/mn_MN/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ms_MY/errors.lang b/htdocs/langs/ms_MY/errors.lang index 44ce0211742..ceef384ddb3 100644 --- a/htdocs/langs/ms_MY/errors.lang +++ b/htdocs/langs/ms_MY/errors.lang @@ -271,7 +271,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/my_MM/errors.lang b/htdocs/langs/my_MM/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/my_MM/errors.lang +++ b/htdocs/langs/my_MM/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/nb_NO/errors.lang b/htdocs/langs/nb_NO/errors.lang index e97723984b2..55e9d540fed 100644 --- a/htdocs/langs/nb_NO/errors.lang +++ b/htdocs/langs/nb_NO/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Du må først konfigurere kontoplanen d ErrorFailedToFindEmailTemplate=Kunne ikke finne mal med kodenavn %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Varighet ikke definert på tjenesten. Ingen måte å beregne timeprisen. ErrorActionCommPropertyUserowneridNotDefined=Brukerens eier kreves -ErrorActionCommBadType=Valgt hendelsestype (id: %n, kode: %s) finnes ikke i ordboken for hendelsestype +ErrorActionCommBadType=Valgt hendelsestype (id: %s, kode: %s) finnes ikke i ordboken for hendelsestype CheckVersionFail=Versjonskontroll mislyktes ErrorWrongFileName=Navnet på filen kan ikke inneholde __SOMETHING__ ErrorNotInDictionaryPaymentConditions=Ikke i ordboken for betalingsvilkår, vennligst endre. diff --git a/htdocs/langs/ne_NP/errors.lang b/htdocs/langs/ne_NP/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/ne_NP/errors.lang +++ b/htdocs/langs/ne_NP/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/nl_NL/errors.lang b/htdocs/langs/nl_NL/errors.lang index fe70a2010cb..ed4a55d1aab 100644 --- a/htdocs/langs/nl_NL/errors.lang +++ b/htdocs/langs/nl_NL/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=U moet eerst uw rekeningschema instelle ErrorFailedToFindEmailTemplate=Kan sjabloon met codenaam %s . niet vinden ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=De lengte is niet gedefinieerd in de dienst. We kunnen de uurkosten niet berekenen. ErrorActionCommPropertyUserowneridNotDefined=Eigenaar van gebruiker is vereist -ErrorActionCommBadType=Het geselecteerde gebeurtenistype (id: %n, code: %s) bestaat niet in het woordenboek voor gebeurtenistypes +ErrorActionCommBadType=Het geselecteerde gebeurtenistype (id: %s, code: %s) bestaat niet in het woordenboek voor gebeurtenistypes CheckVersionFail=Versiecontrole mislukt ErrorWrongFileName=De naam van het bestand mag niet __SOMETHING__ bevatten ErrorNotInDictionaryPaymentConditions=Niet bekend in de gedefinieerde betaalregelingen, graag wijzigen diff --git a/htdocs/langs/pl_PL/errors.lang b/htdocs/langs/pl_PL/errors.lang index 2022a84943f..fb75cc0a943 100644 --- a/htdocs/langs/pl_PL/errors.lang +++ b/htdocs/langs/pl_PL/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Najpierw musisz ustawić swój plan kon ErrorFailedToFindEmailTemplate=Nie udało się znaleźć szablonu o nazwie kodowej %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=Właściciel użytkownika jest wymagany -ErrorActionCommBadType=Wybrany typ zdarzenia (id: %n, kod: %s) nie istnieje w słowniku typów zdarzeń +ErrorActionCommBadType=Wybrany typ zdarzenia (id: %s, kod: %s) nie istnieje w słowniku typów zdarzeń CheckVersionFail=Sprawdzanie wersji nie powiodło się ErrorWrongFileName=Nazwa pliku nie może zawierać __COŚ__ ErrorNotInDictionaryPaymentConditions=Nie w Słowniku terminów płatności, zmień. diff --git a/htdocs/langs/pt_PT/errors.lang b/htdocs/langs/pt_PT/errors.lang index dc0eb4f58d5..2b0dda28541 100644 --- a/htdocs/langs/pt_PT/errors.lang +++ b/htdocs/langs/pt_PT/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ro_RO/errors.lang b/htdocs/langs/ro_RO/errors.lang index 7b55c5259c6..8df5d2b5e43 100644 --- a/htdocs/langs/ro_RO/errors.lang +++ b/htdocs/langs/ro_RO/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Trebuie să setezi mai întâi planul d ErrorFailedToFindEmailTemplate=Nu s-a găsit șablonul cu numele de cod %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Durata nu este definită pentru serviciu. Nicio modalitate de a calcula prețul pe oră. ErrorActionCommPropertyUserowneridNotDefined=Utilizatorul deţinător este obligatoriu -ErrorActionCommBadType=Tipul evenimentului selectat (id: %n, cod: %s) nu există în dicţionarul Tipuri evenimente +ErrorActionCommBadType=Tipul evenimentului selectat (id: %s, cod: %s) nu există în dicţionarul Tipuri evenimente CheckVersionFail=Verificarea versiunii a eşuat ErrorWrongFileName=Numele fișierului nu poate să conțină _SOMETHING_ în el ErrorNotInDictionaryPaymentConditions=Nu se află în dicționarul Condiții de plată, vă rugăm să modificați. diff --git a/htdocs/langs/ru_RU/errors.lang b/htdocs/langs/ru_RU/errors.lang index 088cae1a1b0..c40292244f2 100644 --- a/htdocs/langs/ru_RU/errors.lang +++ b/htdocs/langs/ru_RU/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Вы должны сначала нас ErrorFailedToFindEmailTemplate=Не удалось найти шаблон с кодовым названием %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Срок службы не определен. Невозможно рассчитать почасовую оплату. ErrorActionCommPropertyUserowneridNotDefined=Требуется владелец пользователя -ErrorActionCommBadType=Выбранный тип события (id: %n, код: %s) не существует в словаре типов событий +ErrorActionCommBadType=Выбранный тип события (id: %s, код: %s) не существует в словаре типов событий CheckVersionFail=Ошибка проверки версии ErrorWrongFileName=Имя файла не может содержать __SOMETHING__ ErrorNotInDictionaryPaymentConditions=Нет в Словаре условий оплаты, пожалуйста, измените. diff --git a/htdocs/langs/sk_SK/errors.lang b/htdocs/langs/sk_SK/errors.lang index cbb983f03f0..a3f364bae15 100644 --- a/htdocs/langs/sk_SK/errors.lang +++ b/htdocs/langs/sk_SK/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/sl_SI/errors.lang b/htdocs/langs/sl_SI/errors.lang index a27b6fceea6..7910fee7eaa 100644 --- a/htdocs/langs/sl_SI/errors.lang +++ b/htdocs/langs/sl_SI/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/sq_AL/errors.lang b/htdocs/langs/sq_AL/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/sq_AL/errors.lang +++ b/htdocs/langs/sq_AL/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/sr_RS/errors.lang b/htdocs/langs/sr_RS/errors.lang index ce3cbc6b148..30b2026e6ca 100644 --- a/htdocs/langs/sr_RS/errors.lang +++ b/htdocs/langs/sr_RS/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/sv_SE/errors.lang b/htdocs/langs/sv_SE/errors.lang index 6eac66b349a..e56c87c8212 100644 --- a/htdocs/langs/sv_SE/errors.lang +++ b/htdocs/langs/sv_SE/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Du måste först ställa in ditt kontop ErrorFailedToFindEmailTemplate=Det gick inte att hitta mall med kodnamn %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Varaktighet definieras inte i tjänsten. Inget sätt att beräkna timpriset. ErrorActionCommPropertyUserowneridNotDefined=Användarens ägare krävs -ErrorActionCommBadType=Vald händelsetyp (id: %n, kod: %s) finns inte i ordlistan för händelsetyp +ErrorActionCommBadType=Vald händelsetyp (id: %s, kod: %s) finns inte i ordlistan för händelsetyp CheckVersionFail=Versionskontroll misslyckades ErrorWrongFileName=Filens namn kan inte innehålla __SOMETHING__ ErrorNotInDictionaryPaymentConditions=Inte i ordningen för betalningsvillkor, ändra. diff --git a/htdocs/langs/sw_SW/errors.lang b/htdocs/langs/sw_SW/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/sw_SW/errors.lang +++ b/htdocs/langs/sw_SW/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ta_IN/errors.lang b/htdocs/langs/ta_IN/errors.lang index 04fa1d14975..d46aeff4ca1 100644 --- a/htdocs/langs/ta_IN/errors.lang +++ b/htdocs/langs/ta_IN/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=முதலில் உங்கள ErrorFailedToFindEmailTemplate=%s என்ற குறியீட்டுப் பெயருடன் டெம்ப்ளேட்டைக் கண்டறிய முடியவில்லை ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=சேவையில் காலம் வரையறுக்கப்படவில்லை. மணிநேர விலையை கணக்கிட வழி இல்லை. ErrorActionCommPropertyUserowneridNotDefined=பயனரின் உரிமையாளர் தேவை -ErrorActionCommBadType=தேர்ந்தெடுக்கப்பட்ட நிகழ்வு வகை (ஐடி: %n, குறியீடு: %s) நிகழ்வு வகை அகராதியில் இல்லை +ErrorActionCommBadType=தேர்ந்தெடுக்கப்பட்ட நிகழ்வு வகை (ஐடி: %s, குறியீடு: %s) நிகழ்வு வகை அகராதியில் இல்லை CheckVersionFail=பதிப்பு சரிபார்ப்பு தோல்வி ErrorWrongFileName=கோப்பின் பெயரில் __சம்திங்__ இருக்கக்கூடாது ErrorNotInDictionaryPaymentConditions=கட்டண விதிமுறைகள் அகராதியில் இல்லை, தயவுசெய்து மாற்றவும். diff --git a/htdocs/langs/tg_TJ/errors.lang b/htdocs/langs/tg_TJ/errors.lang index b861ec4b276..ec74135edae 100644 --- a/htdocs/langs/tg_TJ/errors.lang +++ b/htdocs/langs/tg_TJ/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Шумо аввал бояд ҷадва ErrorFailedToFindEmailTemplate=Шаблон бо номи рамзи %s ёфт нашуд ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Давомнокии хидмат муайян карда нашудааст. Ҳеҷ гуна ҳисоб кардани нархи соатбайъ. ErrorActionCommPropertyUserowneridNotDefined=Соҳиби корбар лозим аст -ErrorActionCommBadType=Навъи рӯйдоди интихобшуда (id: %n, рамз: %s) дар луғати навъи чорабиниҳо вуҷуд надорад +ErrorActionCommBadType=Навъи рӯйдоди интихобшуда (id: %s, рамз: %s) дар луғати навъи чорабиниҳо вуҷуд надорад CheckVersionFail=Санҷиши версия ноком шуд ErrorWrongFileName=Номи файл наметавонад дар он __SOMETHING__ дошта бошад ErrorNotInDictionaryPaymentConditions=Дар луғати шартҳои пардохт нест, лутфан тағир диҳед. diff --git a/htdocs/langs/th_TH/errors.lang b/htdocs/langs/th_TH/errors.lang index 43200416193..efeb030607d 100644 --- a/htdocs/langs/th_TH/errors.lang +++ b/htdocs/langs/th_TH/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/tr_TR/errors.lang b/htdocs/langs/tr_TR/errors.lang index 37622276db8..d3cd4ad4a71 100644 --- a/htdocs/langs/tr_TR/errors.lang +++ b/htdocs/langs/tr_TR/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/uk_UA/errors.lang b/htdocs/langs/uk_UA/errors.lang index 1f310d658aa..1fd1e371191 100644 --- a/htdocs/langs/uk_UA/errors.lang +++ b/htdocs/langs/uk_UA/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Спочатку потрібно на ErrorFailedToFindEmailTemplate=Не вдалося знайти шаблон із кодовою назвою %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Тривалість обслуговування не визначена. Неможливо розрахувати погодинну ціну. ErrorActionCommPropertyUserowneridNotDefined=Потрібен власник користувача -ErrorActionCommBadType=Вибраний тип події (id: %n, код: %s) не існує в словнику типів події +ErrorActionCommBadType=Вибраний тип події (id: %s, код: %s) не існує в словнику типів події CheckVersionFail=Помилка перевірки версії ErrorWrongFileName=У назві файлу не може бути __SOMETHING__ ErrorNotInDictionaryPaymentConditions=Немає в словнику умов оплати, будь ласка, змініть. diff --git a/htdocs/langs/ur_PK/errors.lang b/htdocs/langs/ur_PK/errors.lang index 905d70ab7fb..b6a2f5c9eb7 100644 --- a/htdocs/langs/ur_PK/errors.lang +++ b/htdocs/langs/ur_PK/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=آپ کو پہلے اپنے اکاؤن ErrorFailedToFindEmailTemplate=کوڈ نام %s کے ساتھ ٹیمپلیٹ تلاش کرنے میں ناکام ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=سروس پر مدت کی وضاحت نہیں کی گئی ہے۔ فی گھنٹہ قیمت کا حساب لگانے کا کوئی طریقہ نہیں ہے۔ ErrorActionCommPropertyUserowneridNotDefined=صارف کا مالک درکار ہے۔ -ErrorActionCommBadType=ایونٹ کی قسم کی منتخب کردہ (id: %n، کوڈ: %s) ایونٹ کی قسم ڈکشنری میں موجود نہیں ہے۔ +ErrorActionCommBadType=ایونٹ کی قسم کی منتخب کردہ (id: %s، کوڈ: %s) ایونٹ کی قسم ڈکشنری میں موجود نہیں ہے۔ CheckVersionFail=ورژن کی جانچ ناکام ErrorWrongFileName=فائل کے نام میں __SOMETHING__ نہیں ہو سکتا ErrorNotInDictionaryPaymentConditions=ادائیگی کی شرائط ڈکشنری میں نہیں ہے، براہ کرم ترمیم کریں۔ diff --git a/htdocs/langs/uz_UZ/errors.lang b/htdocs/langs/uz_UZ/errors.lang index e992dabb6b3..54c6345ef66 100644 --- a/htdocs/langs/uz_UZ/errors.lang +++ b/htdocs/langs/uz_UZ/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Avval hisob qaydnomangizni o'rnatishing ErrorFailedToFindEmailTemplate=%s kodli shablonni topib bo'lmadi ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Xizmat muddati aniqlanmagan. Bir soatlik narxni hisoblashning iloji yo'q. ErrorActionCommPropertyUserowneridNotDefined=Foydalanuvchi egasi talab qilinadi -ErrorActionCommBadType=Tanlangan voqea turi (id: %n, kod: %s) Voqealar turi lug'atida mavjud emas +ErrorActionCommBadType=Tanlangan voqea turi (id: %s, kod: %s) Voqealar turi lug'atida mavjud emas CheckVersionFail=Versiyani tekshirib bo'lmadi ErrorWrongFileName=Fayl nomida __SOMETHING__ bo'lishi mumkin emas ErrorNotInDictionaryPaymentConditions=To'lov shartlari lug'atida yo'q, iltimos o'zgartiring. diff --git a/htdocs/langs/vi_VN/errors.lang b/htdocs/langs/vi_VN/errors.lang index 1b8c6ca61b9..8707c21f67a 100644 --- a/htdocs/langs/vi_VN/errors.lang +++ b/htdocs/langs/vi_VN/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/zh_CN/errors.lang b/htdocs/langs/zh_CN/errors.lang index 1783be09f3a..53188bca81d 100644 --- a/htdocs/langs/zh_CN/errors.lang +++ b/htdocs/langs/zh_CN/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/zh_HK/errors.lang b/htdocs/langs/zh_HK/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/zh_HK/errors.lang +++ b/htdocs/langs/zh_HK/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/zh_TW/errors.lang b/htdocs/langs/zh_TW/errors.lang index 5afdeaa2b52..a1e28e2d98a 100644 --- a/htdocs/langs/zh_TW/errors.lang +++ b/htdocs/langs/zh_TW/errors.lang @@ -270,7 +270,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=您必須先設定會計項目表 ErrorFailedToFindEmailTemplate=無法找到代號為 %s 的模板 ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=未在服務中定義時間範圍.無法計算時薪. ErrorActionCommPropertyUserowneridNotDefined=需要用戶的擁有者 -ErrorActionCommBadType=選擇的事件類型(id:%n,代碼:%s)在事件類型分類中不存在 +ErrorActionCommBadType=選擇的事件類型(id:%s,代碼:%s)在事件類型分類中不存在 CheckVersionFail=版本檢查失敗 ErrorWrongFileName=檔案名稱中不可以有__SOMETHING__ ErrorNotInDictionaryPaymentConditions=不在支付條款類別中,請修改。 diff --git a/test/phpunit/LangTest.php b/test/phpunit/LangTest.php index c9c332b311e..7bd521c2a7a 100644 --- a/test/phpunit/LangTest.php +++ b/test/phpunit/LangTest.php @@ -226,6 +226,10 @@ class LangTest extends PHPUnit\Framework\TestCase $result=strpos($filecontent, '%'); // A special % char we don't want. We want the common one. //print __METHOD__." Result for checking we don't have bad percent char = ".$result."\n"; $this->assertTrue($result === false, 'Found a bad percent char % instead of % into file '.$code.'/'.$file); + + $result=preg_match('/%n/m', $filecontent); // A sequence of char we don't want + //print __METHOD__." Result for checking we don't have bad percent char = ".$result."\n"; + $this->assertTrue($result == 0, 'Found a sequence %n into the translation file '.$code.'/'.$file.'. We probably want %s'); } } From 629689b13f19badde29d7fe12b9b69d7532e812a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 18:06:49 +0200 Subject: [PATCH 127/205] Fix bad trans %n instead of %s --- htdocs/langs/am_ET/errors.lang | 2 +- htdocs/langs/ar_DZ/errors.lang | 2 +- htdocs/langs/ar_JO/errors.lang | 2 +- htdocs/langs/ar_SA/errors.lang | 2 +- htdocs/langs/az_AZ/errors.lang | 2 +- htdocs/langs/bg_BG/errors.lang | 2 +- htdocs/langs/bn_BD/errors.lang | 2 +- htdocs/langs/bn_IN/errors.lang | 2 +- htdocs/langs/bs_BA/errors.lang | 2 +- htdocs/langs/ca_ES/errors.lang | 2 +- htdocs/langs/cs_CZ/errors.lang | 2 +- htdocs/langs/da_DK/errors.lang | 2 +- htdocs/langs/de_DE/errors.lang | 2 +- htdocs/langs/el_GR/errors.lang | 2 +- htdocs/langs/en_US/errors.lang | 2 +- htdocs/langs/es_ES/errors.lang | 2 +- htdocs/langs/et_EE/errors.lang | 2 +- htdocs/langs/eu_ES/errors.lang | 2 +- htdocs/langs/fa_IR/errors.lang | 2 +- htdocs/langs/fi_FI/errors.lang | 2 +- htdocs/langs/fr_FR/errors.lang | 2 +- htdocs/langs/gl_ES/errors.lang | 2 +- htdocs/langs/he_IL/errors.lang | 2 +- htdocs/langs/hi_IN/errors.lang | 2 +- htdocs/langs/hr_HR/errors.lang | 2 +- htdocs/langs/hu_HU/errors.lang | 2 +- htdocs/langs/id_ID/errors.lang | 2 +- htdocs/langs/is_IS/errors.lang | 2 +- htdocs/langs/it_IT/errors.lang | 2 +- htdocs/langs/ja_JP/errors.lang | 2 +- htdocs/langs/ka_GE/errors.lang | 2 +- htdocs/langs/kk_KZ/errors.lang | 2 +- htdocs/langs/km_KH/errors.lang | 2 +- htdocs/langs/kn_IN/errors.lang | 2 +- htdocs/langs/ko_KR/errors.lang | 2 +- htdocs/langs/lo_LA/errors.lang | 2 +- htdocs/langs/lt_LT/errors.lang | 2 +- htdocs/langs/lv_LV/errors.lang | 2 +- htdocs/langs/mk_MK/errors.lang | 2 +- htdocs/langs/mn_MN/errors.lang | 2 +- htdocs/langs/my_MM/errors.lang | 2 +- htdocs/langs/nb_NO/errors.lang | 2 +- htdocs/langs/ne_NP/errors.lang | 2 +- htdocs/langs/nl_NL/errors.lang | 2 +- htdocs/langs/pl_PL/errors.lang | 2 +- htdocs/langs/pt_PT/errors.lang | 2 +- htdocs/langs/ro_RO/errors.lang | 2 +- htdocs/langs/ru_RU/errors.lang | 2 +- htdocs/langs/sk_SK/errors.lang | 2 +- htdocs/langs/sl_SI/errors.lang | 2 +- htdocs/langs/sq_AL/errors.lang | 2 +- htdocs/langs/sr_RS/errors.lang | 2 +- htdocs/langs/sv_SE/errors.lang | 2 +- htdocs/langs/sw_SW/errors.lang | 2 +- htdocs/langs/ta_IN/errors.lang | 2 +- htdocs/langs/tg_TJ/errors.lang | 2 +- htdocs/langs/th_TH/errors.lang | 2 +- htdocs/langs/tr_TR/errors.lang | 2 +- htdocs/langs/uk_UA/errors.lang | 2 +- htdocs/langs/ur_PK/errors.lang | 2 +- htdocs/langs/uz_UZ/errors.lang | 2 +- htdocs/langs/vi_VN/errors.lang | 2 +- htdocs/langs/zh_CN/errors.lang | 2 +- htdocs/langs/zh_HK/errors.lang | 2 +- htdocs/langs/zh_TW/errors.lang | 2 +- 65 files changed, 65 insertions(+), 65 deletions(-) diff --git a/htdocs/langs/am_ET/errors.lang b/htdocs/langs/am_ET/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/am_ET/errors.lang +++ b/htdocs/langs/am_ET/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ar_DZ/errors.lang b/htdocs/langs/ar_DZ/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/ar_DZ/errors.lang +++ b/htdocs/langs/ar_DZ/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ar_JO/errors.lang b/htdocs/langs/ar_JO/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/ar_JO/errors.lang +++ b/htdocs/langs/ar_JO/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ar_SA/errors.lang b/htdocs/langs/ar_SA/errors.lang index 0b94eabbb83..436921eaaef 100644 --- a/htdocs/langs/ar_SA/errors.lang +++ b/htdocs/langs/ar_SA/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/az_AZ/errors.lang b/htdocs/langs/az_AZ/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/az_AZ/errors.lang +++ b/htdocs/langs/az_AZ/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/bg_BG/errors.lang b/htdocs/langs/bg_BG/errors.lang index ceb6c75ae21..f254274c96d 100644 --- a/htdocs/langs/bg_BG/errors.lang +++ b/htdocs/langs/bg_BG/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/bn_BD/errors.lang b/htdocs/langs/bn_BD/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/bn_BD/errors.lang +++ b/htdocs/langs/bn_BD/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/bn_IN/errors.lang b/htdocs/langs/bn_IN/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/bn_IN/errors.lang +++ b/htdocs/langs/bn_IN/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/bs_BA/errors.lang b/htdocs/langs/bs_BA/errors.lang index 864a09e3e63..25fa336f994 100644 --- a/htdocs/langs/bs_BA/errors.lang +++ b/htdocs/langs/bs_BA/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ca_ES/errors.lang b/htdocs/langs/ca_ES/errors.lang index 9f038bdf256..402bb0c556d 100644 --- a/htdocs/langs/ca_ES/errors.lang +++ b/htdocs/langs/ca_ES/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Primer heu de configurar el vostre pla ErrorFailedToFindEmailTemplate=No s'ha pogut trobar la plantilla amb el nom de codi %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Durada no definida al servei. No hi ha manera de calcular el preu per hora. ErrorActionCommPropertyUserowneridNotDefined=El propietari de l'usuari és obligatori -ErrorActionCommBadType=El tipus d'esdeveniment seleccionat (identificador: %n, codi: %s) no existeix al diccionari del tipus d'esdeveniment +ErrorActionCommBadType=El tipus d'esdeveniment seleccionat (identificador: %s, codi: %s) no existeix al diccionari del tipus d'esdeveniment CheckVersionFail=Error de comprovació de versió ErrorWrongFileName=El nom del fitxer no pot contenir __COSA__ ErrorNotInDictionaryPaymentConditions=No es troba al Diccionari de condicions de pagament, modifiqueu-lo. diff --git a/htdocs/langs/cs_CZ/errors.lang b/htdocs/langs/cs_CZ/errors.lang index e530b0dbba3..15fdd697542 100644 --- a/htdocs/langs/cs_CZ/errors.lang +++ b/htdocs/langs/cs_CZ/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/da_DK/errors.lang b/htdocs/langs/da_DK/errors.lang index f447526798e..41301d32cc1 100644 --- a/htdocs/langs/da_DK/errors.lang +++ b/htdocs/langs/da_DK/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Du skal først konfigurere din kontopla ErrorFailedToFindEmailTemplate=Kunne ikke finde skabelon med kodenavn %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Varighed er ikke defineret i tjenesten. Ingen måde at beregne timeprisen på. ErrorActionCommPropertyUserowneridNotDefined=Brugerens ejer kræves -ErrorActionCommBadType=Den valgte hændelsestype (id: %n, kode: %s) findes ikke i begivenhedstypeordbogen +ErrorActionCommBadType=Den valgte hændelsestype (id: %s, kode: %s) findes ikke i begivenhedstypeordbogen CheckVersionFail=Versionskontrol mislykkedes ErrorWrongFileName=Filens navn kan ikke indeholde __SOMETHING__ ErrorNotInDictionaryPaymentConditions=Ikke i ordbogen om betalingsbetingelser, bedes du ændre. diff --git a/htdocs/langs/de_DE/errors.lang b/htdocs/langs/de_DE/errors.lang index 5b7db2999ca..b75f263a231 100644 --- a/htdocs/langs/de_DE/errors.lang +++ b/htdocs/langs/de_DE/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Sie müssen zuerst Ihren Kontenplan ein ErrorFailedToFindEmailTemplate=Vorlage mit Codename %s konnte nicht gefunden werden ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Die Dauer für den Service ist nicht definiert. Es besteht keine Möglichkeit, den Stundenpreis zu berechnen. ErrorActionCommPropertyUserowneridNotDefined=Der Besitzer des Benutzers ist erforderlich -ErrorActionCommBadType=Der ausgewählte Ereignistyp (ID: %n, Code: %s) ist im Wörterbuch für den Ereignistyp nicht vorhanden +ErrorActionCommBadType=Der ausgewählte Ereignistyp (ID: %s, Code: %s) ist im Wörterbuch für den Ereignistyp nicht vorhanden CheckVersionFail=Versionsprüfung fehlgeschlagen ErrorWrongFileName=Der Dateiname darf nicht __SOMETHING__ enthalten ErrorNotInDictionaryPaymentConditions=Nicht im Dictionary der Zahlungsbedingungen, bitte ändern. diff --git a/htdocs/langs/el_GR/errors.lang b/htdocs/langs/el_GR/errors.lang index 967c1b4090b..1bc41dfcd8a 100644 --- a/htdocs/langs/el_GR/errors.lang +++ b/htdocs/langs/el_GR/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 1a4250834b2..616a2441979 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -267,7 +267,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/es_ES/errors.lang b/htdocs/langs/es_ES/errors.lang index cba521d8f83..649e488cb87 100644 --- a/htdocs/langs/es_ES/errors.lang +++ b/htdocs/langs/es_ES/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Primero debe configurar su plan de cuen ErrorFailedToFindEmailTemplate=No se pudo encontrar la plantilla con el nombre de código %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duración no definida en el servicio. No hay forma de calcular el precio por hora. ErrorActionCommPropertyUserowneridNotDefined=Se requiere el propietario del usuario -ErrorActionCommBadType=El tipo de evento seleccionado (id: %n, código: %s) no existe en el diccionario de tipo de evento +ErrorActionCommBadType=El tipo de evento seleccionado (id: %s, código: %s) no existe en el diccionario de tipo de evento CheckVersionFail=Error de verificación de versión ErrorWrongFileName=El nombre del archivo no puede contener __SOMETHING__ ErrorNotInDictionaryPaymentConditions=No está en el Diccionario de términos de pago, modifíquelo. diff --git a/htdocs/langs/et_EE/errors.lang b/htdocs/langs/et_EE/errors.lang index e6cb1458234..3e4e7b3638a 100644 --- a/htdocs/langs/et_EE/errors.lang +++ b/htdocs/langs/et_EE/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/eu_ES/errors.lang b/htdocs/langs/eu_ES/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/eu_ES/errors.lang +++ b/htdocs/langs/eu_ES/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/fa_IR/errors.lang b/htdocs/langs/fa_IR/errors.lang index 1231bb9e621..4cd240fef47 100644 --- a/htdocs/langs/fa_IR/errors.lang +++ b/htdocs/langs/fa_IR/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/fi_FI/errors.lang b/htdocs/langs/fi_FI/errors.lang index bbbace60e76..9a5148d92c3 100644 --- a/htdocs/langs/fi_FI/errors.lang +++ b/htdocs/langs/fi_FI/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/fr_FR/errors.lang b/htdocs/langs/fr_FR/errors.lang index 80814e27ed2..45c3e0c9a7d 100644 --- a/htdocs/langs/fr_FR/errors.lang +++ b/htdocs/langs/fr_FR/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Vous devez d’abord configurer votre p ErrorFailedToFindEmailTemplate=Aucun gabarit trouvé avec le code %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Durée non définie sur le service. Pas moyen de calculer le prix horaire. ErrorActionCommPropertyUserowneridNotDefined=Le propriétaire de l'utilisateur est requis -ErrorActionCommBadType=Le type d'événement sélectionné (id: %n, code: %s) n'existe pas dans le dictionnaire des types d'événement +ErrorActionCommBadType=Le type d'événement sélectionné (id: %s, code: %s) n'existe pas dans le dictionnaire des types d'événement CheckVersionFail=Échec de la vérification de version ErrorWrongFileName=Le nom du fichier ne peut pas contenir __SOMETHING__ ErrorNotInDictionaryPaymentConditions=Pas dans le dictionnaire des conditions de paiement, veuillez modifier. diff --git a/htdocs/langs/gl_ES/errors.lang b/htdocs/langs/gl_ES/errors.lang index f018fce58a5..8a40a3eb471 100644 --- a/htdocs/langs/gl_ES/errors.lang +++ b/htdocs/langs/gl_ES/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Primeiro debe configurar o seu plan de ErrorFailedToFindEmailTemplate=Fallo ao atopar o modelo co nome de código %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duración non definida no servizo. Non hai forma de calcular o prezo por hora. ErrorActionCommPropertyUserowneridNotDefined=É preciso o supervisor do usuario -ErrorActionCommBadType=O tipo de evento seleccionado (id: %n, código: %s) non existe no diccionario Tipo de Evento +ErrorActionCommBadType=O tipo de evento seleccionado (id: %s, código: %s) non existe no diccionario Tipo de Evento CheckVersionFail=Fallou a comprobación da versión ErrorWrongFileName=O nome do ficheiro non pode conte __SOMETHING__ nel ErrorNotInDictionaryPaymentConditions=Non está no Dicionario de Condicións de Pagamento. Modifíqueo. diff --git a/htdocs/langs/he_IL/errors.lang b/htdocs/langs/he_IL/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/he_IL/errors.lang +++ b/htdocs/langs/he_IL/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/hi_IN/errors.lang b/htdocs/langs/hi_IN/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/hi_IN/errors.lang +++ b/htdocs/langs/hi_IN/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/hr_HR/errors.lang b/htdocs/langs/hr_HR/errors.lang index ec2a653f646..23c3ba0aa1f 100644 --- a/htdocs/langs/hr_HR/errors.lang +++ b/htdocs/langs/hr_HR/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/hu_HU/errors.lang b/htdocs/langs/hu_HU/errors.lang index e097d2988db..d6473374f1b 100644 --- a/htdocs/langs/hu_HU/errors.lang +++ b/htdocs/langs/hu_HU/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=A felhasználó tulajdonosa kötelező -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/id_ID/errors.lang b/htdocs/langs/id_ID/errors.lang index 2df9104a067..be204e5ca21 100644 --- a/htdocs/langs/id_ID/errors.lang +++ b/htdocs/langs/id_ID/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Anda harus terlebih dahulu mengatur bag ErrorFailedToFindEmailTemplate=Gagal menemukan template dengan nama kode %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Durasi tidak ditentukan pada layanan. Tidak ada cara untuk menghitung harga per jam. ErrorActionCommPropertyUserowneridNotDefined=Pemilik pengguna diperlukan -ErrorActionCommBadType=Jenis peristiwa yang dipilih (id: %n, kode: %s) tidak ada di kamus Jenis Peristiwa +ErrorActionCommBadType=Jenis peristiwa yang dipilih (id: %s, kode: %s) tidak ada di kamus Jenis Peristiwa CheckVersionFail=Pemeriksaan versi gagal ErrorWrongFileName=Nama file tidak boleh memiliki __SOMETHING__ di dalamnya ErrorNotInDictionaryPaymentConditions=Tidak ada dalam Kamus Istilah Pembayaran, harap ubah. diff --git a/htdocs/langs/is_IS/errors.lang b/htdocs/langs/is_IS/errors.lang index a6d3ae56134..d8282e3e62a 100644 --- a/htdocs/langs/is_IS/errors.lang +++ b/htdocs/langs/is_IS/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/it_IT/errors.lang b/htdocs/langs/it_IT/errors.lang index f784773bb16..e7d8359baaf 100644 --- a/htdocs/langs/it_IT/errors.lang +++ b/htdocs/langs/it_IT/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Devi prima impostare il tuo piano dei c ErrorFailedToFindEmailTemplate=Impossibile trovare il modello con nome in codice %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Durata non definita in servizio. Non c'è modo di calcolare il prezzo orario. ErrorActionCommPropertyUserowneridNotDefined=Il proprietario dell'utente è obbligatorio -ErrorActionCommBadType=Il tipo di evento selezionato (id: %n, codice: %s) non esiste nel dizionario del tipo di evento +ErrorActionCommBadType=Il tipo di evento selezionato (id: %s, codice: %s) non esiste nel dizionario del tipo di evento CheckVersionFail=Controllo della versione fallito ErrorWrongFileName=Il nome del file non può contenere __SOMETHING__ ErrorNotInDictionaryPaymentConditions=Non nel dizionario dei termini di pagamento, modificare. diff --git a/htdocs/langs/ja_JP/errors.lang b/htdocs/langs/ja_JP/errors.lang index 221d7673ead..278dd008ac8 100644 --- a/htdocs/langs/ja_JP/errors.lang +++ b/htdocs/langs/ja_JP/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=最初に勘定科目表を設定する ErrorFailedToFindEmailTemplate=コードネーム%sのテンプレートが見つかりませんでした ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=サービスで期間が定義されていない。時給計算する方法がない。 ErrorActionCommPropertyUserowneridNotDefined=ユーザの所有者が必要 -ErrorActionCommBadType=選択したイベント種別 (id: %n, code: %s) がイベント種別辞書に存在しない +ErrorActionCommBadType=選択したイベント種別 (id: %s, code: %s) がイベント種別辞書に存在しない CheckVersionFail=バージョンチェックに失敗する ErrorWrongFileName=ファイル名に__SOMETHING__を含めることはできない ErrorNotInDictionaryPaymentConditions=支払条件辞書にないので、変更すること。 diff --git a/htdocs/langs/ka_GE/errors.lang b/htdocs/langs/ka_GE/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/ka_GE/errors.lang +++ b/htdocs/langs/ka_GE/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/kk_KZ/errors.lang b/htdocs/langs/kk_KZ/errors.lang index e10bb476fff..6792201a546 100644 --- a/htdocs/langs/kk_KZ/errors.lang +++ b/htdocs/langs/kk_KZ/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Алдымен сіз өзіңізді ErrorFailedToFindEmailTemplate=%s коды бар үлгі табылмады ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Қызмет көрсету мерзімі анықталмаған. Сағаттық бағаны есептеуге болмайды. ErrorActionCommPropertyUserowneridNotDefined=Пайдаланушының иесі қажет -ErrorActionCommBadType=Таңдалған оқиға түрі (идентификатор: %n, код: %s) оқиға түрі сөздігінде жоқ +ErrorActionCommBadType=Таңдалған оқиға түрі (идентификатор: %s, код: %s) оқиға түрі сөздігінде жоқ CheckVersionFail=Нұсқаны тексеру сәтсіз аяқталды ErrorWrongFileName=Файл атауында __SOMETHING__ болмайды ErrorNotInDictionaryPaymentConditions=Төлем шарттары сөздігінде жоқ, өзгертіңіз. diff --git a/htdocs/langs/km_KH/errors.lang b/htdocs/langs/km_KH/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/km_KH/errors.lang +++ b/htdocs/langs/km_KH/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/kn_IN/errors.lang b/htdocs/langs/kn_IN/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/kn_IN/errors.lang +++ b/htdocs/langs/kn_IN/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ko_KR/errors.lang b/htdocs/langs/ko_KR/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/ko_KR/errors.lang +++ b/htdocs/langs/ko_KR/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/lo_LA/errors.lang b/htdocs/langs/lo_LA/errors.lang index be5f507a576..8390ff24a66 100644 --- a/htdocs/langs/lo_LA/errors.lang +++ b/htdocs/langs/lo_LA/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=ກ່ອນອື່ນmustົດທ ErrorFailedToFindEmailTemplate=ການຊອກຫາແມ່ແບບທີ່ມີລະຫັດຊື່ %s ລົ້ມເຫລວ ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=ບໍ່ໄດ້ ກຳ ນົດໄລຍະເວລາການບໍລິການ. ບໍ່ມີທາງທີ່ຈະຄິດໄລ່ລາຄາຊົ່ວໂມງ. ErrorActionCommPropertyUserowneridNotDefined=ເຈົ້າຂອງຜູ້ໃຊ້ແມ່ນຕ້ອງການ -ErrorActionCommBadType=ປະເພດເຫດການທີ່ເລືອກ (id: %n, ລະຫັດ: %s) ບໍ່ມີຢູ່ໃນວັດຈະນານຸກົມປະເພດເຫດການ +ErrorActionCommBadType=ປະເພດເຫດການທີ່ເລືອກ (id: %s, ລະຫັດ: %s) ບໍ່ມີຢູ່ໃນວັດຈະນານຸກົມປະເພດເຫດການ CheckVersionFail=ກວດສອບເວີຊັນບໍ່ ສຳ ເລັດ ErrorWrongFileName=ຊື່ຂອງໄຟລ cannot ບໍ່ສາມາດມີ __SOMETHING__ ໃນມັນໄດ້ ErrorNotInDictionaryPaymentConditions=ບໍ່ຢູ່ໃນວັດຈະນານຸກົມເງື່ອນໄຂການຈ່າຍເງິນ, ກະລຸນາແກ້ໄຂ. diff --git a/htdocs/langs/lt_LT/errors.lang b/htdocs/langs/lt_LT/errors.lang index 7155a7694df..cff79292d37 100644 --- a/htdocs/langs/lt_LT/errors.lang +++ b/htdocs/langs/lt_LT/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/lv_LV/errors.lang b/htdocs/langs/lv_LV/errors.lang index 58997394f1d..7f8d4a74478 100644 --- a/htdocs/langs/lv_LV/errors.lang +++ b/htdocs/langs/lv_LV/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Vispirms jums ir jāiestata konta plān ErrorFailedToFindEmailTemplate=Neizdevās atrast veidni ar koda nosaukumu %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Ilgums pakalpojumā nav noteikts. Nav iespējams aprēķināt stundas cenu. ErrorActionCommPropertyUserowneridNotDefined=Nepieciešams lietotāja īpašnieks -ErrorActionCommBadType=Atlasītais notikuma veids (id: %n, kods: %s) nepastāv notikuma veida vārdnīcā +ErrorActionCommBadType=Atlasītais notikuma veids (id: %s, kods: %s) nepastāv notikuma veida vārdnīcā CheckVersionFail=Versijas pārbaude neizdevās ErrorWrongFileName=Faila nosaukumā nedrīkst būt __SOMETHING__ ErrorNotInDictionaryPaymentConditions=Nav Maksājumu nosacījumu vārdnīcā, lūdzu, modificējiet. diff --git a/htdocs/langs/mk_MK/errors.lang b/htdocs/langs/mk_MK/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/mk_MK/errors.lang +++ b/htdocs/langs/mk_MK/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/mn_MN/errors.lang b/htdocs/langs/mn_MN/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/mn_MN/errors.lang +++ b/htdocs/langs/mn_MN/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/my_MM/errors.lang b/htdocs/langs/my_MM/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/my_MM/errors.lang +++ b/htdocs/langs/my_MM/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/nb_NO/errors.lang b/htdocs/langs/nb_NO/errors.lang index c9842c73f67..226fc816022 100644 --- a/htdocs/langs/nb_NO/errors.lang +++ b/htdocs/langs/nb_NO/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Du må først konfigurere kontoplanen d ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=Brukerens eier kreves -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Versjonskontroll mislyktes ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ne_NP/errors.lang b/htdocs/langs/ne_NP/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/ne_NP/errors.lang +++ b/htdocs/langs/ne_NP/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/nl_NL/errors.lang b/htdocs/langs/nl_NL/errors.lang index fe70a2010cb..ed4a55d1aab 100644 --- a/htdocs/langs/nl_NL/errors.lang +++ b/htdocs/langs/nl_NL/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=U moet eerst uw rekeningschema instelle ErrorFailedToFindEmailTemplate=Kan sjabloon met codenaam %s . niet vinden ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=De lengte is niet gedefinieerd in de dienst. We kunnen de uurkosten niet berekenen. ErrorActionCommPropertyUserowneridNotDefined=Eigenaar van gebruiker is vereist -ErrorActionCommBadType=Het geselecteerde gebeurtenistype (id: %n, code: %s) bestaat niet in het woordenboek voor gebeurtenistypes +ErrorActionCommBadType=Het geselecteerde gebeurtenistype (id: %s, code: %s) bestaat niet in het woordenboek voor gebeurtenistypes CheckVersionFail=Versiecontrole mislukt ErrorWrongFileName=De naam van het bestand mag niet __SOMETHING__ bevatten ErrorNotInDictionaryPaymentConditions=Niet bekend in de gedefinieerde betaalregelingen, graag wijzigen diff --git a/htdocs/langs/pl_PL/errors.lang b/htdocs/langs/pl_PL/errors.lang index 2022a84943f..fb75cc0a943 100644 --- a/htdocs/langs/pl_PL/errors.lang +++ b/htdocs/langs/pl_PL/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Najpierw musisz ustawić swój plan kon ErrorFailedToFindEmailTemplate=Nie udało się znaleźć szablonu o nazwie kodowej %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=Właściciel użytkownika jest wymagany -ErrorActionCommBadType=Wybrany typ zdarzenia (id: %n, kod: %s) nie istnieje w słowniku typów zdarzeń +ErrorActionCommBadType=Wybrany typ zdarzenia (id: %s, kod: %s) nie istnieje w słowniku typów zdarzeń CheckVersionFail=Sprawdzanie wersji nie powiodło się ErrorWrongFileName=Nazwa pliku nie może zawierać __COŚ__ ErrorNotInDictionaryPaymentConditions=Nie w Słowniku terminów płatności, zmień. diff --git a/htdocs/langs/pt_PT/errors.lang b/htdocs/langs/pt_PT/errors.lang index dc0eb4f58d5..2b0dda28541 100644 --- a/htdocs/langs/pt_PT/errors.lang +++ b/htdocs/langs/pt_PT/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ro_RO/errors.lang b/htdocs/langs/ro_RO/errors.lang index bb74b86bc27..b12fb63d6fd 100644 --- a/htdocs/langs/ro_RO/errors.lang +++ b/htdocs/langs/ro_RO/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Trebuie să setezi mai întâi planul d ErrorFailedToFindEmailTemplate=Nu s-a găsit șablonul cu numele de cod %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Durata nu este definită pentru serviciu. Nicio modalitate de a calcula prețul pe oră. ErrorActionCommPropertyUserowneridNotDefined=Utilizatorul deţinător este obligatoriu -ErrorActionCommBadType=Tipul evenimentului selectat (id: %n, cod: %s) nu există în dicţionarul Tipuri evenimente +ErrorActionCommBadType=Tipul evenimentului selectat (id: %s, cod: %s) nu există în dicţionarul Tipuri evenimente CheckVersionFail=Verificarea versiunii a eşuat ErrorWrongFileName=Numele fișierului nu poate să conțină _SOMETHING_ în el ErrorNotInDictionaryPaymentConditions=Nu se află în dicționarul Condiții de plată, vă rugăm să modificați. diff --git a/htdocs/langs/ru_RU/errors.lang b/htdocs/langs/ru_RU/errors.lang index a5ea90335e0..9f7b33efa88 100644 --- a/htdocs/langs/ru_RU/errors.lang +++ b/htdocs/langs/ru_RU/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Вы должны сначала нас ErrorFailedToFindEmailTemplate=Не удалось найти шаблон с кодовым названием %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Срок службы не определен. Невозможно рассчитать почасовую оплату. ErrorActionCommPropertyUserowneridNotDefined=Требуется владелец пользователя -ErrorActionCommBadType=Выбранный тип события (id: %n, код: %s) не существует в словаре типов событий +ErrorActionCommBadType=Выбранный тип события (id: %s, код: %s) не существует в словаре типов событий CheckVersionFail=Ошибка проверки версии ErrorWrongFileName=Имя файла не может содержать __SOMETHING__ ErrorNotInDictionaryPaymentConditions=Нет в Словаре условий оплаты, пожалуйста, измените. diff --git a/htdocs/langs/sk_SK/errors.lang b/htdocs/langs/sk_SK/errors.lang index cbb983f03f0..a3f364bae15 100644 --- a/htdocs/langs/sk_SK/errors.lang +++ b/htdocs/langs/sk_SK/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/sl_SI/errors.lang b/htdocs/langs/sl_SI/errors.lang index a27b6fceea6..7910fee7eaa 100644 --- a/htdocs/langs/sl_SI/errors.lang +++ b/htdocs/langs/sl_SI/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/sq_AL/errors.lang b/htdocs/langs/sq_AL/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/sq_AL/errors.lang +++ b/htdocs/langs/sq_AL/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/sr_RS/errors.lang b/htdocs/langs/sr_RS/errors.lang index ce3cbc6b148..30b2026e6ca 100644 --- a/htdocs/langs/sr_RS/errors.lang +++ b/htdocs/langs/sr_RS/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/sv_SE/errors.lang b/htdocs/langs/sv_SE/errors.lang index 6eac66b349a..e56c87c8212 100644 --- a/htdocs/langs/sv_SE/errors.lang +++ b/htdocs/langs/sv_SE/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Du måste först ställa in ditt kontop ErrorFailedToFindEmailTemplate=Det gick inte att hitta mall med kodnamn %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Varaktighet definieras inte i tjänsten. Inget sätt att beräkna timpriset. ErrorActionCommPropertyUserowneridNotDefined=Användarens ägare krävs -ErrorActionCommBadType=Vald händelsetyp (id: %n, kod: %s) finns inte i ordlistan för händelsetyp +ErrorActionCommBadType=Vald händelsetyp (id: %s, kod: %s) finns inte i ordlistan för händelsetyp CheckVersionFail=Versionskontroll misslyckades ErrorWrongFileName=Filens namn kan inte innehålla __SOMETHING__ ErrorNotInDictionaryPaymentConditions=Inte i ordningen för betalningsvillkor, ändra. diff --git a/htdocs/langs/sw_SW/errors.lang b/htdocs/langs/sw_SW/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/sw_SW/errors.lang +++ b/htdocs/langs/sw_SW/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ta_IN/errors.lang b/htdocs/langs/ta_IN/errors.lang index 04fa1d14975..d46aeff4ca1 100644 --- a/htdocs/langs/ta_IN/errors.lang +++ b/htdocs/langs/ta_IN/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=முதலில் உங்கள ErrorFailedToFindEmailTemplate=%s என்ற குறியீட்டுப் பெயருடன் டெம்ப்ளேட்டைக் கண்டறிய முடியவில்லை ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=சேவையில் காலம் வரையறுக்கப்படவில்லை. மணிநேர விலையை கணக்கிட வழி இல்லை. ErrorActionCommPropertyUserowneridNotDefined=பயனரின் உரிமையாளர் தேவை -ErrorActionCommBadType=தேர்ந்தெடுக்கப்பட்ட நிகழ்வு வகை (ஐடி: %n, குறியீடு: %s) நிகழ்வு வகை அகராதியில் இல்லை +ErrorActionCommBadType=தேர்ந்தெடுக்கப்பட்ட நிகழ்வு வகை (ஐடி: %s, குறியீடு: %s) நிகழ்வு வகை அகராதியில் இல்லை CheckVersionFail=பதிப்பு சரிபார்ப்பு தோல்வி ErrorWrongFileName=கோப்பின் பெயரில் __சம்திங்__ இருக்கக்கூடாது ErrorNotInDictionaryPaymentConditions=கட்டண விதிமுறைகள் அகராதியில் இல்லை, தயவுசெய்து மாற்றவும். diff --git a/htdocs/langs/tg_TJ/errors.lang b/htdocs/langs/tg_TJ/errors.lang index b861ec4b276..ec74135edae 100644 --- a/htdocs/langs/tg_TJ/errors.lang +++ b/htdocs/langs/tg_TJ/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Шумо аввал бояд ҷадва ErrorFailedToFindEmailTemplate=Шаблон бо номи рамзи %s ёфт нашуд ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Давомнокии хидмат муайян карда нашудааст. Ҳеҷ гуна ҳисоб кардани нархи соатбайъ. ErrorActionCommPropertyUserowneridNotDefined=Соҳиби корбар лозим аст -ErrorActionCommBadType=Навъи рӯйдоди интихобшуда (id: %n, рамз: %s) дар луғати навъи чорабиниҳо вуҷуд надорад +ErrorActionCommBadType=Навъи рӯйдоди интихобшуда (id: %s, рамз: %s) дар луғати навъи чорабиниҳо вуҷуд надорад CheckVersionFail=Санҷиши версия ноком шуд ErrorWrongFileName=Номи файл наметавонад дар он __SOMETHING__ дошта бошад ErrorNotInDictionaryPaymentConditions=Дар луғати шартҳои пардохт нест, лутфан тағир диҳед. diff --git a/htdocs/langs/th_TH/errors.lang b/htdocs/langs/th_TH/errors.lang index 43200416193..efeb030607d 100644 --- a/htdocs/langs/th_TH/errors.lang +++ b/htdocs/langs/th_TH/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/tr_TR/errors.lang b/htdocs/langs/tr_TR/errors.lang index 37622276db8..d3cd4ad4a71 100644 --- a/htdocs/langs/tr_TR/errors.lang +++ b/htdocs/langs/tr_TR/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/uk_UA/errors.lang b/htdocs/langs/uk_UA/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/uk_UA/errors.lang +++ b/htdocs/langs/uk_UA/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ur_PK/errors.lang b/htdocs/langs/ur_PK/errors.lang index 905d70ab7fb..b6a2f5c9eb7 100644 --- a/htdocs/langs/ur_PK/errors.lang +++ b/htdocs/langs/ur_PK/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=آپ کو پہلے اپنے اکاؤن ErrorFailedToFindEmailTemplate=کوڈ نام %s کے ساتھ ٹیمپلیٹ تلاش کرنے میں ناکام ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=سروس پر مدت کی وضاحت نہیں کی گئی ہے۔ فی گھنٹہ قیمت کا حساب لگانے کا کوئی طریقہ نہیں ہے۔ ErrorActionCommPropertyUserowneridNotDefined=صارف کا مالک درکار ہے۔ -ErrorActionCommBadType=ایونٹ کی قسم کی منتخب کردہ (id: %n، کوڈ: %s) ایونٹ کی قسم ڈکشنری میں موجود نہیں ہے۔ +ErrorActionCommBadType=ایونٹ کی قسم کی منتخب کردہ (id: %s، کوڈ: %s) ایونٹ کی قسم ڈکشنری میں موجود نہیں ہے۔ CheckVersionFail=ورژن کی جانچ ناکام ErrorWrongFileName=فائل کے نام میں __SOMETHING__ نہیں ہو سکتا ErrorNotInDictionaryPaymentConditions=ادائیگی کی شرائط ڈکشنری میں نہیں ہے، براہ کرم ترمیم کریں۔ diff --git a/htdocs/langs/uz_UZ/errors.lang b/htdocs/langs/uz_UZ/errors.lang index b337c73d0d6..486e0241698 100644 --- a/htdocs/langs/uz_UZ/errors.lang +++ b/htdocs/langs/uz_UZ/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=Avval hisob qaydnomangizni o'rnatishing ErrorFailedToFindEmailTemplate=%s kodli shablonni topib bo'lmadi ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Xizmat muddati aniqlanmagan. Bir soatlik narxni hisoblashning iloji yo'q. ErrorActionCommPropertyUserowneridNotDefined=Foydalanuvchi egasi talab qilinadi -ErrorActionCommBadType=Tanlangan voqea turi (id: %n, kod: %s) Voqealar turi lug'atida mavjud emas +ErrorActionCommBadType=Tanlangan voqea turi (id: %s, kod: %s) Voqealar turi lug'atida mavjud emas CheckVersionFail=Versiyani tekshirib bo'lmadi ErrorWrongFileName=Fayl nomida __SOMETHING__ bo'lishi mumkin emas ErrorNotInDictionaryPaymentConditions=To'lov shartlari lug'atida yo'q, iltimos o'zgartiring. diff --git a/htdocs/langs/vi_VN/errors.lang b/htdocs/langs/vi_VN/errors.lang index 1b8c6ca61b9..8707c21f67a 100644 --- a/htdocs/langs/vi_VN/errors.lang +++ b/htdocs/langs/vi_VN/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/zh_CN/errors.lang b/htdocs/langs/zh_CN/errors.lang index 1783be09f3a..53188bca81d 100644 --- a/htdocs/langs/zh_CN/errors.lang +++ b/htdocs/langs/zh_CN/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/zh_HK/errors.lang b/htdocs/langs/zh_HK/errors.lang index e05f9dc7a2a..20f5b6f264a 100644 --- a/htdocs/langs/zh_HK/errors.lang +++ b/htdocs/langs/zh_HK/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of acco ErrorFailedToFindEmailTemplate=Failed to find template with code name %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary +ErrorActionCommBadType=Selected event type (id: %s, code: %s) do not exist in Event Type dictionary CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/zh_TW/errors.lang b/htdocs/langs/zh_TW/errors.lang index ef381e5ecb3..7c9a2507df2 100644 --- a/htdocs/langs/zh_TW/errors.lang +++ b/htdocs/langs/zh_TW/errors.lang @@ -269,7 +269,7 @@ ErrorYouMustFirstSetupYourChartOfAccount=您必須先設定會計項目表 ErrorFailedToFindEmailTemplate=無法找到代號為 %s 的模板 ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=未在服務中定義時間範圍.無法計算時薪. ErrorActionCommPropertyUserowneridNotDefined=需要用戶的擁有者 -ErrorActionCommBadType=選擇的事件類型(id:%n,代碼:%s)在事件類型分類中不存在 +ErrorActionCommBadType=選擇的事件類型(id:%s,代碼:%s)在事件類型分類中不存在 CheckVersionFail=版本檢查失敗 ErrorWrongFileName=檔案名稱中不可以有__SOMETHING__ ErrorNotInDictionaryPaymentConditions=不在支付條款類別中,請修改。 From 8dcceeb127a061957be783bfc196c08b01257c64 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Fri, 29 Jul 2022 18:12:17 +0200 Subject: [PATCH 128/205] FIX setup intent stripe Klarna not supported --- htdocs/stripe/class/stripe.class.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index 00d3c4a0d94..5ec149ba07f 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -643,9 +643,6 @@ class Stripe extends CommonObject if (!empty($conf->global->STRIPE_BANCONTACT)) { $paymentmethodtypes[] = "bancontact"; } - if (!empty($conf->global->STRIPE_KLARNA)) { - $paymentmethodtypes[] = "klarna"; - } if (!empty($conf->global->STRIPE_IDEAL)) { $paymentmethodtypes[] = "ideal"; } From edb61faf25c98b1e6b355f2e2e530988ac75b082 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 18:16:29 +0200 Subject: [PATCH 129/205] Fix lang --- test/phpunit/LangTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/phpunit/LangTest.php b/test/phpunit/LangTest.php index 7bd521c2a7a..e0eaded97de 100644 --- a/test/phpunit/LangTest.php +++ b/test/phpunit/LangTest.php @@ -230,6 +230,10 @@ class LangTest extends PHPUnit\Framework\TestCase $result=preg_match('/%n/m', $filecontent); // A sequence of char we don't want //print __METHOD__." Result for checking we don't have bad percent char = ".$result."\n"; $this->assertTrue($result == 0, 'Found a sequence %n into the translation file '.$code.'/'.$file.'. We probably want %s'); + + $result=preg_match('/<<<<assertTrue($result == 0, 'Found a sequence <<<<< into the translation file '.$code.'/'.$file.'. Probably a bad merge of code were done.'); } } From af4d8ef53e75833b9c3f06551c53d9ad94c4be60 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Sat, 30 Jul 2022 15:32:18 +0200 Subject: [PATCH 130/205] FIX validation paymentok.php if advance rights --- htdocs/public/payment/paymentok.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index c9b8f13c877..e04f00d7459 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -364,13 +364,14 @@ if ($ispaymentok) { } if (empty($user->rights->facture)) { $user->rights->facture = new stdClass(); + $user->rights->facture->invoice_advance = new stdClass(); } if (empty($user->rights->adherent)) { $user->rights->adherent = new stdClass(); - $user->rights->adherent->cotisation = new stdClass(); } $user->rights->societe->creer = 1; $user->rights->facture->creer = 1; + $user->rights->facture->invoice_advance->validate = 1; $user->rights->adherent->cotisation->creer = 1; if (array_key_exists('MEM', $tmptag) && $tmptag['MEM'] > 0) { From 454fb6b0f5f709cec4b77b5005a16a627a891029 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Sun, 31 Jul 2022 13:10:38 +0200 Subject: [PATCH 131/205] new: Add IMAP port setting on email collector module --- htdocs/emailcollector/class/emailcollector.class.php | 5 +++-- htdocs/install/mysql/migration/16.0.0-17.0.0.sql | 1 + .../mysql/tables/llx_emailcollector_emailcollector.sql | 1 + htdocs/langs/en_US/admin.lang | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 9a60624e9d2..11d2dcfeb46 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -115,7 +115,8 @@ class EmailCollector extends CommonObject 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'visible'=>1, 'enabled'=>1, 'position'=>30, 'notnull'=>-1, 'searchall'=>1, 'help'=>'Example: My Email collector', 'csslist'=>'tdoverflowmax150'), 'description' => array('type'=>'text', 'label'=>'Description', 'visible'=>-1, 'enabled'=>1, 'position'=>60, 'notnull'=>-1, 'csslist'=>'small'), 'host' => array('type'=>'varchar(255)', 'label'=>'EMailHost', 'visible'=>1, 'enabled'=>1, 'position'=>90, 'notnull'=>1, 'searchall'=>1, 'comment'=>"IMAP server", 'help'=>'Example: imap.gmail.com', 'csslist'=>'tdoverflow125'), - 'hostcharset' => array('type'=>'varchar(16)', 'label'=>'HostCharset', 'visible'=>-1, 'enabled'=>1, 'position'=>91, 'notnull'=>0, 'searchall'=>0, 'comment'=>"IMAP server charset", 'help'=>'Example: "UTF-8" (May be "US-ASCII" with some Office365)'), + 'port' => array('type'=>'varchar(10)', 'label'=>'EMailHostPort', 'visible'=>1, 'enabled'=>1, 'position'=>91, 'notnull'=>1, 'searchall'=>0, 'comment'=>"IMAP server port", 'help'=>'Example: 993', 'csslist'=>'tdoverflow125', 'default'=>'993'), + 'hostcharset' => array('type'=>'varchar(16)', 'label'=>'HostCharset', 'visible'=>-1, 'enabled'=>1, 'position'=>92, 'notnull'=>0, 'searchall'=>0, 'comment'=>"IMAP server charset", 'help'=>'Example: "UTF-8" (May be "US-ASCII" with some Office365)', 'default'=>'UTF-8'), 'login' => array('type'=>'varchar(128)', 'label'=>'Login', 'visible'=>1, 'enabled'=>1, 'position'=>101, 'notnull'=>-1, 'index'=>1, 'comment'=>"IMAP login", 'help'=>'Example: myaccount@gmail.com'), 'password' => array('type'=>'password', 'label'=>'Password', 'visible'=>-1, 'enabled'=>1, 'position'=>102, 'notnull'=>-1, 'comment'=>"IMAP password", 'help'=>'WithGMailYouCanCreateADedicatedPassword'), 'source_directory' => array('type'=>'varchar(255)', 'label'=>'MailboxSourceDirectory', 'visible'=>-1, 'enabled'=>1, 'position'=>103, 'notnull'=>1, 'default' => 'Inbox', 'help'=>'Example: INBOX'), @@ -746,7 +747,7 @@ class EmailCollector extends CommonObject $flags .= '/authuser='.$partofauth[0].'/user='.$partofauth[1]; } - $connectstringserver = '{'.$this->host.':993'.$flags.'}'; + $connectstringserver = '{'.$this->host.':'.$this->port.$flags.'}'; return $connectstringserver; } diff --git a/htdocs/install/mysql/migration/16.0.0-17.0.0.sql b/htdocs/install/mysql/migration/16.0.0-17.0.0.sql index 24b4e20a7b7..8394ae97478 100644 --- a/htdocs/install/mysql/migration/16.0.0-17.0.0.sql +++ b/htdocs/install/mysql/migration/16.0.0-17.0.0.sql @@ -64,3 +64,4 @@ ALTER TABLE llx_ticket ADD COLUMN ip varchar(250); ALTER TABLE llx_societe ADD last_main_doc VARCHAR(255) NULL AFTER model_pdf; +ALTER TABLE llx_emailcollector_emailcollector ADD COLUMN port varchar(10) DEFAULT '993'; diff --git a/htdocs/install/mysql/tables/llx_emailcollector_emailcollector.sql b/htdocs/install/mysql/tables/llx_emailcollector_emailcollector.sql index b62a9b6ba7f..3580f1659b1 100644 --- a/htdocs/install/mysql/tables/llx_emailcollector_emailcollector.sql +++ b/htdocs/install/mysql/tables/llx_emailcollector_emailcollector.sql @@ -22,6 +22,7 @@ CREATE TABLE llx_emailcollector_emailcollector( label varchar(255), description text, host varchar(255), + port varchar(10) DEFAULT '993', hostcharset varchar(16) DEFAULT 'UTF-8', login varchar(128), password varchar(128), diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index c1f01ae85d9..7148e19fb48 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2064,6 +2064,7 @@ EmailCollectors=Email collectors EmailCollectorDescription=Add a scheduled job and a setup page to scan regularly email boxes (using IMAP protocol) and record emails received into your application, at the right place and/or create some records automatically (like leads). NewEmailCollector=New Email Collector EMailHost=Host of email IMAP server +EMailHostPort=Port of email IMAP server MailboxSourceDirectory=Mailbox source directory MailboxTargetDirectory=Mailbox target directory EmailcollectorOperations=Operations to do by collector From 93031773868b62ef9b8593b5a4d15f3ae6f06d17 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 31 Jul 2022 19:12:42 +0200 Subject: [PATCH 132/205] Fix regression --- htdocs/compta/bank/releve.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index 2dbaaa07373..c08336841e2 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -387,6 +387,10 @@ if (empty($numref)) { * Show list of record into a bank statement */ + $title = $langs->trans("FinancialAccount").' - '.$langs->trans("AccountStatements"); + $helpurl = ""; + llxHeader('', $title, $helpurl); + // Onglets $head = account_statement_prepare_head($object, $numref); print dol_get_fiche_head($head, 'statement', $langs->trans("AccountStatement"), -1, 'account'); From 1fbd4b1c2dad208b38002d6ea02c955d69f63fba Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 31 Jul 2022 20:12:22 +0200 Subject: [PATCH 133/205] Clean code --- htdocs/modulebuilder/template/myobject_list.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 32bf5ae3200..380eab1ab6b 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -53,7 +53,8 @@ if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) { // Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME $tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1; while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { - $i--; $j--; + $i--; + $j--; } if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) { $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php"; @@ -88,9 +89,6 @@ require_once __DIR__.'/class/myobject.class.php'; // Load translation files required by the page $langs->loadLangs(array("mymodule@mymodule", "other")); -$id = GETPOST('id', 'int'); -$ref = GETPOST('ref', 'alpha'); - $action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ... $massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) $show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ? @@ -102,6 +100,9 @@ $backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') $mode = GETPOST('mode', 'aZ'); +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); + // Load variable for pagination $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST('sortfield', 'aZ09comma'); From 9286f84b47fc1b0b24f958fe65082ef2e7997b22 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 31 Jul 2022 21:06:08 +0200 Subject: [PATCH 134/205] Fix php8 --- htdocs/core/class/commonobject.class.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 2d393ab9dc3..aa85c0aa5c2 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -744,6 +744,7 @@ abstract class CommonObject public function setUpperOrLowerCase() { global $conf; + if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) { $this->lastname = dol_ucwords(dol_strtolower($this->lastname)); $this->firstname = dol_ucwords(dol_strtolower($this->firstname)); @@ -759,8 +760,12 @@ abstract class CommonObject $this->address = dol_strtoupper($this->address); $this->town = dol_strtoupper($this->town); } - $this->email = dol_strtolower($this->email); - $this->personal_email = dol_strtolower($this->personal_email); + if (isset($this->email)) { + $this->email = dol_strtolower($this->email); + } + if (isset($this->personal_email)) { + $this->personal_email = dol_strtolower($this->personal_email); + } } /** From 628a368686c466acd5d770e5fa77a1c2c945f71e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 31 Jul 2022 21:25:24 +0200 Subject: [PATCH 135/205] Add column position for llx_bank --- htdocs/install/mysql/migration/16.0.0-17.0.0.sql | 2 ++ htdocs/install/mysql/tables/llx_bank.sql | 1 + 2 files changed, 3 insertions(+) diff --git a/htdocs/install/mysql/migration/16.0.0-17.0.0.sql b/htdocs/install/mysql/migration/16.0.0-17.0.0.sql index 24b4e20a7b7..78f71563a45 100644 --- a/htdocs/install/mysql/migration/16.0.0-17.0.0.sql +++ b/htdocs/install/mysql/migration/16.0.0-17.0.0.sql @@ -64,3 +64,5 @@ ALTER TABLE llx_ticket ADD COLUMN ip varchar(250); ALTER TABLE llx_societe ADD last_main_doc VARCHAR(255) NULL AFTER model_pdf; +ALTER TABLE llx_bank ADD COLUMN position integer DEFAULT 0; + diff --git a/htdocs/install/mysql/tables/llx_bank.sql b/htdocs/install/mysql/tables/llx_bank.sql index d0a8e34790b..9a1b12d5754 100644 --- a/htdocs/install/mysql/tables/llx_bank.sql +++ b/htdocs/install/mysql/tables/llx_bank.sql @@ -37,6 +37,7 @@ create table llx_bank rappro tinyint default 0, note text, fk_bordereau integer DEFAULT 0, + position integer DEFAULT 0, banque varchar(255), -- banque pour les cheques emetteur varchar(255), -- emetteur du cheque author varchar(40), -- a supprimer apres migration From 7dfeae694f2d4b1a5f2b816ad3d57d9ec2fc7659 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 31 Jul 2022 22:22:46 +0200 Subject: [PATCH 136/205] CSS amount --- htdocs/compta/facture/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index bdc6a102147..7b7d8c61c1d 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -2083,7 +2083,7 @@ if ($resql) { // Amount HT if (!empty($arrayfields['f.total_ht']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } From 4c4dd53385bc8259b7bfdd33421f62f16e294b0d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 31 Jul 2022 22:46:53 +0200 Subject: [PATCH 137/205] Fix filter on company --- htdocs/compta/facture/list.php | 11 ++++++----- htdocs/fourn/facture/list.php | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index f5d1f519698..b7d20f3f0f8 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -363,11 +363,11 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', $search_datelimit_start = ''; $search_datelimit_end = ''; $search_fac_rec_source_title = ''; - $option = ''; - $filter = ''; $toselect = array(); $search_array_options = array(); $search_categ_cus = 0; + $option = ''; + $socid = 0; } if (empty($reshook)) { @@ -919,7 +919,7 @@ if ($resql) { llxHeader('', $langs->trans('CustomersInvoices'), 'EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes'); - if ($socid) { + if ($socid > 0) { $soc = new Societe($db); $soc->fetch($socid); if (empty($search_company)) { @@ -1151,8 +1151,9 @@ if ($resql) { print ''; print ''; print ''; + print ''; - print_barre_liste($langs->trans('BillsCustomers').' '.($socid ? ' '.$soc->name : ''), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'bill', 0, $newcardbutton, '', $limit, 0, 0, 1); + print_barre_liste($langs->trans('BillsCustomers').' '.($socid > 0 ? ' '.$soc->name : ''), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'bill', 0, $newcardbutton, '', $limit, 0, 0, 1); $topicmail = "SendBillRef"; $modelmail = "facture_send"; @@ -1320,7 +1321,7 @@ if ($resql) { } // Thirdparty if (!empty($arrayfields['s.nom']['checked'])) { - print ''; + print ''; } // Alias if (!empty($arrayfields['s.name_alias']['checked'])) { diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index 70a7334196a..df5cd0d090d 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -1002,7 +1002,7 @@ if ($resql) { } // Thirpdarty if (!empty($arrayfields['s.nom']['checked'])) { - print ''; + print ''; } // Town if (!empty($arrayfields['s.town']['checked'])) { From 6b5fac432fdeb53593f6b16dee4551cb5f3504b0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 1 Aug 2022 03:46:15 +0200 Subject: [PATCH 138/205] Add doc --- htdocs/core/lib/functions.lib.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index b286adae481..c3cd8922955 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -9141,6 +9141,7 @@ function printCommonFooter($zone = 'private') print "\n"; if (!empty($conf->use_javascript_ajax)) { + print "\n\n"; print ''; diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 3886651e8d5..078d485a5c9 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -543,6 +543,7 @@ fieldset { border: 1px solid #AAAAAA !important; padding-inline-start: 2em; padding-inline-end: 2em; + min-inline-size: auto; } .legendforfieldsetstep { padding-bottom: 10px; } input#onlinepaymenturl, input#directdownloadlink { diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 6e423228df1..ca485fb0d5f 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -725,6 +725,7 @@ fieldset { border: 1px solid #AAAAAA !important; padding-inline-start: 2em; padding-inline-end: 2em; + min-inline-size: auto; } .legendforfieldsetstep { padding-bottom: 10px; } input#onlinepaymenturl, input#directdownloadlink { From 064c95baef12a3ac5b4b353b503c84d2b467b738 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 3 Aug 2022 18:18:17 +0200 Subject: [PATCH 193/205] CSS --- htdocs/admin/tools/dolibarr_export.php | 12 +++++++----- htdocs/theme/eldy/global.inc.php | 1 + htdocs/theme/md/style.css.php | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/htdocs/admin/tools/dolibarr_export.php b/htdocs/admin/tools/dolibarr_export.php index 1a68b17c3e0..588cc5ed866 100644 --- a/htdocs/admin/tools/dolibarr_export.php +++ b/htdocs/admin/tools/dolibarr_export.php @@ -168,9 +168,10 @@ print ''; print ''; -print '
'; - print $langs->trans("AddContactIntoCategory").'  '; + print $langs->trans("AssignCategoryTo").'  '; print $form->selectContacts('', '', 'elemid'); print '
'; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -931,7 +935,7 @@ if ($type == Categorie::TYPE_ACCOUNT) { // Link to delete from category print ''; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -1009,7 +1013,7 @@ if ($type == Categorie::TYPE_PROJECT) { // Link to delete from category print ''; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -1081,7 +1085,7 @@ if ($type == Categorie::TYPE_USER) { // Link to delete from category print ''; if ($user->rights->user->user->creer) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -1140,7 +1144,7 @@ if ($type == Categorie::TYPE_WAREHOUSE) { // Link to delete from category print ''; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -1156,6 +1160,7 @@ if ($type == Categorie::TYPE_WAREHOUSE) { } } +// List of tickets if ($type == Categorie::TYPE_TICKET) { $permission = ($user->rights->categorie->creer || $user->rights->categorie->creer); @@ -1212,7 +1217,7 @@ if ($type == Categorie::TYPE_TICKET) { // Link to delete from category print ''; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; From 59b2412bc2d36a0c4435e01ee210385ea91432db Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 12:52:27 +0200 Subject: [PATCH 107/205] Fix position of fields --- htdocs/contact/list.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 8d60b37611f..a0091061adb 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -207,16 +207,16 @@ foreach ($object->fields as $key => $val) { } // Add none object fields to fields for list -$arrayfields['country.code_iso'] = array('label'=>"Country", 'position'=>22, 'checked'=>0); +$arrayfields['country.code_iso'] = array('label'=>"Country", 'position'=>66, 'checked'=>0); if (empty($conf->global->SOCIETE_DISABLE_CONTACTS)) { - $arrayfields['s.nom'] = array('label'=>"ThirdParty", 'position'=>25, 'checked'=>1); + $arrayfields['s.nom'] = array('label'=>"ThirdParty", 'position'=>113, 'checked'=> 1); } $arrayfields['unsubscribed'] = array( 'label'=>'No_Email', 'checked'=>0, 'enabled'=>(!empty($conf->mailing->enabled)), - 'position'=>41); + 'position'=>111); if (!empty($conf->socialnetworks->enabled)) { foreach ($socialnetworks as $key => $value) { From e25b599ee3a3251402833939b18364e034d50b0b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 12:52:27 +0200 Subject: [PATCH 108/205] Fix position of fields --- htdocs/contact/list.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 97dd6444d0a..0bb902f7ca1 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -206,16 +206,16 @@ foreach ($object->fields as $key => $val) { } // Add none object fields to fields for list -$arrayfields['country.code_iso'] = array('label'=>"Country", 'position'=>22, 'checked'=>0); +$arrayfields['country.code_iso'] = array('label'=>"Country", 'position'=>66, 'checked'=>0); if (empty($conf->global->SOCIETE_DISABLE_CONTACTS)) { - $arrayfields['s.nom'] = array('label'=>"ThirdParty", 'position'=>25, 'checked'=>1); + $arrayfields['s.nom'] = array('label'=>"ThirdParty", 'position'=>113, 'checked'=> 1); } $arrayfields['unsubscribed'] = array( 'label'=>'No_Email', 'checked'=>0, 'enabled'=>(!empty($conf->mailing->enabled)), - 'position'=>41); + 'position'=>111); if (!empty($conf->socialnetworks->enabled)) { foreach ($socialnetworks as $key => $value) { From 3dc0e14f0e7956b36604c7282f252e00f47287ff Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Fri, 29 Jul 2022 13:04:04 +0200 Subject: [PATCH 109/205] Fix : HasRight on user.class.php for $permlevel2 --- htdocs/user/class/user.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 6fca728ee8b..f206d47bd24 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -775,16 +775,16 @@ class User extends CommonObject // For backward compatibility with old permissions called "lire", "creer", "create", "supprimer" // instead of "read", "write", "delete" if ($permlevel2 == 'read' && !empty($this->rights->$rightsPath->$permlevel1->lire)) { - return $this->rights->$rightsPath->lire; + return $this->rights->$rightsPath->$permlevel1->lire; } if ($permlevel2 == 'write' && !empty($this->rights->$rightsPath->$permlevel1->creer)) { - return $this->rights->$rightsPath->create; + return $this->rights->$rightsPath->$permlevel1->create; } if ($permlevel2 == 'write' && !empty($this->rights->$rightsPath->$permlevel1->create)) { - return $this->rights->$rightsPath->create; + return $this->rights->$rightsPath->$permlevel1->create; } if ($permlevel2 == 'delete' && !empty($this->rights->$rightsPath->$permlevel1->supprimer)) { - return $this->rights->$rightsPath->supprimer; + return $this->rights->$rightsPath->$permlevel1->supprimer; } } } else { From aca6b848d2d722b7d9db0fa0bd2b7631f8d6e2b8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Jul 2022 13:58:30 +0200 Subject: [PATCH 110/205] Picto --- htdocs/product/stock/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/stock/index.php b/htdocs/product/stock/index.php index 9aad5f382cc..6efe9f0d9e8 100644 --- a/htdocs/product/stock/index.php +++ b/htdocs/product/stock/index.php @@ -141,7 +141,7 @@ print '
'; $max = 10; $sql = "SELECT p.rowid, p.label as produit, p.tobatch, p.tosell, p.tobuy,"; $sql .= " e.ref as warehouse_ref, e.rowid as warehouse_id, e.ref as warehouse_label, e.lieu, e.statut as warehouse_status,"; -$sql .= " m.value as qty, m.datem, m.batch, m.eatby, m.sellby"; +$sql .= " m.rowid as mid, m.value as qty, m.datem, m.batch, m.eatby, m.sellby"; $sql .= " FROM ".MAIN_DB_PREFIX."entrepot as e"; $sql .= ", ".MAIN_DB_PREFIX."stock_mouvement as m"; $sql .= ", ".MAIN_DB_PREFIX."product as p"; @@ -200,7 +200,7 @@ if ($resql) { $tmplotstatic->eatby = $objp->eatby; print '
'.dol_print_date($db->jdate($objp->datem), 'dayhour').''.img_picto($langs->trans("Ref").' '.$objp->mid, 'movement', 'class="pictofixedwidth"').dol_print_date($db->jdate($objp->datem), 'dayhour').''; print $producttmp->getNomUrl(1); print "
'.dol_print_date($db->jdate($objp->datem), 'dayhour').''.img_picto($langs->trans("Ref").' '.$objp->mid, 'movement', 'class="pictofixedwidth"').dol_print_date($db->jdate($objp->datem), 'dayhour').''; print $producttmp->getNomUrl(1); print "
'.$form->editfieldkey('Categories', 'usercats', '', $object, 0).''; $cate_arbo = $form->select_all_categories('user', null, 'parent', null, null, 1); print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('usercats', $cate_arbo, GETPOST('usercats', 'array'), 0, 0, 'maxwdith300 widthcentpercentminusx', 0, '90%'); @@ -1234,9 +1234,9 @@ if ($action == 'create' || $action == 'adduserldap') { print ''; print '
'.$langs->trans("Categories").''; print $form->showCategories($object->id, Categorie::TYPE_USER, 1); @@ -1804,7 +1804,7 @@ if ($action == 'create' || $action == 'adduserldap') { print '
'.$langs->trans("ApiKey").''; if (!empty($object->api_key)) { @@ -2369,7 +2369,7 @@ if ($action == 'create' || $action == 'adduserldap') { print "
'.$langs->trans("ApiKey").''; print ''; @@ -2566,7 +2566,7 @@ if ($action == 'create' || $action == 'adduserldap') { print '
'.$form->editfieldkey('Categories', 'usercats', '', $object, 0).''; print img_picto('', 'category', 'class="pictofixedwidth"'); @@ -2711,8 +2711,8 @@ if ($action == 'create' || $action == 'adduserldap') { // Sensitive salary/value information if ((empty($user->socid) && in_array($id, $childids)) // A user can always see salary/value information for its subordinates - || (!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall)) - || (!empty($conf->hrm->enabled) && !empty($user->rights->hrm->employee->read))) { + || (!empty($conf->salaries->enabled) && !empty($user->hasRight("salaries", "readall"))) + || (!empty($conf->hrm->enabled) && !empty($user->hasRight("hrm", "employee", "read")))) { $langs->load("salaries"); // Salary @@ -2803,8 +2803,8 @@ if ($action == 'create' || $action == 'adduserldap') { $filename = dol_sanitizeFileName($object->ref); $filedir = $conf->user->dir_output."/".dol_sanitizeFileName($object->ref); $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; - $genallowed = $user->rights->user->user->lire; - $delallowed = $user->rights->user->user->creer; + $genallowed = $user->hasRight("user", "user", "read"); + $delallowed = $user->hasRight("user", "user", "write"); print $formfile->showdocuments('user', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', 0, '', empty($soc->default_lang) ? '' : $soc->default_lang); $somethingshown = $formfile->numoffiles; diff --git a/htdocs/user/document.php b/htdocs/user/document.php index ed1fe30df4e..31ec618a795 100644 --- a/htdocs/user/document.php +++ b/htdocs/user/document.php @@ -41,23 +41,23 @@ $ref = GETPOST('ref', 'alpha'); $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'userdoc'; // To manage different context of search // Define value to know what current user can do on users -$canadduser = (!empty($user->admin) || $user->rights->user->user->creer); -$canreaduser = (!empty($user->admin) || $user->rights->user->user->lire); -$canedituser = (!empty($user->admin) || $user->rights->user->user->creer); -$candisableuser = (!empty($user->admin) || $user->rights->user->user->supprimer); +$canadduser = (!empty($user->admin) || $user->hasRight("user", "user", "write")); +$canreaduser = (!empty($user->admin) || $user->hasRight("user", "user", "read")); +$canedituser = (!empty($user->admin) || $user->hasRight("user", "user", "write")); +$candisableuser = (!empty($user->admin) || $user->hasRight("user", "user", "delete")); $canreadgroup = $canreaduser; $caneditgroup = $canedituser; if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - $canreadgroup = (!empty($user->admin) || $user->rights->user->group_advance->read); - $caneditgroup = (!empty($user->admin) || $user->rights->user->group_advance->write); + $canreadgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "read")); + $caneditgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "write")); } // Define value to know what current user can do on properties of edited user if ($id) { // $user est le user qui edite, $id est l'id de l'utilisateur edite - $caneditfield = ((($user->id == $id) && $user->rights->user->self->creer) - || (($user->id != $id) && $user->rights->user->user->creer)); - $caneditpassword = ((($user->id == $id) && $user->rights->user->self->password) - || (($user->id != $id) && $user->rights->user->user->password)); + $caneditfield = ((($user->id == $id) && $user->hasRight("user", "self", "write")) + || (($user->id != $id) && $user->hasRight("user", "user", "write"))); + $caneditpassword = ((($user->id == $id) && $user->hasRight("user", "self", "password")) + || (($user->id != $id) && $user->hasRight("user", "user", "passsword"))); } $permissiontoadd = $caneditfield; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles @@ -147,7 +147,7 @@ if ($object->id) { print dol_get_fiche_head($head, 'document', $langs->trans("User"), -1, 'user'); $linkback = ''; - if ($user->rights->user->user->lire || $user->admin) { + if ($user->hasRight("user", "user", "read") || $user->admin) { $linkback = ''.$langs->trans("BackToList").''; } @@ -155,7 +155,7 @@ if ($object->id) { $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); $morehtmlref .= ''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); + dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; print '
'; diff --git a/htdocs/user/group/card.php b/htdocs/user/group/card.php index 92d309e554b..9b6e9e1c317 100644 --- a/htdocs/user/group/card.php +++ b/htdocs/user/group/card.php @@ -32,16 +32,16 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; // Defini si peux lire/modifier utilisateurs et permisssions -$canreadperms = ($user->admin || $user->rights->user->user->lire); -$caneditperms = ($user->admin || $user->rights->user->user->creer); -$candisableperms = ($user->admin || $user->rights->user->user->supprimer); +$canreadperms = ($user->admin || $user->hasRight("user", "user", "read")); +$caneditperms = ($user->admin || $user->hasRight("user", "user", "write")); +$candisableperms = ($user->admin || $user->hasRight("user", "user", "delete")); $feature2 = 'user'; // Advanced permissions if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - $canreadperms = ($user->admin || $user->rights->user->group_advance->read); - $caneditperms = ($user->admin || $user->rights->user->group_advance->write); - $candisableperms = ($user->admin || $user->rights->user->group_advance->delete); + $canreadperms = ($user->admin || $user->hasRight("user", "group_advance", "read")); + $caneditperms = ($user->admin || $user->hasRight("user", "group_advance", "write")); + $candisableperms = ($user->admin || $user->hasRight("user", "group_advance", "delete")); $feature2 = 'group_advance'; } @@ -238,7 +238,7 @@ if (empty($reshook)) { // Actions to build doc $upload_dir = $conf->user->dir_output.'/usergroups'; - $permissiontoadd = $user->rights->user->user->creer; + $permissiontoadd = $user->hasRight("user", "user", "write"); include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; } @@ -250,7 +250,7 @@ $title = $object->name.' - '.$langs->trans("Card"); if ($action == 'create') { $title = $langs->trans("NewGroup"); } - +$help_url = ""; llxHeader('', $title, $help_url); @@ -329,7 +329,7 @@ if ($action == 'create') { $linkback = ''.$langs->trans("BackToList").''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); + dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin); print '
'; print '
'; @@ -485,8 +485,8 @@ if ($action == 'create') { $filename = dol_sanitizeFileName($object->ref); $filedir = $conf->user->dir_output."/usergroups/".dol_sanitizeFileName($object->ref); $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; - $genallowed = $user->rights->user->user->creer; - $delallowed = $user->rights->user->user->supprimer; + $genallowed = $user->hasRight("user", "user", "write"); + $delallowed = $user->hasRight("user", "user", "delete"); $somethingshown = $formfile->showdocuments('usergroup', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', 0, '', $mysoc->default_lang); diff --git a/htdocs/user/group/list.php b/htdocs/user/group/list.php index bb130b33e75..8f7f907eb7b 100644 --- a/htdocs/user/group/list.php +++ b/htdocs/user/group/list.php @@ -38,10 +38,10 @@ $massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choi $contextpage = GETPOST('optioncss', 'aZ09'); // Defini si peux lire/modifier utilisateurs et permisssions -$caneditperms = ($user->admin || $user->rights->user->user->creer); +$caneditperms = ($user->admin || $user->hasRight("user", "user", "write")); // Advanced permissions if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - $caneditperms = ($user->admin || $user->rights->user->group_advance->write); + $caneditperms = ($user->admin || $user->hasRight("user", "group_advance", "write")); } // Load variable for pagination @@ -70,7 +70,7 @@ $fieldstosearchall = array( ); if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - if (!$user->rights->user->group_advance->read && !$user->admin) { + if (!$user->hasRight("user", "group_advance", "read") && !$user->admin) { accessforbidden(); } } @@ -80,7 +80,7 @@ if (!empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global-> accessforbidden(); } -if (!$user->rights->user->user->lire && !$user->admin) { +if (!$user->hasRight("user", "user", "read") && !$user->admin) { accessforbidden(); } @@ -121,6 +121,7 @@ if (empty($reshook)) { * View */ $title = $langs->trans("ListOfGroups"); +$help_url=""; llxHeader('', $title, $help_url); $sql = "SELECT g.rowid, g.nom as name, g.note, g.entity, g.datec, g.tms as datem, COUNT(DISTINCT ugu.fk_user) as nb, COUNT(DISTINCT ugr.fk_id) as nbpermissions"; diff --git a/htdocs/user/group/perms.php b/htdocs/user/group/perms.php index edf20d0884c..15fcc2a319f 100644 --- a/htdocs/user/group/perms.php +++ b/htdocs/user/group/perms.php @@ -50,15 +50,15 @@ if (!isset($id) || empty($id)) { } // Define if user can read permissions -$canreadperms = ($user->admin || $user->rights->user->user->lire); +$canreadperms = ($user->admin || $user->hasRight("user", "user", "read")); // Define if user can modify group permissions -$caneditperms = ($user->admin || $user->rights->user->user->creer); +$caneditperms = ($user->admin || $user->hasRight("user", "user", "write")); // Advanced permissions $advancedpermsactive = false; if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { $advancedpermsactive = true; - $canreadperms = ($user->admin || ($user->rights->user->group_advance->read && $user->rights->user->group_advance->readperms)); - $caneditperms = ($user->admin || $user->rights->user->group_advance->write); + $canreadperms = ($user->admin || ($user->hasRight("user", "group_advance", "read") && $user->hasRight("user", "group_advance", "readperms"))); + $caneditperms = ($user->admin || $user->hasRight("user", "group_advance", "write")); } // Security check @@ -206,7 +206,7 @@ if ($object->id > 0) { $linkback = ''.$langs->trans("BackToList").''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); + dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin); print '
'; print '
'; diff --git a/htdocs/user/hierarchy.php b/htdocs/user/hierarchy.php index 92d0490f1c6..3f8326d3b7b 100644 --- a/htdocs/user/hierarchy.php +++ b/htdocs/user/hierarchy.php @@ -60,9 +60,9 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', $userstatic = new User($db); // Define value to know what current user can do on users -$canadduser = (!empty($user->admin) || $user->rights->user->user->creer); +$canadduser = (!empty($user->admin) || $user->hasRight("user", "user", "write")); -if (!$user->rights->user->user->lire && !$user->admin) { +if (!$user->hasRight("user", "user", "read") && !$user->admin) { accessforbidden(); } diff --git a/htdocs/user/list.php b/htdocs/user/list.php index a47fa7a51c2..f0196789e25 100644 --- a/htdocs/user/list.php +++ b/htdocs/user/list.php @@ -131,7 +131,7 @@ $arrayfields = array( 'u.email'=>array('label'=>"EMail", 'checked'=>1, 'position'=>35), 'u.api_key'=>array('label'=>"ApiKey", 'checked'=>0, 'position'=>40, "enabled"=>(!empty($conf->api->enabled) && $user->admin)), 'u.fk_soc'=>array('label'=>"Company", 'checked'=>($contextpage == 'employeelist' ? 0 : 1), 'position'=>45), - 'u.salary'=>array('label'=>"Salary", 'checked'=>1, 'position'=>80, 'enabled'=>(!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall))), + 'u.salary'=>array('label'=>"Salary", 'checked'=>1, 'position'=>80, 'enabled'=>(!empty($conf->salaries->enabled) && !empty($user->hasRight("salaries", "readall")))), 'u.datelastlogin'=>array('label'=>"LastConnexion", 'checked'=>1, 'position'=>100), 'u.datepreviouslogin'=>array('label'=>"PreviousConnexion", 'checked'=>0, 'position'=>110), 'u.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500), @@ -174,26 +174,26 @@ if ($mode == 'employee' && !GETPOSTISSET('search_employee')) { } // Define value to know what current user can do on users -$permissiontoadd = (!empty($user->admin) || $user->rights->user->user->creer); -$canreaduser = (!empty($user->admin) || $user->rights->user->user->lire); -$canedituser = (!empty($user->admin) || $user->rights->user->user->creer); -$candisableuser = (!empty($user->admin) || $user->rights->user->user->supprimer); +$permissiontoadd = (!empty($user->admin) || $user->hasRight("user", "user", "write")); +$canreaduser = (!empty($user->admin) || $user->hasRight("user", "user", "read")); +$canedituser = (!empty($user->admin) || $user->hasRight("user", "user", "write")); +$candisableuser = (!empty($user->admin) || $user->hasRight("user", "user", "delete")); $canreadgroup = $canreaduser; $caneditgroup = $canedituser; if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - $canreadgroup = (!empty($user->admin) || $user->rights->user->group_advance->read); - $caneditgroup = (!empty($user->admin) || $user->rights->user->group_advance->write); + $canreadgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "read")); + $caneditgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "write")); } $error = 0; // Permission to list if ($mode == 'employee') { - if (empty($user->rights->salaries->read)) { + if (empty($user->hasRight("salaries", "read"))) { accessforbidden(); } } else { - if (empty($user->rights->user->user->lire) && empty($user->admin)) { + if (empty($user->hasRight("user", "user", "read")) && empty($user->admin)) { accessforbidden(); } } @@ -441,7 +441,7 @@ if ($search_categ == -2) { if ($search_warehouse > 0) { $sql .= " AND u.fk_warehouse = ".((int) $search_warehouse); } -if ($mode == 'employee' && empty($user->rights->salaries->readall)) { +if ($mode == 'employee' && empty($user->hasRight("salaries", "readall"))) { $sql .= " AND u.rowid IN (".$db->sanitize(join(',', $childids)).")"; } // Add where from extra fields @@ -658,7 +658,7 @@ $moreforfilter = ''; $moreforfilter.= '
';*/ // Filter on categories -if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) { +if (!empty($conf->categorie->enabled) && $user->hasRight("categorie", "read")) { $moreforfilter .= '
'; $tmptitle = $langs->trans('Category'); $moreforfilter .= img_picto($langs->trans("Category"), 'category', 'class="pictofixedwidth"').$formother->select_categories(Categorie::TYPE_USER, $search_categ, 'search_categ', 1, $tmptitle); @@ -939,9 +939,9 @@ while ($i < $imaxinloop) { $li = $object->getNomUrl(-1, '', 0, 0, 24, 1, 'login', '', 1); $canreadhrmdata = 0; - if ((!empty($conf->salaries->enabled) && !empty($user->rights->salaries->read) && in_array($obj->rowid, $childids)) - || (!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall)) - || (!empty($conf->hrm->enabled) && !empty($user->rights->hrm->employee->read))) { + if ((!empty($conf->salaries->enabled) && !empty($user->hasRight("salaries", "read")) && in_array($obj->rowid, $childids)) + || (!empty($conf->salaries->enabled) && !empty($user->hasRight("salaries", "readall"))) + || (!empty($conf->hrm->enabled) && !empty($user->hasRight("hrm", "employee", "read")))) { $canreadhrmdata = 1; } $canreadsecretapi = 0; diff --git a/htdocs/user/note.php b/htdocs/user/note.php index 2aeb496c20f..2b1e02b1376 100644 --- a/htdocs/user/note.php +++ b/htdocs/user/note.php @@ -39,7 +39,7 @@ $object->fetch($id, '', '', 1); $object->getrights(); // If user is not user read and no permission to read other users, we stop -if (($object->id != $user->id) && (!$user->rights->user->user->lire)) { +if (($object->id != $user->id) && (!$user->hasRight("user", "user", "read"))) { accessforbidden(); } @@ -48,7 +48,7 @@ $socid = 0; if ($user->socid > 0) { $socid = $user->socid; } -$feature2 = (($socid && $user->rights->user->self->creer) ? '' : 'user'); +$feature2 = (($socid && $user->hasRight("user", "self", "write")) ? '' : 'user'); $result = restrictedArea($user, 'user', $id, 'user&user', $feature2); @@ -67,7 +67,7 @@ if ($reshook < 0) { } if (empty($reshook)) { - if ($action == 'update' && $user->rights->user->user->creer && !GETPOST("cancel")) { + if ($action == 'update' && $user->hasRight("user", "user", "write") && !GETPOST("cancel")) { $db->begin(); $res = $object->update_note(dol_html_entity_decode(GETPOST('note_private', 'restricthtml'), ENT_QUOTES | ENT_HTML5)); @@ -99,7 +99,7 @@ if ($id) { $linkback = ''; - if ($user->rights->user->user->lire || $user->admin) { + if ($user->hasRight("user", "user", "read") || $user->admin) { $linkback = ''.$langs->trans("BackToList").''; } @@ -107,7 +107,7 @@ if ($id) { $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); $morehtmlref .= ''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); + dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; @@ -138,7 +138,7 @@ if ($id) { } print '
'.$langs->trans("Note").''; print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'lang'); print ''; print $form->selectarray($value, $elementList, (!empty($obj->{$value}) ? $obj->{$value}:'')); print ''; - print $form->selectarray($value, $elementList, (!empty($obj->{$value}) ? $obj->{$value}:'')); + print $form->selectarray($value, $tmparray, (!empty($obj->{$value}) ? $obj->{$value}:''), 0, 0, 0, '', 0, 0, 0, '', 'maxwidth250'); print '
'.$langs->trans("NoRecordFound").'
'.$langs->trans("NoRecordFound").'
'; if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { - print ' '; + print ' '; $htmltext = $langs->trans("ProjectFollowOpportunity"); print ''; print ''; print '
'; } if (empty($conf->global->PROJECT_HIDE_TASKS)) { - print ' '; + print ' '; $htmltext = $langs->trans("ProjectFollowTasks"); print ''; print '
'; } if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) { - print ' '; + print ' '; $htmltext = $langs->trans("ProjectBillTimeDescription"); print ''; print '
'; } if (!empty($conf->eventorganization->enabled)) { - print ' '; + print ' '; $htmltext = $langs->trans("EventOrganizationDescriptionLong"); print ''; } @@ -734,7 +738,7 @@ if ($action == 'create' && $user->rights->projet->creer) { print ''; - // Change probability from status + // Change probability from status or role of project print ''; print '
'; diff --git a/htdocs/public/project/suggestbooth.php b/htdocs/public/project/suggestbooth.php index cb1b1089b0c..52193e4fcd4 100644 --- a/htdocs/public/project/suggestbooth.php +++ b/htdocs/public/project/suggestbooth.php @@ -101,7 +101,7 @@ $extrafields = new ExtraFields($db); $user->loadDefaultValues(); $cactioncomm = new CActionComm($db); -$arrayofeventtype = $cactioncomm->liste_array('', 'id', '', 0, "module='booth@eventorganization'"); +$arrayofconfboothtype = $cactioncomm->liste_array('', 'id', '', 0, "module='booth@eventorganization'"); // Security check if (empty($conf->eventorganization->enabled)) { @@ -612,8 +612,8 @@ if (empty($conf->global->SOCIETE_DISABLE_STATE)) { print '
'.$langs->trans("EventType").'*'.FORM::selectarray('eventtype', $arrayofeventtype, $eventtype).'
'.$langs->trans("Format").'*'.Form::selectarray('eventtype', $arrayofconfboothtype, $eventtype, 1).'
'.$langs->trans("LabelOfBooth").'*
'.$langs->trans("EventType").'*'.FORM::selectarray('eventtype', $arrayofeventtype, $eventtype).'
'.$langs->trans("Format").'*'.Form::selectarray('eventtype', $arrayofconfboothtype, $eventtype, 1).'
'.$langs->trans("LabelOfconference").'*
'.price($obj->total_ht)."'.price($obj->total_ht)." 0 ? " disabled" : "").'> 0 ? " disabled" : "").'>'; print $langs->trans("DatabaseName").' : '.$dolibarr_main_db_name.'
'; print '
'; +print '
'; print ''; + print ''; print ''; print ''; + print ''; -print '
'; @@ -196,10 +197,11 @@ print ''; print '
'; -print '
'; -print ' '.$langs->trans("ShowAdvancedOptions").''; +print '
'; + +print ''; print ''; diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 3886651e8d5..078d485a5c9 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -543,6 +543,7 @@ fieldset { border: 1px solid #AAAAAA !important; padding-inline-start: 2em; padding-inline-end: 2em; + min-inline-size: auto; } .legendforfieldsetstep { padding-bottom: 10px; } input#onlinepaymenturl, input#directdownloadlink { diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 6e423228df1..ca485fb0d5f 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -725,6 +725,7 @@ fieldset { border: 1px solid #AAAAAA !important; padding-inline-start: 2em; padding-inline-end: 2em; + min-inline-size: auto; } .legendforfieldsetstep { padding-bottom: 10px; } input#onlinepaymenturl, input#directdownloadlink { From a509ec2c227cae48c8277e2455767107f87eb02e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 3 Aug 2022 18:31:55 +0200 Subject: [PATCH 194/205] Removed bad fields --- htdocs/install/mysql/migration/16.0.0-17.0.0.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/install/mysql/migration/16.0.0-17.0.0.sql b/htdocs/install/mysql/migration/16.0.0-17.0.0.sql index 597681c4ad5..e72fc1b8dcd 100644 --- a/htdocs/install/mysql/migration/16.0.0-17.0.0.sql +++ b/htdocs/install/mysql/migration/16.0.0-17.0.0.sql @@ -47,6 +47,9 @@ ALTER TABLE llx_expedition ADD COLUMN billed smallint DEFAULT 0; ALTER TABLE llx_accounting_system MODIFY COLUMN pcg_version varchar(32) NOT NULL; +ALTER TABLE llx_user DROP COLUMN idpers1; +ALTER TABLE llx_user DROP COLUMN idpers2; +ALTER TABLE llx_user DROP COLUMN idpers3; -- v17 From 3108cd12fb1eda63d7d18601cb61c9cf1d57ef9e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 3 Aug 2022 21:30:40 +0200 Subject: [PATCH 195/205] Fix export of website --- htdocs/core/modules/modWebsite.class.php | 15 ++++++++++++++- htdocs/website/class/website.class.php | 10 ++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/htdocs/core/modules/modWebsite.class.php b/htdocs/core/modules/modWebsite.class.php index e27e7a2f6b0..6e0dc80e41c 100644 --- a/htdocs/core/modules/modWebsite.class.php +++ b/htdocs/core/modules/modWebsite.class.php @@ -164,6 +164,8 @@ class modWebsite extends DolibarrModules { global $conf, $langs; + $error = 0; + $result = $this->_load_tables('/install/mysql/', 'website'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') @@ -185,11 +187,16 @@ class modWebsite extends DolibarrModules if ($result < 0) { $langs->load("errors"); $this->error = $langs->trans('ErrorFailToCopyDir', $src, $dest); - return 0; + $this->errors[] = $langs->trans('ErrorFailToCopyDir', $src, $dest); + $error++; } } } + if ($error) { + return 0; + } + // Website templates $srcroot = DOL_DOCUMENT_ROOT.'/install/doctemplates/websites'; $destroot = DOL_DATA_ROOT.'/doctemplates/websites'; @@ -205,9 +212,15 @@ class modWebsite extends DolibarrModules if ($result < 0) { $langs->load("errors"); $this->error = $langs->trans('ErrorFailToCopyFile', $src, $dest); + $this->errors[] = $langs->trans('ErrorFailToCopyFile', $src, $dest); + $error++; } } + if ($error) { + return 0; + } + $sql = array(); return $this->_init($sql, $options); diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index 0e062b038a0..aa405861e6a 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1059,29 +1059,35 @@ class Website extends CommonObject $line .= "'".$this->db->escape($objectpageold->grabbed_from)."', "; $line .= "'".$this->db->escape($objectpageold->type_container)."', "; + // Make substitution with a generic path into htmlheader content $stringtoexport = $objectpageold->htmlheader; $stringtoexport = str_replace(array("\r\n", "\r", "\n"), "__N__", $stringtoexport); $stringtoexport = str_replace('file=image/'.$website->ref.'/', "file=image/__WEBSITE_KEY__/", $stringtoexport); $stringtoexport = str_replace('file=js/'.$website->ref.'/', "file=js/__WEBSITE_KEY__/", $stringtoexport); $stringtoexport = str_replace('medias/image/'.$website->ref.'/', "medias/image/__WEBSITE_KEY__/", $stringtoexport); $stringtoexport = str_replace('medias/js/'.$website->ref.'/', "medias/js/__WEBSITE_KEY__/", $stringtoexport); + $stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo_small, "file=logos%2Fthumbs%2F__LOGO_SMALL_KEY__", $stringtoexport); $stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo_mini, "file=logos%2Fthumbs%2F__LOGO_MINI_KEY__", $stringtoexport); $stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo, "file=logos%2Fthumbs%2F__LOGO_KEY__", $stringtoexport); $line .= "'".$this->db->escape(str_replace(array("\r\n", "\r", "\n"), "__N__", $stringtoexport))."', "; // Replace \r \n to have record on 1 line + // Make substitution with a generic path into page content $stringtoexport = $objectpageold->content; $stringtoexport = str_replace(array("\r\n", "\r", "\n"), "__N__", $stringtoexport); $stringtoexport = str_replace('file=image/'.$website->ref.'/', "file=image/__WEBSITE_KEY__/", $stringtoexport); $stringtoexport = str_replace('file=js/'.$website->ref.'/', "file=js/__WEBSITE_KEY__/", $stringtoexport); $stringtoexport = str_replace('medias/image/'.$website->ref.'/', "medias/image/__WEBSITE_KEY__/", $stringtoexport); $stringtoexport = str_replace('medias/js/'.$website->ref.'/', "medias/js/__WEBSITE_KEY__/", $stringtoexport); + $stringtoexport = str_replace('"image/'.$website->ref.'/', '"image/__WEBSITE_KEY__/', $stringtoexport); // When we have a link src="image/websiteref/file.png" into html content + $stringtoexport = str_replace('"/image/'.$website->ref.'/', '"/image/__WEBSITE_KEY__/', $stringtoexport); // When we have a link src="/image/websiteref/file.png" into html content + $stringtoexport = str_replace('"js/'.$website->ref.'/', '"js/__WEBSITE_KEY__/', $stringtoexport); + $stringtoexport = str_replace('"/js/'.$website->ref.'/', '"/js/__WEBSITE_KEY__/', $stringtoexport); + $stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo_small, "file=logos%2Fthumbs%2F__LOGO_SMALL_KEY__", $stringtoexport); $stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo_mini, "file=logos%2Fthumbs%2F__LOGO_MINI_KEY__", $stringtoexport); $stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo, "file=logos%2Fthumbs%2F__LOGO_KEY__", $stringtoexport); - // When we have a link src="image/websiteref/file.png" into html content - $stringtoexport = str_replace('="image/'.$website->ref.'/', '="image/__WEBSITE_KEY__/', $stringtoexport); $line .= "'".$this->db->escape($stringtoexport)."', "; // Replace \r \n to have record on 1 line $line .= "'".$this->db->escape($objectpageold->author_alias)."', "; From f731fcc7d18727b4cc28fc49c412b79a6392dbd5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 3 Aug 2022 21:30:59 +0200 Subject: [PATCH 196/205] Use good format for image templates --- .../websites/website_template-style03.jpg | Bin 0 -> 96899 bytes .../websites/website_template-style03.png | Bin 101033 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 htdocs/install/doctemplates/websites/website_template-style03.jpg delete mode 100644 htdocs/install/doctemplates/websites/website_template-style03.png diff --git a/htdocs/install/doctemplates/websites/website_template-style03.jpg b/htdocs/install/doctemplates/websites/website_template-style03.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1479f08b5d9074d62566bde6922a6b74fa49ab64 GIT binary patch literal 96899 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 T>%|y*8c18fAAsq@KOg@e9)D$= literal 0 HcmV?d00001 diff --git a/htdocs/install/doctemplates/websites/website_template-style03.png b/htdocs/install/doctemplates/websites/website_template-style03.png deleted file mode 100644 index 7732f9f3c18a35ea96d0aaf8fd17e025ca60a189..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101033 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 d;yVj%i|%V~D7$I0(R*Ph{vSjX1dIRx From a60a8d5057568f12950fe5b290b1772941f9875e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Aug 2022 00:10:18 +0200 Subject: [PATCH 197/205] sql error --- htdocs/fourn/facture/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index ce3ad5b708e..0a54792c665 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -635,7 +635,7 @@ if (!$search_all) { $sql .= ' f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc,'; $sql .= " f.note_public, f.note_private,"; $sql .= " f.fk_user_author,"; - $sql .= ' s.rowid, s.nom, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,'; + $sql .= ' s.rowid, s.nom, s.name_alias, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,'; $sql .= " typent.code,"; $sql .= " state.code_departement, state.nom,"; $sql .= ' country.code,'; From fb173da0f3669859cff0e9c4461390e2faad57f7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Aug 2022 11:14:21 +0200 Subject: [PATCH 198/205] css --- htdocs/user/ldap.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/user/ldap.php b/htdocs/user/ldap.php index 8a8ca28092e..01be4fdcbae 100644 --- a/htdocs/user/ldap.php +++ b/htdocs/user/ldap.php @@ -97,7 +97,7 @@ llxHeader('', $title, $help_url); $head = user_prepare_head($object); $title = $langs->trans("User"); -print dol_get_fiche_head($head, 'ldap', $title, 0, 'user'); +print dol_get_fiche_head($head, 'ldap', $title, -1, 'user'); $linkback = ''; @@ -110,7 +110,7 @@ dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $use print '
'; print '
'; -print ''; +print '
'; // Login print ''; From 92d4cb84a0cbd1b65308caaf72e5643832ae46d7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Aug 2022 13:13:24 +0200 Subject: [PATCH 199/205] css --- htdocs/emailcollector/class/emailcollector.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index ecd32d2cefc..e3957637dd0 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -111,7 +111,7 @@ class EmailCollector extends CommonObject public $fields = array( 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'visible'=>2, 'enabled'=>1, 'position'=>1, 'notnull'=>1, 'index'=>1), 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'default'=>1, 'notnull'=>1, 'index'=>1, 'position'=>20), - 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'help'=>'Example: MyCollector1', 'csslist'=>'tdoverflowmax250'), + 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'help'=>'Example: MyCollector1', 'csslist'=>'tdoverflowmax150'), 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'visible'=>1, 'enabled'=>1, 'position'=>30, 'notnull'=>-1, 'searchall'=>1, 'help'=>'Example: My Email collector', 'csslist'=>'tdoverflowmax150'), 'description' => array('type'=>'text', 'label'=>'Description', 'visible'=>-1, 'enabled'=>1, 'position'=>60, 'notnull'=>-1, 'csslist'=>'small'), 'host' => array('type'=>'varchar(255)', 'label'=>'EMailHost', 'visible'=>1, 'enabled'=>1, 'position'=>90, 'notnull'=>1, 'searchall'=>1, 'comment'=>"IMAP server", 'help'=>'Example: imap.gmail.com', 'csslist'=>'tdoverflow125'), From 8570fe597366744b7dcc7d91fa288b3576846f43 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Aug 2022 13:19:24 +0200 Subject: [PATCH 200/205] css --- htdocs/emailcollector/class/emailcollector.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index e3957637dd0..4f95a44652e 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -111,13 +111,13 @@ class EmailCollector extends CommonObject public $fields = array( 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'visible'=>2, 'enabled'=>1, 'position'=>1, 'notnull'=>1, 'index'=>1), 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'default'=>1, 'notnull'=>1, 'index'=>1, 'position'=>20), - 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'help'=>'Example: MyCollector1', 'csslist'=>'tdoverflowmax150'), + 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'help'=>'Example: MyCollector1', 'csslist'=>'tdoverflowmax200'), 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'visible'=>1, 'enabled'=>1, 'position'=>30, 'notnull'=>-1, 'searchall'=>1, 'help'=>'Example: My Email collector', 'csslist'=>'tdoverflowmax150'), 'description' => array('type'=>'text', 'label'=>'Description', 'visible'=>-1, 'enabled'=>1, 'position'=>60, 'notnull'=>-1, 'csslist'=>'small'), 'host' => array('type'=>'varchar(255)', 'label'=>'EMailHost', 'visible'=>1, 'enabled'=>1, 'position'=>90, 'notnull'=>1, 'searchall'=>1, 'comment'=>"IMAP server", 'help'=>'Example: imap.gmail.com', 'csslist'=>'tdoverflow125'), 'port' => array('type'=>'varchar(10)', 'label'=>'EMailHostPort', 'visible'=>1, 'enabled'=>1, 'position'=>91, 'notnull'=>1, 'searchall'=>0, 'comment'=>"IMAP server port", 'help'=>'Example: 993', 'csslist'=>'tdoverflow125', 'default'=>'993'), 'hostcharset' => array('type'=>'varchar(16)', 'label'=>'HostCharset', 'visible'=>-1, 'enabled'=>1, 'position'=>92, 'notnull'=>0, 'searchall'=>0, 'comment'=>"IMAP server charset", 'help'=>'Example: "UTF-8" (May be "US-ASCII" with some Office365)', 'default'=>'UTF-8'), - 'login' => array('type'=>'varchar(128)', 'label'=>'Login', 'visible'=>1, 'enabled'=>1, 'position'=>101, 'notnull'=>-1, 'index'=>1, 'comment'=>"IMAP login", 'help'=>'Example: myaccount@gmail.com'), + 'login' => array('type'=>'varchar(128)', 'label'=>'Login', 'visible'=>-1, 'enabled'=>1, 'position'=>101, 'notnull'=>-1, 'index'=>1, 'comment'=>"IMAP login", 'help'=>'Example: myaccount@gmail.com'), 'password' => array('type'=>'password', 'label'=>'Password', 'visible'=>-1, 'enabled'=>1, 'position'=>102, 'notnull'=>-1, 'comment'=>"IMAP password", 'help'=>'WithGMailYouCanCreateADedicatedPassword'), 'source_directory' => array('type'=>'varchar(255)', 'label'=>'MailboxSourceDirectory', 'visible'=>-1, 'enabled'=>1, 'position'=>103, 'notnull'=>1, 'default' => 'Inbox', 'help'=>'Example: INBOX'), //'filter' => array('type'=>'text', 'label'=>'Filter', 'visible'=>1, 'enabled'=>1, 'position'=>105), From a7a1c70c654de796be867ad9231ac772051837ea Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Aug 2022 13:42:57 +0200 Subject: [PATCH 201/205] FIX Scan IMAP must not be done automatically --- htdocs/admin/emailcollector_card.php | 86 +++++++++++++++------------- 1 file changed, 45 insertions(+), 41 deletions(-) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index ab4f0c7def0..2a32551eaad 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -378,33 +378,54 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $connectstringserver = $object->getConnectStringIMAP($usessl); - try { - if ($sourcedir) { - //$connectstringsource = $connectstringserver.imap_utf7_encode($sourcedir); - $connectstringsource = $connectstringserver.$object->getEncodedUtf7($sourcedir); - } - if ($targetdir) { - //$connectstringtarget = $connectstringserver.imap_utf7_encode($targetdir); - $connectstringtarget = $connectstringserver.$object->getEncodedUtf7($targetdir); + if ($action == 'scan') { + try { + if ($sourcedir) { + //$connectstringsource = $connectstringserver.imap_utf7_encode($sourcedir); + $connectstringsource = $connectstringserver.$object->getEncodedUtf7($sourcedir); + } + if ($targetdir) { + //$connectstringtarget = $connectstringserver.imap_utf7_encode($targetdir); + $connectstringtarget = $connectstringserver.$object->getEncodedUtf7($targetdir); + } + + $timeoutconnect = empty($conf->global->MAIN_USE_CONNECT_TIMEOUT) ? 5 : $conf->global->MAIN_USE_CONNECT_TIMEOUT; + $timeoutread = empty($conf->global->MAIN_USE_RESPONSE_TIMEOUT) ? 20 : $conf->global->MAIN_USE_RESPONSE_TIMEOUT; + + dol_syslog("imap_open connectstring=".$connectstringsource." login=".$object->login." password=".$object->password." timeoutconnect=".$timeoutconnect." timeoutread=".$timeoutread); + + $result1 = imap_timeout(IMAP_OPENTIMEOUT, $timeoutconnect); // timeout seems ignored with ssl connect + $result2 = imap_timeout(IMAP_READTIMEOUT, $timeoutread); + $result3 = imap_timeout(IMAP_WRITETIMEOUT, 5); + $result4 = imap_timeout(IMAP_CLOSETIMEOUT, 5); + + dol_syslog("result1=".$result1." result2=".$result2." result3=".$result3." result4=".$result4); + + $connection = imap_open($connectstringsource, $object->login, $object->password); + + //dol_syslog("end imap_open connection=".var_export($connection, true)); + } catch (Exception $e) { + print $e->getMessage(); } - $timeoutconnect = empty($conf->global->MAIN_USE_CONNECT_TIMEOUT) ? 5 : $conf->global->MAIN_USE_CONNECT_TIMEOUT; - $timeoutread = empty($conf->global->MAIN_USE_RESPONSE_TIMEOUT) ? 20 : $conf->global->MAIN_USE_RESPONSE_TIMEOUT; + if (!$connection) { + $morehtml .= 'Failed to open IMAP connection '.$connectstringsource; + if (function_exists('imap_last_error')) { + $morehtml .= '
'.imap_last_error(); + } + dol_syslog("Error ".$morehtml, LOG_WARNING); + //var_dump(imap_errors()) + } else { + dol_syslog("Imap connected. Now we call imap_num_msg()"); + $morehtml .= imap_num_msg($connection); + } - dol_syslog("imap_open connectstring=".$connectstringsource." login=".$object->login." password=".$object->password." timeoutconnect=".$timeoutconnect." timeoutread=".$timeoutread); - - $result1 = imap_timeout(IMAP_OPENTIMEOUT, $timeoutconnect); // timeout seems ignored with ssl connect - $result2 = imap_timeout(IMAP_READTIMEOUT, $timeoutread); - $result3 = imap_timeout(IMAP_WRITETIMEOUT, 5); - $result4 = imap_timeout(IMAP_CLOSETIMEOUT, 5); - - dol_syslog("result1=".$result1." result2=".$result2." result3=".$result3." result4=".$result4); - - $connection = imap_open($connectstringsource, $object->login, $object->password); - - //dol_syslog("end imap_open connection=".var_export($connection, true)); - } catch (Exception $e) { - print $e->getMessage(); + if ($connection) { + dol_syslog("Imap close"); + imap_close($connection); + } + } else { + $morehtml .= ''.img_picto('', 'refresh', 'class="paddingrightonly"').$langs->trans("Refresh").''; } $morehtml .= $form->textwithpicto('', 'connect string '.$connectstringserver); @@ -412,23 +433,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $morehtml .= 'IMAP functions not available on your PHP. '; } - if (!$connection) { - $morehtml .= 'Failed to open IMAP connection '.$connectstringsource; - if (function_exists('imap_last_error')) { - $morehtml .= '
'.imap_last_error(); - } - dol_syslog("Error ".$morehtml, LOG_WARNING); - //var_dump(imap_errors()) - } else { - dol_syslog("Imap connected. Now we call imap_num_msg()"); - $morehtml .= imap_num_msg($connection); - } - - if ($connection) { - dol_syslog("Imap close"); - imap_close($connection); - } - dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref.'
'.$morehtml.'
', '', 0, '', '', 0, ''); print '
'; From 1093084e9b349069a8e0f594d9a9d7308195fc63 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Aug 2022 14:00:04 +0200 Subject: [PATCH 202/205] Better doc --- htdocs/admin/emailcollector_card.php | 6 +++--- htdocs/langs/en_US/admin.lang | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index 2a32551eaad..bc8267f9ef9 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -584,11 +584,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
'; print ''; print ''; print ''; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 6ca93dc7788..149668e34a7 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2108,7 +2108,7 @@ CreateCandidature=Create job application FormatZip=Zip MainMenuCode=Menu entry code (mainmenu) ECMAutoTree=Show automatic ECM tree -OperationParamDesc=Define the rules to use to extract or set values.
Example for operations that need to extract a name from email subject:
name=EXTRACT:SUBJECT:Message from company ([^\n]*)
Example for operations that create objects:
objproperty1=SET:the value to set
objproperty2=SET:a value including value of __objproperty1__
objproperty3=SETIFEMPTY:value used if objproperty3 is not already defined
objproperty4=EXTRACT:HEADER:X-Myheaderkey:\s*([^\s]*)
options_myextrafield1=EXTRACT:SUBJECT:([^\n]*)
object.objproperty5=EXTRACT:BODY:My company name is\s([^\s]*)

Use a ; char as separator to extract or set several properties. +OperationParamDesc=Define the rules to use to extract some data or set values to use for operation.

Example to extract a company name from email subject into a temporary variable:
tmp_var=EXTRACT:SUBJECT:Message from company ([^\n]*)

Examples to set the properties of an object to create:
objproperty1=SET:a hard coded value
objproperty2=SET:__tmp_var__
objproperty3=SETIFEMPTY:a value (value is set only if property is not already defined)
objproperty4=EXTRACT:HEADER:X-Myheaderkey:\s*([^\s]*)
options_myextrafield1=EXTRACT:SUBJECT:([^\n]*)
object.objproperty5=EXTRACT:BODY:My company name is\s([^\s]*)

Use a ; char as separator to extract or set several properties. OpeningHours=Opening hours OpeningHoursDesc=Enter here the regular opening hours of your company. ResourceSetup=Configuration of Resource module From 4a9c9a97e503b8e846f1c19352718bc47003c15e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Aug 2022 15:58:00 +0200 Subject: [PATCH 203/205] WIP Implement a generic handler for OAuth. --- htdocs/admin/oauth.php | 61 +++++- htdocs/admin/oauthlogintokens.php | 71 ++++--- htdocs/core/lib/oauth.lib.php | 29 ++- .../modules/oauth/generic_oauthcallback.php | 193 ++++++++++++++++++ .../modules/oauth/github_oauthcallback.php | 4 +- .../modules/oauth/google_oauthcallback.php | 2 +- .../oauth/stripelive_oauthcallback.php | 2 +- .../oauth/stripetest_oauthcallback.php | 2 +- htdocs/langs/en_US/oauth.lang | 7 +- 9 files changed, 320 insertions(+), 51 deletions(-) create mode 100644 htdocs/core/modules/oauth/generic_oauthcallback.php diff --git a/htdocs/admin/oauth.php b/htdocs/admin/oauth.php index 772055f0809..ade561c4ef1 100644 --- a/htdocs/admin/oauth.php +++ b/htdocs/admin/oauth.php @@ -62,7 +62,7 @@ if ($action == 'add') { // $provider is OAUTH_XXX setEventMessages($langs->trans("AOAuthEntryForThisProviderAndLabelAlreadyHasAKey"), null, 'errors'); $error++; } else { - dolibarr_set_const($db, $constname, 'ToComplete', 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, $constname, $langs->trans('ToComplete'), 'chaine', 0, '', $conf->entity); setEventMessages($langs->trans("OAuthProviderAdded"), null); } } @@ -78,6 +78,16 @@ if ($action == 'update') { if (!dolibarr_set_const($db, $constvalue.'_SECRET', GETPOST($constvalue.'_ID') ? GETPOST($constvalue.'_SECRET') : '', 'chaine', 0, '', $conf->entity)) { $error++; } + if (GETPOSTISSET($constvalue.'_URLAUTHORIZE')) { + if (!dolibarr_set_const($db, $constvalue.'_URLAUTHORIZE', GETPOST($constvalue.'_URLAUTHORIZE'), 'chaine', 0, '', $conf->entity)) { + $error++; + } + } + if (GETPOSTISSET($constvalue.'_SCOPE')) { + if (!dolibarr_set_const($db, $constvalue.'_SCOPE', GETPOST($constvalue.'_SCOPE'), 'chaine', 0, '', $conf->entity)) { + $error++; + } + } } } @@ -147,11 +157,17 @@ print '
'.$langs->trans("Login").''; print $form->selectarray('operationtype', $arrayoftypes, '', 1, 0, 0, '', 1, 0, 0, '', 'maxwidth300', 1); print ''; - print ''; + //print ''; + $htmltext = $langs->transnoentitiesnoconv("OperationParamDesc"); + print $form->textwithpicto('', $htmltext, 1, 'help', '', 0, 2, 'operationparamtt'); print ''; - $htmltext = $langs->transnoentitiesnoconv("OperationParamDesc"); - print $form->textwithpicto('', $htmltext, 1, 'help', '', 0, 2, 'operationparamtt'); print '
'; $i = 0; -//var_dump($list); +// Define $listinsetup foreach ($conf->global as $key => $val) { if (!empty($val) && preg_match('/^OAUTH_.*_ID$/', $key)) { $provider = preg_replace('/_ID$/', '', $key); - $listinsetup[] = array($provider.'_NAME', $provider.'_ID', $provider.'_SECRET', 'OAUTH Provider '.str_replace('OAUTH_', '', $provider)); + $listinsetup[] = array( + $provider.'_NAME', + $provider.'_ID', + $provider.'_SECRET', + $provider.'_URLAUTHORIZE', // For custom oauth links + $provider.'_SCOPE' // For custom oauth links + ); } } @@ -178,12 +194,16 @@ foreach ($listinsetup as $key) { $i++; - print ''; // Api Name $label = $langs->trans($keyforsupportedoauth2array); + print ''; print ''; print ''; - print ''; + + if ($keyforsupportedoauth2array == 'OAUTH_OTHER_NAME') { + print ''; + print ''; + print ''; + } } else { print ''; print ''; @@ -213,14 +240,32 @@ foreach ($listinsetup as $key) { // Api Id print ''; print ''; - print ''; // Api Secret print ''; print ''; - print ''; + + // TODO Move this into token generation + if ($supported) { + if ($keyforsupportedoauth2array == 'OAUTH_OTHER_NAME') { + print ''; + print ''; + print ''; + } else { + print ''; + print ''; + print ''; + } + } } print '
'; print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"'); - print $label; + if ($label == $keyforsupportedoauth2array) { + print $supportedoauth2array[$keyforsupportedoauth2array]['name']; + } else { + print $label; + } if ($keyforprovider) { print ' ('.$keyforprovider.')'; } else { @@ -201,8 +221,15 @@ foreach ($listinsetup as $key) { $redirect_uri = $urlwithroot.'/core/modules/oauth/'.$supportedoauth2array[$keyforsupportedoauth2array]['callbackfile'].'_oauthcallback.php'; print '
'.$langs->trans("UseTheFollowingUrlAsRedirectURI").''; + print ''; print '
'.$langs->trans("URLOfServiceForAuthorization").''; + print '
'.$langs->trans("UseTheFollowingUrlAsRedirectURI").'
'; + print ''; print '
'; + print ''; print '
'.$langs->trans("Scopes").''; + print ''; + print '
'.$langs->trans("Scopes").''; + //print ''; + print $supportedoauth2array[$keyforsupportedoauth2array]['defaultscope']; + print '
'."\n"; diff --git a/htdocs/admin/oauthlogintokens.php b/htdocs/admin/oauthlogintokens.php index b2830f95743..00daaf01e27 100644 --- a/htdocs/admin/oauthlogintokens.php +++ b/htdocs/admin/oauthlogintokens.php @@ -138,11 +138,17 @@ if (GETPOST('error')) { if ($mode == 'setup' && $user->admin) { print ''.$langs->trans("OAuthSetupForLogin")."

\n"; - //var_dump($list); + // Define $listinsetup foreach ($conf->global as $key => $val) { if (!empty($val) && preg_match('/^OAUTH_.*_ID$/', $key)) { $provider = preg_replace('/_ID$/', '', $key); - $listinsetup[] = array($provider.'_NAME', $provider.'_ID', $provider.'_SECRET', 'OAUTH Provider '.str_replace('OAUTH_', '', $provider)); + $listinsetup[] = array( + $provider.'_NAME', + $provider.'_ID', + $provider.'_SECRET', + $provider.'_URLAUTHORIZE', // For custom oauth links + $provider.'_SCOPE' // For custom oauth links + ); } } @@ -165,46 +171,39 @@ if ($mode == 'setup' && $user->admin) { $OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : '')); - // Define $shortscope, $urltorenew, $urltodelete, $urltocheckperms + $shortscope = $supportedoauth2array[$keyforsupportedoauth2array]['defaultscope']; + if (getDolGlobalString($key[4])) { + $shortscope = getDolGlobalString($key[4]); + } + $state = $shortscope; // TODO USe a better state + + // Define $urltorenew, $urltodelete, $urltocheckperms // TODO Use array $supportedoauth2array if ($keyforsupportedoauth2array == 'OAUTH_GITHUB_NAME') { // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service). // We pass this param list in to 'state' because we need it before and after the redirect. - $shortscope = 'user,public_repo'; - // Note: github does not accept csrf key inside the state parameter (only know values) - $urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); + // Note: github does not accept csrf key inside the state parameter (only known values) + $urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltocheckperms = 'https://github.com/settings/applications/'; } elseif ($keyforsupportedoauth2array == 'OAUTH_GOOGLE_NAME') { // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service). // List of scopes for Google are here: https://developers.google.com/identity/protocols/oauth2/scopes // We pass this key list into the param 'state' because we need it before and after the redirect. - $shortscope = 'userinfo_email,userinfo_profile'; - $shortscope .= ',openid,email,profile'; // For openid connect - if (!empty($conf->printing->enabled)) { - $shortscope .= ',cloud_print'; - } - if (!empty($conf->global->OAUTH_GOOGLE_GSUITE)) { - $shortscope .= ',admin_directory_user'; - } - if (!empty($conf->global->OAUTH_GOOGLE_GMAIL)) { - $shortscope.=',gmail_full'; - } - - $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); + $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltocheckperms = 'https://security.google.com/settings/security/permissions'; } elseif ($keyforsupportedoauth2array == 'OAUTH_STRIPE_TEST_NAME') { - $shortscope = 'none'; - - $urltorenew = $urlwithroot.'/core/modules/oauth/stripetest_oauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); + $urltorenew = $urlwithroot.'/core/modules/oauth/stripetest_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = ''; $urltocheckperms = ''; } elseif ($keyforsupportedoauth2array == 'OAUTH_STRIPE_LIVE_NAME') { - $shortscope = 'none'; - - $urltorenew = $urlwithroot.'/core/modules/oauth/stripelive_oauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); + $urltorenew = $urlwithroot.'/core/modules/oauth/stripelive_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); + $urltodelete = ''; + $urltocheckperms = ''; + } elseif ($keyforsupportedoauth2array = 'OAUTH_OTHER_NAME') { + $urltorenew = $urlwithroot.'/core/modules/oauth/generic_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = ''; $urltocheckperms = ''; } else { @@ -212,7 +211,8 @@ if ($mode == 'setup' && $user->admin) { $urltodelete = ''; $urltocheckperms = ''; } - $urltorenew .= '&keyforprovider='.$keyforprovider; + + $urltorenew .= '&keyforprovider='.urlencode($keyforprovider); // Show value of token $tokenobj = null; @@ -246,7 +246,7 @@ if ($mode == 'setup' && $user->admin) { } elseif ($endoflife == $tokenobj::EOL_UNKNOWN) { $expiredat = $langs->trans("Unknown"); } else { - $expiredat = dol_print_date($endoflife, "dayhour"); + $expiredat = dol_print_date($endoflife, "dayhour", 'tzuserrel'); } } } @@ -260,10 +260,16 @@ if ($mode == 'setup' && $user->admin) { print '
'; print ''."\n"; + // Api Name + $label = $langs->trans($keyforsupportedoauth2array); print ''; print '
'; print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"'); - print $langs->trans($keyforsupportedoauth2array); + if ($label == $keyforsupportedoauth2array) { + print $supportedoauth2array[$keyforsupportedoauth2array]['name']; + } else { + print $label; + } if ($keyforprovider) { print ' ('.$keyforprovider.')'; } else { @@ -292,7 +298,8 @@ if ($mode == 'setup' && $user->admin) { print ''; print ''; if (is_object($tokenobj)) { - print $langs->trans("HasAccessToken"); + // TODO Read in database to get the date of creation of token + print $form->textwithpicto(yn(1), $langs->trans("HasAccessToken").' : '); } else { print ''.$langs->trans("NoAccessToken").''; } @@ -305,7 +312,9 @@ if ($mode == 'setup' && $user->admin) { } // Request remote token if ($urltorenew) { - print ''.$langs->trans('RequestAccess').'
'; + print ''.$langs->trans('GetAccess').''; + print $form->textwithpicto('', $langs->trans('RequestAccess')); + print '
'; } // Check remote access if ($urltocheckperms) { @@ -378,8 +387,8 @@ if ($mode == 'setup' && $user->admin) { } } - print ''; + print '
'; } } diff --git a/htdocs/core/lib/oauth.lib.php b/htdocs/core/lib/oauth.lib.php index f99266db178..bacd8135739 100644 --- a/htdocs/core/lib/oauth.lib.php +++ b/htdocs/core/lib/oauth.lib.php @@ -23,16 +23,30 @@ */ +$shortscopegoogle = 'userinfo_email,userinfo_profile'; +$shortscopegoogle .= ',openid,email,profile'; // For openid connect +if (!empty($conf->printing->enabled)) { + $shortscopegoogle .= ',cloud_print'; +} +if (!empty($conf->global->OAUTH_GOOGLE_GSUITE)) { + $shortscopegoogle .= ',admin_directory_user'; +} +if (!empty($conf->global->OAUTH_GOOGLE_GMAIL)) { + $shortscopegoogle.=',gmail_full'; +} + // Supported OAUTH (a provider is supported when a file xxx_oauthcallback.php is available into htdocs/core/modules/oauth) $supportedoauth2array = array( - 'OAUTH_GOOGLE_NAME'=>array('callbackfile' => 'google', 'picto' => 'google', 'urlforapp' => 'OAUTH_GOOGLE_DESC', 'name'=>'Google', 'urlforcredentials'=>'https://console.developers.google.com/'), + 'OAUTH_GOOGLE_NAME'=>array('callbackfile' => 'google', 'picto' => 'google', 'urlforapp' => 'OAUTH_GOOGLE_DESC', 'name'=>'Google', 'urlforcredentials'=>'https://console.developers.google.com/', 'defaultscope'=>$shortscopegoogle), ); if (!empty($conf->stripe->enabled)) { - $supportedoauth2array['OAUTH_STRIPE_TEST_NAME'] = array('callbackfile' => 'stripetest', 'picto' => 'stripe', 'urlforapp' => '', 'name'=>'StripeTest', 'urlforcredentials'=>''); - $supportedoauth2array['OAUTH_STRIPE_LIVE_NAME'] = array('callbackfile' => 'stripelive', 'picto' => 'stripe', 'urlforapp' => '', 'name'=>'StripeLive', 'urlforcredentials'=>''); + $supportedoauth2array['OAUTH_STRIPE_TEST_NAME'] = array('callbackfile' => 'stripetest', 'picto' => 'stripe', 'urlforapp' => '', 'name'=>'StripeTest', 'urlforcredentials'=>'', 'defaultscope'=>'read_write'); + $supportedoauth2array['OAUTH_STRIPE_LIVE_NAME'] = array('callbackfile' => 'stripelive', 'picto' => 'stripe', 'urlforapp' => '', 'name'=>'StripeLive', 'urlforcredentials'=>'', 'defaultscope'=>'read_write'); +} +$supportedoauth2array['OAUTH_GITHUB_NAME'] = array('callbackfile' => 'github', 'picto' => 'github', 'urlforapp' => 'OAUTH_GITHUB_DESC', 'name'=>'GitHub', 'urlforcredentials'=>'https://github.com/settings/developers', 'defaultscope'=>'user,public_repo'); +if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { + $supportedoauth2array['OAUTH_OTHER_NAME'] = array('callbackfile' => 'generic', 'picto' => 'generic', 'urlforapp' => 'OAUTH_OTHER_DESC', 'name'=>'Other', 'urlforcredentials'=>'', 'defaultscope'=>'ToComplete'); } -$supportedoauth2array['OAUTH_GITHUB_NAME'] = array('callbackfile' => 'github', 'picto' => 'github', 'urlforapp' => 'OAUTH_GITHUB_DESC', 'name'=>'GitHub', 'urlforcredentials'=>'https://github.com/settings/developers'); - // API access parameters OAUTH @@ -259,6 +273,11 @@ $list = array( 'OAUTH_YAMMER_ID', 'OAUTH_YAMMER_SECRET', ), + array( + 'OAUTH_OTHER_NAME', + 'OAUTH_OTHER_ID', + 'OAUTH_OTHER_SECRET', + ), ); diff --git a/htdocs/core/modules/oauth/generic_oauthcallback.php b/htdocs/core/modules/oauth/generic_oauthcallback.php new file mode 100644 index 00000000000..9d66bb07302 --- /dev/null +++ b/htdocs/core/modules/oauth/generic_oauthcallback.php @@ -0,0 +1,193 @@ + + * Copyright (C) 2015 Frederic France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/modules/oauth/generic_oauthcallback.php + * \ingroup oauth + * \brief Page to get oauth callback + */ + +require '../../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php'; +use OAuth\Common\Storage\DoliStorage; +use OAuth\Common\Consumer\Credentials; +use OAuth\OAuth2\Service\GitHub; + +// Define $urlwithroot +$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); +$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file +//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + + +$action = GETPOST('action', 'aZ09'); +$backtourl = GETPOST('backtourl', 'alpha'); +$keyforprovider = GETPOST('keyforprovider', 'aZ09'); +if (empty($keyforprovider) && !empty($_SESSION["oauthkeyforproviderbeforeoauthjump"]) && (GETPOST('code') || $action == 'delete')) { + $keyforprovider = $_SESSION["oauthkeyforproviderbeforeoauthjump"]; +} +$genericstring = 'OTHER'; + + +/** + * Create a new instance of the URI class with the current URI, stripping the query string + */ +$uriFactory = new \OAuth\Common\Http\Uri\UriFactory(); +//$currentUri = $uriFactory->createFromSuperGlobalArray($_SERVER); +//$currentUri->setQuery(''); +$currentUri = $uriFactory->createFromAbsolute($urlwithroot.'/core/modules/oauth/generic_oauthcallback.php'); + + +/** + * Load the credential for the service + */ + +/** @var $serviceFactory \OAuth\ServiceFactory An OAuth service factory. */ +$serviceFactory = new \OAuth\ServiceFactory(); +$httpClient = new \OAuth\Common\Http\Client\CurlClient(); +// TODO Set options for proxy and timeout +// $params=array('CURLXXX'=>value, ...) +//$httpClient->setCurlParameters($params); +$serviceFactory->setHttpClient($httpClient); + +// Dolibarr storage +$storage = new DoliStorage($db, $conf); + +// Setup the credentials for the requests +$keyforparamid = 'OAUTH_'.$genericstring.($keyforprovider ? '-'.$keyforprovider : '').'_ID'; +$keyforparamsecret = 'OAUTH_'.$genericstring.($keyforprovider ? '-'.$keyforprovider : '').'_SECRET'; +$credentials = new Credentials( + getDolGlobalString($keyforparamid), + getDolGlobalString($keyforparamsecret), + $currentUri->getAbsoluteUri() +); + +$requestedpermissionsarray = array(); +if (GETPOST('state')) { + $requestedpermissionsarray = explode(',', GETPOST('state')); // Example: 'user'. 'state' parameter is standard to retrieve some parameters back +} +if ($action != 'delete' && empty($requestedpermissionsarray)) { + print 'Error, parameter state is not defined'; + exit; +} +//var_dump($requestedpermissionsarray);exit; + +// Instantiate the Api service using the credentials, http client and storage mechanism for the token +$apiService = $serviceFactory->createService($genericstring, $credentials, $storage, $requestedpermissionsarray); + +/* +var_dump($genericstring.($keyforprovider ? '-'.$keyforprovider : '')); +var_dump($credentials); +var_dump($storage); +var_dump($requestedpermissionsarray); +*/ + +if (empty($apiService)) { + print 'Error, failed to create serviceFactory'; + exit; +} + +// access type needed to have oauth provider refreshing token +//$apiService->setAccessType('offline'); + +$langs->load("oauth"); + +if (!getDolGlobalString($keyforparamid)) { + accessforbidden('Setup of service is not complete. Customer ID is missing'); +} +if (!getDolGlobalString($keyforparamsecret)) { + accessforbidden('Setup of service is not complete. Secret key is missing'); +} + + +/* + * Actions + */ + +if ($action == 'delete') { + $storage->clearToken($genericstring); + + setEventMessages($langs->trans('TokenDeleted'), null, 'mesgs'); + + header('Location: '.$backtourl); + exit(); +} + +if (GETPOST('code')) { // We are coming from oauth provider page + // We should have + //$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16)) + + dol_syslog("We are coming from the oauth provider page"); + //llxHeader('',$langs->trans("OAuthSetup")); + + //$linkback=''.$langs->trans("BackToModuleList").''; + //print load_fiche_titre($langs->trans("OAuthSetup"),$linkback,'title_setup'); + + //print dol_get_fiche_head(); + // retrieve the CSRF state parameter + $state = GETPOSTISSET('state') ? GETPOST('state') : null; + //print ''; + + // This was a callback request from service, get the token + try { + //var_dump($_GET['code']); + //var_dump($state); + //var_dump($apiService); // OAuth\OAuth2\Service\GitHub + + //$token = $apiService->requestAccessToken(GETPOST('code'), $state); + $token = $apiService->requestAccessToken(GETPOST('code')); + // Github is a service that does not need state to be stored. + // Into constructor of GitHub, the call + // parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri) + // has not the ending parameter to true like the Google class constructor. + + setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token + + $backtourl = $_SESSION["backtourlsavedbeforeoauthjump"]; + unset($_SESSION["backtourlsavedbeforeoauthjump"]); + + header('Location: '.$backtourl); + exit(); + } catch (Exception $e) { + print $e->getMessage(); + } +} else { // If entry on page with no parameter, we arrive here + $_SESSION["backtourlsavedbeforeoauthjump"] = $backtourl; + $_SESSION["oauthkeyforproviderbeforeoauthjump"] = $keyforprovider; + $_SESSION['oauthstateanticsrf'] = $state; + + // This may create record into oauth_state before the header redirect. + // Creation of record with state in this tables depend on the Provider used (see its constructor). + if (GETPOST('state')) { + $url = $apiService->getAuthorizationUri(array('state' => GETPOST('state'))); + } else { + $url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated + } + + // we go on oauth provider authorization page + header('Location: '.$url); + exit(); +} + + +/* + * View + */ + +// No view at all, just actions + +$db->close(); diff --git a/htdocs/core/modules/oauth/github_oauthcallback.php b/htdocs/core/modules/oauth/github_oauthcallback.php index 5c24e23aafa..f496c42d0ac 100644 --- a/htdocs/core/modules/oauth/github_oauthcallback.php +++ b/htdocs/core/modules/oauth/github_oauthcallback.php @@ -1,5 +1,5 @@ * Copyright (C) 2015 Frederic France * * This program is free software; you can redistribute it and/or modify @@ -86,7 +86,7 @@ if ($action != 'delete' && empty($requestedpermissionsarray)) { //var_dump($requestedpermissionsarray);exit; // Instantiate the Api service using the credentials, http client and storage mechanism for the token -$apiService = $serviceFactory->createService('GitHub'.($keyforprovider ? '-'.$keyforprovider : ''), $credentials, $storage, $requestedpermissionsarray); +$apiService = $serviceFactory->createService('GitHub', $credentials, $storage, $requestedpermissionsarray); // access type needed to have oauth provider refreshing token //$apiService->setAccessType('offline'); diff --git a/htdocs/core/modules/oauth/google_oauthcallback.php b/htdocs/core/modules/oauth/google_oauthcallback.php index 2812c4f7163..9208a6110a9 100644 --- a/htdocs/core/modules/oauth/google_oauthcallback.php +++ b/htdocs/core/modules/oauth/google_oauthcallback.php @@ -1,5 +1,5 @@ * Copyright (C) 2015 Frederic France * * This program is free software; you can redistribute it and/or modify diff --git a/htdocs/core/modules/oauth/stripelive_oauthcallback.php b/htdocs/core/modules/oauth/stripelive_oauthcallback.php index bf9656df783..f24921faf83 100644 --- a/htdocs/core/modules/oauth/stripelive_oauthcallback.php +++ b/htdocs/core/modules/oauth/stripelive_oauthcallback.php @@ -1,5 +1,5 @@ * Copyright (C) 2019 Thibault FOUCART * * This program is free software; you can redistribute it and/or modify diff --git a/htdocs/core/modules/oauth/stripetest_oauthcallback.php b/htdocs/core/modules/oauth/stripetest_oauthcallback.php index 64d55fba760..b41b579857e 100644 --- a/htdocs/core/modules/oauth/stripetest_oauthcallback.php +++ b/htdocs/core/modules/oauth/stripetest_oauthcallback.php @@ -1,5 +1,5 @@ * Copyright (C) 2015 Frederic France * * This program is free software; you can redistribute it and/or modify diff --git a/htdocs/langs/en_US/oauth.lang b/htdocs/langs/en_US/oauth.lang index 08f7956f455..b7f7c0c2c1a 100644 --- a/htdocs/langs/en_US/oauth.lang +++ b/htdocs/langs/en_US/oauth.lang @@ -9,8 +9,9 @@ HasAccessToken=A token was generated and saved into local database NewTokenStored=Token received and saved ToCheckDeleteTokenOnProvider=Click here to check/delete authorization saved by %s OAuth provider TokenDeleted=Token deleted +GetAccess=Click here to get a token RequestAccess=Click here to request/renew access and receive a new token -DeleteAccess=Click here to delete token +DeleteAccess=Click here to delete the token UseTheFollowingUrlAsRedirectURI=Use the following URL as the Redirect URI when creating your credentials with your OAuth provider: ListOfSupportedOauthProviders=Add your OAuth2 token providers. Then, go on your OAuth provider admin page to create/get an OAuth ID and Secret and save them here. Once done, switch on the other tab to generate your token. OAuthSetupForLogin=Page to manage (generate/delete) OAuth tokens @@ -33,4 +34,6 @@ OAUTH_STRIPE_LIVE_NAME=OAuth Stripe Live OAUTH_ID=OAuth ID OAUTH_SECRET=OAuth secret OAuthProviderAdded=OAuth provider added -AOAuthEntryForThisProviderAndLabelAlreadyHasAKey=An OAuth entry for this provider and label already exists \ No newline at end of file +AOAuthEntryForThisProviderAndLabelAlreadyHasAKey=An OAuth entry for this provider and label already exists +URLOfServiceForAuthorization=URL provided by OAuth service for authentication +Scopes=Scopes \ No newline at end of file From 8e572d605e7e12b091630ad6e8f179db85667b5c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Aug 2022 16:16:46 +0200 Subject: [PATCH 204/205] Fix php8 --- htdocs/includes/tecnickcom/tcpdf/tcpdf_barcodes_1d.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/includes/tecnickcom/tcpdf/tcpdf_barcodes_1d.php b/htdocs/includes/tecnickcom/tcpdf/tcpdf_barcodes_1d.php index 78bfc5b5bf4..2fea49ef4ce 100644 --- a/htdocs/includes/tecnickcom/tcpdf/tcpdf_barcodes_1d.php +++ b/htdocs/includes/tecnickcom/tcpdf/tcpdf_barcodes_1d.php @@ -1337,14 +1337,14 @@ class TCPDFBarcode { // calculate check digit $sum_a = 0; for ($i = 1; $i < $data_len; $i+=2) { - $sum_a += $code[$i]; + $sum_a += (int) $code[$i]; } if ($len > 12) { $sum_a *= 3; } $sum_b = 0; for ($i = 0; $i < $data_len; $i+=2) { - $sum_b += ($code[$i]); + $sum_b += (int) ($code[$i]); } if ($len < 13) { $sum_b *= 3; @@ -2171,7 +2171,7 @@ class TCPDFBarcode { /** * IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200 - * + * * @param $code (string) pre-formatted IMB barcode (65 chars "FADT") * @return array barcode representation. * @protected From f56abb1e5f676e3e7b3114f0833a54545999f9ba Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Aug 2022 16:17:07 +0200 Subject: [PATCH 205/205] Fix limit on nb of stickers --- htdocs/barcode/printsheet.php | 35 ++++++++++++++++++---------------- htdocs/langs/en_US/errors.lang | 1 + 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/htdocs/barcode/printsheet.php b/htdocs/barcode/printsheet.php index 763463d6fb8..c55db4ef2a1 100644 --- a/htdocs/barcode/printsheet.php +++ b/htdocs/barcode/printsheet.php @@ -203,25 +203,30 @@ if ($action == 'builddoc') { $forceimgscalewidth = (empty($conf->global->BARCODE_FORCEIMGSCALEWIDTH) ? 1 : $conf->global->BARCODE_FORCEIMGSCALEWIDTH); $forceimgscaleheight = (empty($conf->global->BARCODE_FORCEIMGSCALEHEIGHT) ? 1 : $conf->global->BARCODE_FORCEIMGSCALEHEIGHT); - for ($i = 0; $i < $numberofsticker; $i++) { - $arrayofrecords[] = array( - 'textleft'=>$textleft, - 'textheader'=>$textheader, - 'textfooter'=>$textfooter, - 'textright'=>$textright, - 'code'=>$code, - 'encoding'=>$encoding, - 'is2d'=>$is2d, - 'photo'=>$barcodeimage // Photo must be a file that exists with format supported by TCPDF - ); + $MAXSTICKERS = 1000; + if ($numberofsticker <= $MAXSTICKERS) { + for ($i = 0; $i < $numberofsticker; $i++) { + $arrayofrecords[] = array( + 'textleft'=>$textleft, + 'textheader'=>$textheader, + 'textfooter'=>$textfooter, + 'textright'=>$textright, + 'code'=>$code, + 'encoding'=>$encoding, + 'is2d'=>$is2d, + 'photo'=>$barcodeimage // Photo must be a file that exists with format supported by TCPDF + ); + } + } else { + $mesg = $langs->trans("ErrorQuantityIsLimitedTo", $MAXSTICKERS); + $error++; } } $i++; - $mesg = ''; // Build and output PDF - if ($mode == 'label') { + if (!$error && $mode == 'label') { if (!count($arrayofrecords)) { $mesg = $langs->trans("ErrorRecordNotFound"); } @@ -240,7 +245,7 @@ if ($action == 'builddoc') { } } - if ($result <= 0 || $mesg) { + if ($result <= 0 || $mesg || $error) { if (empty($mesg)) { $mesg = 'Error '.$result; } @@ -272,8 +277,6 @@ print '
'; print ''.$langs->trans("PageToGenerateBarCodeSheets", $langs->transnoentitiesnoconv("BuildPageToPrint")).'
'; print '
'; -dol_htmloutput_errors($mesg); - //print img_picto('','puce').' '.$langs->trans("PrintsheetForOneBarCode").'
'; //print '
'; diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index a280228a46d..ebdb359a66e 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -290,6 +290,7 @@ ErrorDeleteLineNotAllowedByObjectStatus=Delete line is not allowed by current ob ErrorAjaxRequestFailed=Request failed ErrorThirpdartyOrMemberidIsMandatory=Third party or Member of partnership is mandatory ErrorFailedToWriteInTempDirectory=Failed to write in temp directory +ErrorQuantityIsLimitedTo=Quantity is limited to %s # Warnings WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup.