From 284627b693413a8251f11981bd407060b1d162c2 Mon Sep 17 00:00:00 2001 From: trekmorris <78349579+trekmorris@users.noreply.github.com> Date: Fri, 16 Jul 2021 23:55:29 +0800 Subject: [PATCH 01/52] Update opensurvey.lang manually This file is not auto sync from transifex . So update it manually . --- htdocs/langs/zh_TW/opensurvey.lang | 120 ++++++++++++++--------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/htdocs/langs/zh_TW/opensurvey.lang b/htdocs/langs/zh_TW/opensurvey.lang index 51a4283c721..ff927bfc863 100644 --- a/htdocs/langs/zh_TW/opensurvey.lang +++ b/htdocs/langs/zh_TW/opensurvey.lang @@ -1,61 +1,61 @@ # Dolibarr language file - Source file is en_US - opensurvey -Survey=Poll -Surveys=Polls -OrganizeYourMeetingEasily=Organize your meetings and polls easily. First select the type of poll... -NewSurvey=New poll -OpenSurveyArea=Polls area -AddACommentForPoll=You can add a comment into poll... -AddComment=Add comment -CreatePoll=Create poll -PollTitle=Poll title -ToReceiveEMailForEachVote=Receive an email for each vote -TypeDate=Type date -TypeClassic=Type standard -OpenSurveyStep2=Select your dates among the free days (grey). The selected days are green. You can unselect a day previously selected by clicking again on it -RemoveAllDays=Remove all days -CopyHoursOfFirstDay=Copy hours of first day -RemoveAllHours=Remove all hours -SelectedDays=Selected days -TheBestChoice=The best choice currently is -TheBestChoices=The best choices currently are -with=with -OpenSurveyHowTo=If you agree to vote in this poll, you have to give your name, choose the values that fit best for you and validate with the plus button at the end of the line. -CommentsOfVoters=Comments of voters -ConfirmRemovalOfPoll=Are you sure you want to remove this poll (and all votes) -RemovePoll=Remove poll -UrlForSurvey=URL to communicate to get a direct access to poll -PollOnChoice=You are creating a poll to make a multi-choice for a poll. First enter all possible choices for your poll: -CreateSurveyDate=Create a date poll -CreateSurveyStandard=Create a standard poll -CheckBox=Simple checkbox -YesNoList=List (empty/yes/no) -PourContreList=List (empty/for/against) -AddNewColumn=Add new column -TitleChoice=Choice label -ExportSpreadsheet=Export result spreadsheet -ExpireDate=極限日期 -NbOfSurveys=Number of polls -NbOfVoters=No. of voters -SurveyResults=Results -PollAdminDesc=You are allowed to change all vote lines of this poll with button "Edit". You can, as well, remove a column or a line with %s. You can also add a new column with %s. -5MoreChoices=5 more choices -Against=Against -YouAreInivitedToVote=You are invited to vote for this poll -VoteNameAlreadyExists=This name was already used for this poll -AddADate=Add a date -AddStartHour=Add start hour -AddEndHour=Add end hour -votes=vote(s) -NoCommentYet=No comments have been posted for this poll yet -CanComment=Voters can comment in the poll -CanSeeOthersVote=Voters can see other people's vote -SelectDayDesc=For each selected day, you can choose, or not, meeting hours in the following format:
- empty,
- "8h", "8H" or "8:00" to give a meeting's start hour,
- "8-11", "8h-11h", "8H-11H" or "8:00-11:00" to give a meeting's start and end hour,
- "8h15-11h15", "8H15-11H15" or "8:15-11:15" for the same thing but with minutes. -BackToCurrentMonth=Back to current month -ErrorOpenSurveyFillFirstSection=You haven't filled the first section of the poll creation -ErrorOpenSurveyOneChoice=Enter at least one choice -ErrorInsertingComment=There was an error while inserting your comment -MoreChoices=Enter more choices for the voters -SurveyExpiredInfo=The poll has been closed or voting delay has expired. -EmailSomeoneVoted=%s has filled a line.\nYou can find your poll at the link: \n%s -ShowSurvey=Show survey -UserMustBeSameThanUserUsedToVote=You must have voted and use the same user name that the one used to vote, to post a comment +Survey=調查 +Surveys=調查 +OrganizeYourMeetingEasily=輕鬆組織會議和調查。首先選擇調查的類型... +NewSurvey=新調查 +OpenSurveyArea=調查區 +AddACommentForPoll=您可以在調查中加入評論... +AddComment=增加評論 +CreatePoll=建立調查 +PollTitle=調查標題 +ToReceiveEMailForEachVote=每次投票都會收到一封電子郵件 +TypeDate=日期類型 +TypeClassic=標準類型 +OpenSurveyStep2=在空閒日中選擇日期(灰色)。所選的日期為綠色。您可以通過再次點擊來取消先前選擇的日期 +RemoveAllDays=全部刪除 +CopyHoursOfFirstDay=複制第一天的時間 +RemoveAllHours=刪除所有時間 +SelectedDays=已選擇的日子 +TheBestChoice=目前最好的選擇是 +TheBestChoices=目前最好的選擇是 +with=與 +OpenSurveyHowTo=如果您同意在此次調查中投票,則必須給出自己的名字,選擇最適合您的值,並使用該行末尾的加號按鈕進行驗證。 +CommentsOfVoters=投票人的評論 +ConfirmRemovalOfPoll=您確定要刪除此調查(以及所有投票)嗎? +RemovePoll=刪除調查 +UrlForSurvey=調查的直接網址 +PollOnChoice=您正在建立多項選擇的調查。首先為您的調查輸入所有可能的選擇: +CreateSurveyDate=建立日期調查 +CreateSurveyStandard=建立標準調查 +CheckBox=簡易勾選框 +YesNoList=清單(空/是/否) +PourContreList=清單(空/支持/反對) +AddNewColumn=增加新欄位 +TitleChoice=選擇標籤 +ExportSpreadsheet=匯出結果表格 +ExpireDate=調查截止日 +NbOfSurveys=投票次數 +NbOfVoters=投票人數 +SurveyResults=結果 +PollAdminDesc=您可以使用“編輯”按鈕更改此民意調查的所有投票行。您也可以使用%s刪除列或行。您也可以使用%s增加新列。 +5MoreChoices=再多5個選項 +Against=反對 +YouAreInivitedToVote=您被邀請參加此項調查 +VoteNameAlreadyExists=此名稱已用於此調查 +AddADate=增加日期 +AddStartHour=增加開始時間 +AddEndHour=增加結束時間 +votes=投票 +NoCommentYet=尚未有此調查的評論 +CanComment=投票者可以在調查中發表評論 +CanSeeOthersVote=投票者可以看到其他人的投票 +SelectDayDesc=對於每個選定的日期,您可以依照以下格式選擇是否選擇開會時間:
-空的
-“ 8h”,“ 8H”或“ 8:00”指定會議的開始時間,
-“ 8-11”,“ 8h-11h”,“ 8H-11H”或“ 8:00-11:00”給出會議的開始和結束時間,
-同樣的用“ 8h15-11h15”,“ 8H15-11H15”或“ 8:15-11:15”表示,但要加上分鐘。 +BackToCurrentMonth=回到目前月份 +ErrorOpenSurveyFillFirstSection=您尚未填寫建立調查的第一部分 +ErrorOpenSurveyOneChoice=輸入至少一個選項 +ErrorInsertingComment=插入您的評論時出錯 +MoreChoices=為投票者輸入更多選項 +SurveyExpiredInfo=投票已關閉或投票已到期。 +EmailSomeoneVoted=%s已填滿一行。\n您可以在以下連結找到您的調查:\n%s +ShowSurvey=顯示調查 +UserMustBeSameThanUserUsedToVote=您必須已投票並使用與投票時相同的用戶名來發表評論 From 4d6b63dbed10f3df56ceda40d0a0abf4334b971d Mon Sep 17 00:00:00 2001 From: ksar <35605507+ksar-ksar@users.noreply.github.com> Date: Tue, 20 Jul 2021 16:14:47 +0200 Subject: [PATCH 02/52] FIX #18181 FIX #18181 --- htdocs/core/class/notify.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index 6b32799bc89..044115f1568 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -687,7 +687,7 @@ class Notify break; case 'BILL_PAYED': $link = ''.$newref.''; - $dir_output = $$conf->facture->dir_output."/".get_exdir(0, 0, 0, 1, $object, 'invoice'); + $dir_output = $conf->facture->dir_output."/".get_exdir(0, 0, 0, 1, $object, 'invoice'); $object_type = 'facture'; $mesg = $langs->transnoentitiesnoconv("EMailTextInvoicePayed", $link); break; From 922354f36616288ea69d066206d4c775b4c43e17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 20 Jul 2021 18:19:27 +0200 Subject: [PATCH 03/52] Update projects.php --- htdocs/projet/ajax/projects.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/ajax/projects.php b/htdocs/projet/ajax/projects.php index 0036ae64353..a852ab6bad8 100644 --- a/htdocs/projet/ajax/projects.php +++ b/htdocs/projet/ajax/projects.php @@ -63,7 +63,7 @@ if (!GETPOST('mode', 'aZ09') || GETPOST('mode', 'aZ09') != 'gettasks') { // Mode to get list of tasks if (GETPOST('mode', 'aZ09') == 'gettasks') { $formproject = new FormProjets($db); - $formproject->selectTasks((!empty($$socid) ? $socid : -1), 0, 'taskid', 24, 1, '1', 1, 0, 0, 'maxwidth500', GETPOST('projectid', 'int'), ''); + $formproject->selectTasks((!empty($socid) ? $socid : -1), 0, 'taskid', 24, 1, '1', 1, 0, 0, 'maxwidth500', GETPOST('projectid', 'int'), ''); return; } From e93a362a0d585374260be696f91420d922672d4e Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Fri, 23 Jul 2021 18:33:18 +0200 Subject: [PATCH 04/52] fix: since be62c2f7 commit selectlist from formconfirm were behind the form confirm --- htdocs/core/class/html.form.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 1213c070acc..56316475ab7 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1182,7 +1182,7 @@ class Form // mode 1 $urloption = 'htmlname='.urlencode($htmlname).'&outjson=1&filter='.urlencode($filter).($showtype ? '&showtype='.urlencode($showtype) : ''); $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/societe/ajax/company.php', $urloption, $conf->global->COMPANY_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); - $out .= ''; + $out .= ''; if (empty($hidelabel)) print $langs->trans("RefOrLabel").' : '; elseif ($hidelabel > 1) { $placeholder = ' placeholder="'.$langs->trans("RefOrLabel").'"'; @@ -6052,7 +6052,7 @@ class Form $urloption = 'htmlname='.$htmlname.'&outjson=1&objectdesc='.$objectdesc.'&filter='.urlencode($objecttmp->filter); // Activate the auto complete using ajax call. $out .= ajax_autocompleter($preselectedvalue, $htmlname, $urlforajaxcall, $urloption, $conf->global->$confkeyforautocompletemode, 0, array()); - $out .= ''; + $out .= ''; if ($placeholder) $placeholder = ' placeholder="'.$placeholder.'"'; $out .= ''; } From bbd84fd13ec2241348d31246125f286c364192d2 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Mon, 26 Jul 2021 04:08:05 +0200 Subject: [PATCH 05/52] FIX: Missing column Date validation in ledger & subledger --- .../accountancy/bookkeeping/listbyaccount.php | 56 ++++++++++++++++- .../bookkeeping/listbysubaccount.php | 63 ++++++++++++++++--- 2 files changed, 108 insertions(+), 11 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 98c3f14191b..c8364c35ee5 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -2,7 +2,7 @@ /* Copyright (C) 2016 Neil Orley * Copyright (C) 2013-2016 Olivier Geffroy * Copyright (C) 2013-2020 Florian Henry - * Copyright (C) 2013-2020 Alexandre Spangaro + * Copyright (C) 2013-2021 Alexandre Spangaro * Copyright (C) 2018 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -56,6 +56,14 @@ $search_date_export_endmonth = GETPOST('search_date_export_endmonth', 'int'); $search_date_export_endday = GETPOST('search_date_export_endday', 'int'); $search_date_export_start = dol_mktime(0, 0, 0, $search_date_export_startmonth, $search_date_export_startday, $search_date_export_startyear); $search_date_export_end = dol_mktime(23, 59, 59, $search_date_export_endmonth, $search_date_export_endday, $search_date_export_endyear); +$search_date_validation_startyear = GETPOST('search_date_validation_startyear', 'int'); +$search_date_validation_startmonth = GETPOST('search_date_validation_startmonth', 'int'); +$search_date_validation_startday = GETPOST('search_date_validation_startday', 'int'); +$search_date_validation_endyear = GETPOST('search_date_validation_endyear', 'int'); +$search_date_validation_endmonth = GETPOST('search_date_validation_endmonth', 'int'); +$search_date_validation_endday = GETPOST('search_date_validation_endday', 'int'); +$search_date_validation_start = dol_mktime(0, 0, 0, $search_date_validation_startmonth, $search_date_validation_startday, $search_date_validation_startyear); +$search_date_validation_end = dol_mktime(23, 59, 59, $search_date_validation_endmonth, $search_date_validation_endday, $search_date_validation_endyear); $search_accountancy_code = GETPOST("search_accountancy_code"); $search_accountancy_code_start = GETPOST('search_accountancy_code_start', 'alpha'); @@ -81,7 +89,7 @@ if (GETPOST("button_delmvt_x") || GETPOST("button_delmvt.x") || GETPOST("button_ } // Load variable for pagination -$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION); +$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION); $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); @@ -144,6 +152,7 @@ $arrayfields = array( 't.credit'=>array('label'=>$langs->trans("Credit"), 'checked'=>1), 't.lettering_code'=>array('label'=>$langs->trans("LetteringCode"), 'checked'=>1), 't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1), + 't.date_validated'=>array('label'=>$langs->trans("DateValidation"), 'checked'=>1), ); if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) { @@ -221,6 +230,14 @@ if (empty($reshook)) { $search_date_export_endyear = ''; $search_date_export_endmonth = ''; $search_date_export_endday = ''; + $search_date_validation_start = ''; + $search_date_validation_end = ''; + $search_date_validation_startyear = ''; + $search_date_validation_startmonth = ''; + $search_date_validation_startday = ''; + $search_date_validation_endyear = ''; + $search_date_validation_endmonth = ''; + $search_date_validation_endday = ''; $search_debit = ''; $search_credit = ''; $search_lettering_code = ''; @@ -301,6 +318,14 @@ if (empty($reshook)) { $filter['t.date_export<='] = $search_date_export_end; $param .= '&search_date_export_endmonth='.$search_date_export_endmonth.'&search_date_export_endday='.$search_date_export_endday.'&search_date_export_endyear='.$search_date_export_endyear; } + if (!empty($search_date_validation_start)) { + $filter['t.date_validated>='] = $search_date_validation_start; + $param .= '&search_date_validation_startmonth='.$search_date_validation_startmonth.'&search_date_validation_startday='.$search_date_validation_startday.'&search_date_validation_startyear='.$search_date_validation_startyear; + } + if (!empty($search_date_validation_end)) { + $filter['t.date_validated<='] = $search_date_validation_end; + $param .= '&search_date_validation_endmonth='.$search_date_validation_endmonth.'&search_date_validation_endday='.$search_date_validation_endday.'&search_date_validation_endyear='.$search_date_validation_endyear; + } } if ($action == 'delbookkeeping' && $user->rights->accounting->mouvements->supprimer) { @@ -564,6 +589,17 @@ if (!empty($arrayfields['t.date_export']['checked'])) { print ''; print ''; } +// Date validation +if (!empty($arrayfields['t.date_validated']['checked'])) { + print ''; + print '
'; + print $form->selectDate($search_date_validation_start, 'search_date_validation_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + print '
'; + print '
'; + print $form->selectDate($search_date_validation_end, 'search_date_validation_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); + print '
'; + print ''; +} // Fields from hook $parameters = array('arrayfields'=>$arrayfields); @@ -605,6 +641,9 @@ if (!empty($arrayfields['t.lettering_code']['checked'])) { if (!empty($arrayfields['t.date_export']['checked'])) { print_liste_field_titre($arrayfields['t.date_export']['label'], $_SERVER['PHP_SELF'], "t.date_export", "", $param, '', $sortfield, $sortorder, 'center '); } +if (!empty($arrayfields['t.date_validated']['checked'])) { + print_liste_field_titre($arrayfields['t.date_validated']['label'], $_SERVER['PHP_SELF'], "t.date_validated", "", $param, '', $sortfield, $sortorder, 'center '); +} // Hook fields $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook @@ -635,7 +674,7 @@ while ($i < min($num, $limit)) { // Is it a break ? if ($accountg != $displayed_account_number || !isset($displayed_account_number)) { $colnumber = 5; - $colnumberend = 7; + $colnumberend = 8; if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING) || empty($arrayfields['t.lettering_code']['checked'])) { $colnumber--; @@ -643,6 +682,9 @@ while ($i < min($num, $limit)) { if (empty($arrayfields['t.date_export']['checked'])) { $colnumber--; } + if (empty($arrayfields['t.date_validated']['checked'])) { + $colnumber--; + } $colspan = $totalarray['nbfield'] - $colnumber; $colspanend = $totalarray['nbfield'] - $colnumberend; @@ -845,6 +887,14 @@ while ($i < min($num, $limit)) { } } + // Validated operation date + if (!empty($arrayfields['t.date_validated']['checked'])) { + print ''.dol_print_date($line->date_validation, 'dayhour').''; + if (!$i) { + $totalarray['nbfield']++; + } + } + // Fields from hook $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook diff --git a/htdocs/accountancy/bookkeeping/listbysubaccount.php b/htdocs/accountancy/bookkeeping/listbysubaccount.php index 20899c693c6..d2e036b1f60 100644 --- a/htdocs/accountancy/bookkeeping/listbysubaccount.php +++ b/htdocs/accountancy/bookkeeping/listbysubaccount.php @@ -2,8 +2,8 @@ /* Copyright (C) 2016 Neil Orley * Copyright (C) 2013-2016 Olivier Geffroy * Copyright (C) 2013-2020 Florian Henry - * Copyright (C) 2013-2020 Alexandre Spangaro - * Copyright (C) 2018-2020 Frédéric France + * Copyright (C) 2013-2021 Alexandre Spangaro + * Copyright (C) 2018-2020 Frédéric 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 @@ -46,7 +46,7 @@ $search_date_endyear = GETPOST('search_date_endyear', 'int'); $search_date_endmonth = GETPOST('search_date_endmonth', 'int'); $search_date_endday = GETPOST('search_date_endday', 'int'); $search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); -$search_date_end = dol_mktime(0, 0, 0, $search_date_endmonth, $search_date_endday, $search_date_endyear); +$search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear); $search_doc_date = dol_mktime(0, 0, 0, GETPOST('doc_datemonth', 'int'), GETPOST('doc_dateday', 'int'), GETPOST('doc_dateyear', 'int')); $search_date_export_startyear = GETPOST('search_date_export_startyear', 'int'); $search_date_export_startmonth = GETPOST('search_date_export_startmonth', 'int'); @@ -55,7 +55,15 @@ $search_date_export_endyear = GETPOST('search_date_export_endyear', 'int'); $search_date_export_endmonth = GETPOST('search_date_export_endmonth', 'int'); $search_date_export_endday = GETPOST('search_date_export_endday', 'int'); $search_date_export_start = dol_mktime(0, 0, 0, $search_date_export_startmonth, $search_date_export_startday, $search_date_export_startyear); -$search_date_export_end = dol_mktime(0, 0, 0, $search_date_export_endmonth, $search_date_export_endday, $search_date_export_endyear); +$search_date_export_end = dol_mktime(23, 59, 59, $search_date_export_endmonth, $search_date_export_endday, $search_date_export_endyear); +$search_date_validation_startyear = GETPOST('search_date_validation_startyear', 'int'); +$search_date_validation_startmonth = GETPOST('search_date_validation_startmonth', 'int'); +$search_date_validation_startday = GETPOST('search_date_validation_startday', 'int'); +$search_date_validation_endyear = GETPOST('search_date_validation_endyear', 'int'); +$search_date_validation_endmonth = GETPOST('search_date_validation_endmonth', 'int'); +$search_date_validation_endday = GETPOST('search_date_validation_endday', 'int'); +$search_date_validation_start = dol_mktime(0, 0, 0, $search_date_validation_startmonth, $search_date_validation_startday, $search_date_validation_startyear); +$search_date_validation_end = dol_mktime(23, 59, 59, $search_date_validation_endmonth, $search_date_validation_endday, $search_date_validation_endyear); $search_accountancy_code = GETPOST("search_accountancy_code"); $search_accountancy_code_start = GETPOST('search_accountancy_code_start', 'alpha'); @@ -144,6 +152,7 @@ $arrayfields = array( 't.credit'=>array('label'=>$langs->trans("Credit"), 'checked'=>1), 't.lettering_code'=>array('label'=>$langs->trans("LetteringCode"), 'checked'=>1), 't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1), + 't.date_validated'=>array('label'=>$langs->trans("DateValidation"), 'checked'=>1), ); if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) { @@ -221,6 +230,14 @@ if (empty($reshook)) { $search_date_export_endyear = ''; $search_date_export_endmonth = ''; $search_date_export_endday = ''; + $search_date_validation_start = ''; + $search_date_validation_end = ''; + $search_date_validation_startyear = ''; + $search_date_validation_startmonth = ''; + $search_date_validation_startday = ''; + $search_date_validation_endyear = ''; + $search_date_validation_endmonth = ''; + $search_date_validation_endday = ''; $search_debit = ''; $search_credit = ''; $search_lettering_code = ''; @@ -301,6 +318,14 @@ if (empty($reshook)) { $filter['t.date_export<='] = $search_date_export_end; $param .= '&search_date_export_endmonth='.$search_date_export_endmonth.'&search_date_export_endday='.$search_date_export_endday.'&search_date_export_endyear='.$search_date_export_endyear; } + if (!empty($search_date_validation_start)) { + $filter['t.date_validated>='] = $search_date_validation_start; + $param .= '&search_date_validation_startmonth='.$search_date_validation_startmonth.'&search_date_validation_startday='.$search_date_validation_startday.'&search_date_validation_startyear='.$search_date_validation_startyear; + } + if (!empty($search_date_validation_end)) { + $filter['t.date_validated<='] = $search_date_validation_end; + $param .= '&search_date_validation_endmonth='.$search_date_validation_endmonth.'&search_date_validation_endday='.$search_date_validation_endday.'&search_date_validation_endyear='.$search_date_validation_endyear; + } } if ($action == 'delbookkeeping' && $user->rights->accounting->mouvements->supprimer) { @@ -373,7 +398,6 @@ $title_page = $langs->trans("Operations").' - '.$langs->trans("VueByAccountAccou llxHeader('', $title_page); - // List $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { @@ -448,7 +472,6 @@ print ''; print ''; - $parameters = array(); $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { @@ -568,6 +591,17 @@ if (!empty($arrayfields['t.date_export']['checked'])) { print ''; print ''; } +// Date validation +if (!empty($arrayfields['t.date_validated']['checked'])) { + print ''; + print '
'; + print $form->selectDate($search_date_validation_start, 'search_date_validation_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + print '
'; + print '
'; + print $form->selectDate($search_date_validation_end, 'search_date_validation_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); + print '
'; + print ''; +} // Fields from hook $parameters = array('arrayfields'=>$arrayfields); @@ -609,6 +643,9 @@ if (!empty($arrayfields['t.lettering_code']['checked'])) { if (!empty($arrayfields['t.date_export']['checked'])) { print_liste_field_titre($arrayfields['t.date_export']['label'], $_SERVER['PHP_SELF'], "t.date_export", "", $param, '', $sortfield, $sortorder, 'center '); } +if (!empty($arrayfields['t.date_validated']['checked'])) { + print_liste_field_titre($arrayfields['t.date_validated']['label'], $_SERVER['PHP_SELF'], "t.date_validated", "", $param, '', $sortfield, $sortorder, 'center '); +} // Hook fields $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook @@ -639,7 +676,7 @@ while ($i < min($num, $limit)) { // Is it a break ? if ($accountg != $displayed_account_number || !isset($displayed_account_number)) { $colnumber = 5; - $colnumberend = 7; + $colnumberend = 8; if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING) || empty($arrayfields['t.lettering_code']['checked'])) { $colnumber--; @@ -647,10 +684,12 @@ while ($i < min($num, $limit)) { if (empty($arrayfields['t.date_export']['checked'])) { $colnumber--; } + if (empty($arrayfields['t.date_validated']['checked'])) { + $colnumber--; + } $colspan = $totalarray['nbfield'] - $colnumber; $colspanend = $totalarray['nbfield'] - $colnumberend; - // Show a subtotal by accounting account if (isset($displayed_account_number)) { print ''; @@ -859,6 +898,14 @@ while ($i < min($num, $limit)) { } } + // Validated operation date + if (!empty($arrayfields['t.date_validated']['checked'])) { + print ''.dol_print_date($line->date_validation, 'dayhour').''; + if (!$i) { + $totalarray['nbfield']++; + } + } + // Fields from hook $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook From a7cef1aa1595a768353a6d7980f7437eaecd1f49 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Mon, 26 Jul 2021 10:20:11 +0200 Subject: [PATCH 06/52] FIX: cannot add time spend when column ref is not displayed --- htdocs/projet/tasks/time.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 3b2e36d34c6..2a4b1d6aeee 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -1374,7 +1374,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0) print ''; if (!$i) $totalarray['nbfield']++; } - } else { + } elseif ($action !== 'createtime') { print ''; } From b5dde982d52c54e1b5a311c485ab2e2f41331239 Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Mon, 26 Jul 2021 10:32:51 +0200 Subject: [PATCH 07/52] Fix #18185 : for v13 --- htdocs/societe/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 5dceee7751d..04ad5a32fcc 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -482,7 +482,7 @@ if ($search_type_thirdparty && $search_type_thirdparty != '-1') $sql .= natural_ if (!empty($search_staff) && $search_staff != '-1') $sql .= natural_search("s.fk_effectif", $search_staff, 2); if ($search_level) $sql .= natural_search("s.fk_prospectlevel", join(',', $search_level), 3); if ($search_parent_name) $sql .= natural_search("s2.nom", $search_parent_name); -if ($search_stcomm != '' && $search_stcomm != -2) $sql .= natural_search("s.fk_stcomm", $search_stcomm, 2); +if ($search_stcomm != '' && $search_stcomm != -2) $sql .= natural_search("s.fk_stcomm", $search_stcomm, 1); if ($search_import_key) $sql .= natural_search("s.import_key", $search_import_key); // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; From a7f55f4778ebe778515edd7baeab2699d912b7f4 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Mon, 26 Jul 2021 15:43:57 +0200 Subject: [PATCH 08/52] fix: Expense report line, on update qty can be decimal --- htdocs/expensereport/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index e1e5fb34f2a..07d3e018390 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -2314,7 +2314,7 @@ if ($action == 'create') // Quantity print ''; - print ''; + print ''; print ''; //print ''.$langs->trans('AmountHT').''; From 42252abc07fb7a73050af8cc14205bbd96150e79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 28 Jul 2021 10:14:57 +0200 Subject: [PATCH 09/52] remove debug --- htdocs/accountancy/admin/index.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/accountancy/admin/index.php b/htdocs/accountancy/admin/index.php index 5f40022518b..9bb9fe3220c 100644 --- a/htdocs/accountancy/admin/index.php +++ b/htdocs/accountancy/admin/index.php @@ -93,7 +93,6 @@ if ($action == 'update') { foreach ($list as $constname) { $constvalue = GETPOST($constname, 'alpha'); - var_dump($constname); if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) { $error++; } From 712f0b897d66047a3d5d37f90d1ab15896f77129 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Wed, 28 Jul 2021 12:02:45 +0200 Subject: [PATCH 10/52] FIX: Accountancy - Debug Export Sage50 / CIEL Compta / CIEL Compta Evo (Format XIMPORT) --- .../class/accountancyexport.class.php | 35 ++++++++++++------- htdocs/accountancy/tpl/export_journal.tpl.php | 6 ++-- htdocs/langs/en_US/accountancy.lang | 2 +- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index 6ef54ea3029..aa3e24ab545 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -5,7 +5,7 @@ * Copyright (C) 2015 Florian Henry * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2016 Pierre-Henry Favre - * Copyright (C) 2016-2020 Alexandre Spangaro + * Copyright (C) 2016-2021 Alexandre Spangaro * Copyright (C) 2013-2017 Olivier Geffroy * Copyright (C) 2017 Elarifr. Ari Elbaz * Copyright (C) 2017-2019 Frédéric France @@ -439,33 +439,42 @@ class AccountancyExport } /** - * Export format : CIEL + * Export format : CIEL (Format XIMPORT) + * Format since 2003 compatible CIEL version > 2002 / Sage50 + * + * Help : https://sage50c.online-help.sage.fr/aide-technique/ + * In sage software | Use menu : "Exchange" > "Importing entries..." + * + * If you want to force filename to "XIMPORT.TXT" for automatically import file present in a directory : + * use constant ACCOUNTING_EXPORT_XIMPORT_FORCE_FILENAME * * @param array $TData data * @return void */ public function exportCiel(&$TData) { - global $conf; - $end_line = "\r\n"; $i = 1; - $date_ecriture = dol_print_date(dol_now(), $conf->global->ACCOUNTING_EXPORT_DATE); // format must be yyyymmdd + foreach ($TData as $data) { - $code_compta = $data->numero_compte; - if (!empty($data->subledger_account)) - $code_compta = $data->subledger_account; + $code_compta = length_accountg($data->numero_compte); + if (!empty($data->subledger_account)) { + $code_compta = length_accounta($data->subledger_account); + } + + $date_creation = dol_print_date($data->date_creation, '%Y%m%d'); + $date_document = dol_print_date($data->doc_date, '%Y%m%d'); $Tab = array(); - $Tab['num_ecriture'] = str_pad($i, 5); + $Tab['num_ecriture'] = str_pad($data->piece_num, 5); $Tab['code_journal'] = str_pad($data->code_journal, 2); - $Tab['date_ecriture'] = $date_ecriture; - $Tab['date_ope'] = dol_print_date($data->doc_date, $conf->global->ACCOUNTING_EXPORT_DATE); - $Tab['num_piece'] = str_pad(self::trunc($data->piece_num, 12), 12); + $Tab['date_ecriture'] = $date_creation; + $Tab['date_ope'] = $date_document; + $Tab['num_piece'] = str_pad(self::trunc($data->doc_ref, 12), 12); $Tab['num_compte'] = str_pad(self::trunc($code_compta, 11), 11); $Tab['libelle_ecriture'] = str_pad(self::trunc(dol_string_unaccent($data->doc_ref).dol_string_unaccent($data->label_operation), 25), 25); - $Tab['montant'] = str_pad(abs($data->montant), 13, ' ', STR_PAD_LEFT); + $Tab['montant'] = str_pad(price2fec(abs($data->montant)), 13, ' ', STR_PAD_LEFT); $Tab['type_montant'] = str_pad($data->sens, 1); $Tab['vide'] = str_repeat(' ', 18); $Tab['intitule_compte'] = str_pad(self::trunc(dol_string_unaccent($data->label_operation), 34), 34); diff --git a/htdocs/accountancy/tpl/export_journal.tpl.php b/htdocs/accountancy/tpl/export_journal.tpl.php index fb957db2233..c53ec1197f9 100644 --- a/htdocs/accountancy/tpl/export_journal.tpl.php +++ b/htdocs/accountancy/tpl/export_journal.tpl.php @@ -58,9 +58,9 @@ if ($accountancyexport->getFormatCode($formatexportset) == $accountancyexport::$ $endaccountingperiod = dol_print_date(dol_get_last_day($tmparray['year'], $tmparray['mon']), 'dayxcard'); $completefilename = $siren."FEC".$endaccountingperiod.".txt"; -} -else -{ +} elseif ($accountancyexport->getFormatCode($formatexportset) == $accountancyexport::$EXPORT_TYPE_CIEL && $type_export == "general_ledger" && !empty($conf->global->ACCOUNTING_EXPORT_XIMPORT_FORCE_FILENAME)) { + $completefilename = "XIMPORT.TXT"; +} else { $completefilename = ($code ? $code."_" : "").($prefix ? $prefix."_" : "").$filename.($nodateexport ? "" : $date_export).".".$format; } diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index fea7bf9d0ef..bf58e28e4f6 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -311,7 +311,7 @@ Modelcsv_normal=Classic export Modelcsv_CEGID=Export for CEGID Expert Comptabilité Modelcsv_COALA=Export for Sage Coala Modelcsv_bob50=Export for Sage BOB 50 -Modelcsv_ciel=Export for Sage Ciel Compta or Compta Evolution +Modelcsv_ciel=Export for Sage50, Ciel Compta or Compta Evo. (Format XIMPORT) Modelcsv_quadratus=Export for Quadratus QuadraCompta Modelcsv_ebp=Export for EBP Modelcsv_cogilog=Export for Cogilog From 7acebd28ca0196f3a720e8226e8e08e95e3e4a2b Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Wed, 28 Jul 2021 14:08:53 +0200 Subject: [PATCH 11/52] Add information --- htdocs/accountancy/class/accountancyexport.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index aa3e24ab545..009a4c3cb74 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -441,6 +441,7 @@ class AccountancyExport /** * Export format : CIEL (Format XIMPORT) * Format since 2003 compatible CIEL version > 2002 / Sage50 + * Last review for this format : 2021/07/28 Alexandre Spangaro (aspangaro@open-dsi.fr) * * Help : https://sage50c.online-help.sage.fr/aide-technique/ * In sage software | Use menu : "Exchange" > "Importing entries..." From cd63ede35a6c3db0ada94c096949abb0da1ddd09 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Wed, 28 Jul 2021 16:46:57 +0200 Subject: [PATCH 12/52] Correctif date --- htdocs/accountancy/class/accountancyexport.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index 009a4c3cb74..7cd1a153183 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -464,14 +464,14 @@ class AccountancyExport $code_compta = length_accounta($data->subledger_account); } - $date_creation = dol_print_date($data->date_creation, '%Y%m%d'); - $date_document = dol_print_date($data->doc_date, '%Y%m%d'); + $date_document = dol_print_date($data->doc_date, '%Y%m%d'); + $date_echeance = dol_print_date($data->date_lim_reglement, '%Y%m%d'); $Tab = array(); $Tab['num_ecriture'] = str_pad($data->piece_num, 5); $Tab['code_journal'] = str_pad($data->code_journal, 2); - $Tab['date_ecriture'] = $date_creation; - $Tab['date_ope'] = $date_document; + $Tab['date_ecriture'] = str_pad($date_document, 8, ' ', STR_PAD_LEFT); + $Tab['date_echeance'] = str_pad($date_echeance, 8, ' ', STR_PAD_LEFT); $Tab['num_piece'] = str_pad(self::trunc($data->doc_ref, 12), 12); $Tab['num_compte'] = str_pad(self::trunc($code_compta, 11), 11); $Tab['libelle_ecriture'] = str_pad(self::trunc(dol_string_unaccent($data->doc_ref).dol_string_unaccent($data->label_operation), 25), 25); From ae5d17815f03a80c9ef21ac4917c1ff0db852e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 27 Jul 2021 10:26:51 +0200 Subject: [PATCH 13/52] Update dolreceiptprinter.class.php --- htdocs/core/class/dolreceiptprinter.class.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php index 45c87401416..a3ddb3d7c7f 100644 --- a/htdocs/core/class/dolreceiptprinter.class.php +++ b/htdocs/core/class/dolreceiptprinter.class.php @@ -680,9 +680,7 @@ class dolReceiptPrinter extends Printer foreach ($object->lines as $line) { $total_localtax1 += $line->total_localtax1; } - foreach ($vatarray as $vatkey => $vatvalue) { - $this->printer->text(str_pad(price($total_localtax1), 10, ' ', STR_PAD_LEFT)."\n"); - } + $this->printer->text(str_pad(price($total_localtax1), 10, ' ', STR_PAD_LEFT)."\n"); break; case 'DOL_PRINT_OBJECT_TAX2': //var_dump($object); @@ -690,9 +688,7 @@ class dolReceiptPrinter extends Printer foreach ($object->lines as $line) { $total_localtax2 += $line->total_localtax2; } - foreach ($vatarray as $vatkey => $vatvalue) { - $this->printer->text(str_pad(price($total_localtax2), 10, ' ', STR_PAD_LEFT)."\n"); - } + $this->printer->text(str_pad(price($total_localtax2), 10, ' ', STR_PAD_LEFT)."\n"); break; case 'DOL_PRINT_OBJECT_TOTAL': $title = $langs->trans('TotalHT'); From e7af8e9d5ea7d825bea0d58d6e1d816388d0dd73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josep=20Llu=C3=ADs?= Date: Wed, 28 Jul 2021 18:02:55 +0200 Subject: [PATCH 14/52] FIX totalDayAll hours in tasks The extra days hours were not considered in total hours --- htdocs/core/js/timesheet.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/js/timesheet.js b/htdocs/core/js/timesheet.js index 0c8c9ff3245..e9e66787aa0 100644 --- a/htdocs/core/js/timesheet.js +++ b/htdocs/core/js/timesheet.js @@ -1,5 +1,6 @@ /* Copyright (C) 2014 delcroip * Copyright (C) 2015-2017 Laurent Destailleur + * Copyright (C) 2021 Josep Lluís Amador * * 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 @@ -257,7 +258,7 @@ function updateTotal(days,mode) result=parseTime(jQuery('.totalDay'+stringdays).text(),taskTime); if (result >= 0) { - totalhour = totalhour + taskTime.getHours(); + totalhour = totalhour + taskTime.getHours() + result*24; totalmin = totalmin + taskTime.getMinutes(); } } From fdd0ab8461c46556b0fcc11e3aae539eb3401589 Mon Sep 17 00:00:00 2001 From: atm-florian Date: Wed, 28 Jul 2021 23:56:44 +0200 Subject: [PATCH 15/52] FIX $conf->task used but it does not exist, use $conf->projet instead --- .../modules/project/task/doc/doc_generic_task_odt.modules.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php index 566c7f07a2e..638ab70bb84 100644 --- a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php +++ b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php @@ -524,8 +524,8 @@ class doc_generic_task_odt extends ModelePDFTask //print "conf->societe->dir_temp=".$conf->societe->dir_temp; dol_mkdir($conf->projet->dir_temp); - if (!is_writable($conf->task->dir_temp)) { - $this->error = "Failed to write in temp directory ".$conf->task->dir_temp; + if (!is_writable($conf->projet->dir_temp)) { + $this->error = "Failed to write in temp directory ".$conf->projet->dir_temp; dol_syslog('Error in write_file: '.$this->error, LOG_ERR); return -1; } From 262dd1600b67fec20c028e4021c12456951e3549 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Thu, 29 Jul 2021 06:23:12 +0200 Subject: [PATCH 16/52] FIX: Invoice - Missing button to reopen an abandoned situation invoice --- htdocs/compta/facture/card.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 519f40c254a..fe5d5c3ab0a 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -5206,7 +5206,8 @@ elseif ($id > 0 || !empty($ref)) // Reopen a standard paid invoice if ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) || ($object->type == Facture::TYPE_CREDIT_NOTE && empty($discount->id)) - || ($object->type == Facture::TYPE_DEPOSIT && empty($discount->id))) + || ($object->type == Facture::TYPE_DEPOSIT && empty($discount->id)) + || ($object->type == Facture::TYPE_SITUATION && empty($discount->id))) && ($object->statut == Facture::STATUS_CLOSED || $object->statut == Facture::STATUS_ABANDONED || ($object->statut == 1 && $object->paye == 1)) // Condition ($object->statut == 1 && $object->paye == 1) should not happened but can be found due to corrupted data && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || $usercanreopen)) // A paid invoice (partially or completely) { From da482018d217d7cfe149b0e91630a3d1718d82b7 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Thu, 29 Jul 2021 10:51:51 +0200 Subject: [PATCH 17/52] Fix for php 8 --- htdocs/core/class/CMailFile.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 5683c8e6a07..33db393bbc6 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -1628,7 +1628,7 @@ class CMailFile * @return array array of email => name * @see getValidAddress() */ - public function getArrayAddress($address) + public static function getArrayAddress($address) { global $conf; From ae5bb956accb6dc81c266f8c90f2806b955db178 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 29 Jul 2021 17:18:05 +0200 Subject: [PATCH 18/52] fix invoice in stand registration pb --- htdocs/core/class/commonobject.class.php | 6 +- htdocs/core/class/html.form.class.php | 4 + .../conferenceorbooth_card.php | 45 +++++- .../conferenceorbooth_list.php | 2 - .../conferenceorboothattendee_card.php | 10 +- .../tpl/linkedobjectblock.tpl.php | 47 +++++++ htdocs/langs/en_US/eventorganization.lang | 2 + htdocs/public/payment/paymentok.php | 9 +- htdocs/public/project/suggestbooth.php | 130 ++++++++++-------- 9 files changed, 191 insertions(+), 64 deletions(-) create mode 100644 htdocs/eventorganization/tpl/linkedobjectblock.tpl.php diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index ceac7015065..36df3b1a7b9 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3791,7 +3791,6 @@ abstract class CommonObject } elseif ($objecttype == 'contact') { $module = 'societe'; } - // Set classfile $classfile = strtolower($subelement); $classname = ucfirst($subelement); @@ -3823,6 +3822,11 @@ abstract class CommonObject $classfile = 'conferenceorboothattendee'; $classname = 'ConferenceOrBoothAttendee'; $module = 'eventorganization'; + } elseif ($objecttype == 'conferenceorbooth') { + $classpath = 'eventorganization/class'; + $classfile = 'conferenceorbooth'; + $classname = 'ConferenceOrBooth'; + $module = 'eventorganization'; } // Here $module, $classfile and $classname are set diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 816e0a79225..d548c7d91e1 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -7642,6 +7642,10 @@ class Form $tplpath = 'expensereport'; } elseif ($objecttype == 'subscription') { $tplpath = 'adherents'; + } elseif ($objecttype == 'conferenceorbooth') { + $tplpath = 'eventorganization'; + } elseif ($objecttype == 'conferenceorboothattendee') { + $tplpath = 'eventorganization'; } global $linkedObjectBlock; diff --git a/htdocs/eventorganization/conferenceorbooth_card.php b/htdocs/eventorganization/conferenceorbooth_card.php index f983994c4ec..6ae9ab9664b 100644 --- a/htdocs/eventorganization/conferenceorbooth_card.php +++ b/htdocs/eventorganization/conferenceorbooth_card.php @@ -330,7 +330,15 @@ if (!empty($withproject)) { print ""; print ''.$langs->trans("EventOrganizationICSLink").''; - print ''; + // Define $urlwithroot + $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); + $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; + + // Show message + $message = 'global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...'); + $message .= "&project=".$projectstatic->id.'&module='.urlencode('@eventorganization').'&status='.ConferenceOrBooth::STATUS_CONFIRMED.'">'.$langs->trans('DownloadICSLink').''; + print $message; print ""; print ''; @@ -496,6 +504,41 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $keyforbreak='pubregister'; include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; + $object->fetchObjectLinked(); + + + if (is_array($object->linkedObjects) && count($object->linkedObjects)>0 && array_key_exists("facture", $object->linkedObjects)) { + foreach ($object->linkedObjects["facture"] as $fac) { + /** + * @var $fac Facture + */ + if (empty($fac->paye)) { + $key = 'paymentlink_'.$fac->id; + print ''; + print img_picto('', 'globe').' '.$langs->trans("ToOfferALinkForOnlinePayment", $langs->transnoentitiesnoconv('Online')) . ' '. $fac->ref.'
'; + print ''; + + print ''; + $sourcetouse = 'boothlocation'; + $reftouse = $fac->id; + $redirection = $dolibarr_main_url_root.'/public/payment/newpayment.php?source='.$sourcetouse.'&ref='.$reftouse.'&booth='.$object->id; + if (!empty($conf->global->PAYMENT_SECURITY_TOKEN)) { + if (!empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) { + $redirection .= '&securekey='.dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . $sourcetouse . $reftouse, 2); // Use the source in the hash to avoid duplicates if the references are identical + } else { + $redirection .= '&securekey='.$conf->global->PAYMENT_SECURITY_TOKEN; + } + } + print ''; + print ''; + print ''; + } + } + } //var_dump($object); // Other attributes. Fields from hook formObjectOptions and Extrafields. include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; diff --git a/htdocs/eventorganization/conferenceorbooth_list.php b/htdocs/eventorganization/conferenceorbooth_list.php index 0b1221006a8..ab595e8b86e 100644 --- a/htdocs/eventorganization/conferenceorbooth_list.php +++ b/htdocs/eventorganization/conferenceorbooth_list.php @@ -421,8 +421,6 @@ if ($projectid > 0) { $message = 'global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...'); $message .= "&project=".$projectid.'&module='.urlencode('@eventorganization').'&status='.ConferenceOrBooth::STATUS_CONFIRMED.'">'.$langs->trans('DownloadICSLink').''; - $message .= ''; - $message .= '
'; print $message; print ""; diff --git a/htdocs/eventorganization/conferenceorboothattendee_card.php b/htdocs/eventorganization/conferenceorboothattendee_card.php index c5f3a91b10e..fe5ea292e8b 100644 --- a/htdocs/eventorganization/conferenceorboothattendee_card.php +++ b/htdocs/eventorganization/conferenceorboothattendee_card.php @@ -336,7 +336,15 @@ if (!empty($withproject)) { print ""; print ''.$langs->trans("EventOrganizationICSLink").''; - print ''; + // Define $urlwithroot + $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); + $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; + + // Show message + $message = 'global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...'); + $message .= "&project=".$projectstatic->id.'&module='.urlencode('@eventorganization').'&status='.ConferenceOrBooth::STATUS_CONFIRMED.'">'.$langs->trans('DownloadICSLink').''; + print $message; print ""; print ''; diff --git a/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php b/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php new file mode 100644 index 00000000000..f67e086a575 --- /dev/null +++ b/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php @@ -0,0 +1,47 @@ + + * Copyright (C) 2013 Juanjo Menent + * Copyright (C) 2014 Marcos García + * + * 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 . + */ + +// Protection to avoid direct call of template +if (empty($conf) || !is_object($conf)) { + print "Error, template page can't be called as URL"; + exit; +} + +echo "\n"; + +global $user; + +$langs = $GLOBALS['langs']; +$linkedObjectBlock = $GLOBALS['linkedObjectBlock']; +$langs->load("eventorganization"); + +$total = 0; +foreach ($linkedObjectBlock as $key => $objectlink) { + echo ''; + echo '' . $langs->trans(get_class($objectlink)) . ''; + echo ''.$objectlink->getNomUrl(1).''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''.img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink').''; + echo ''; +} + +echo "\n"; diff --git a/htdocs/langs/en_US/eventorganization.lang b/htdocs/langs/en_US/eventorganization.lang index f361e6bc192..67a242e640a 100644 --- a/htdocs/langs/en_US/eventorganization.lang +++ b/htdocs/langs/en_US/eventorganization.lang @@ -119,6 +119,8 @@ EventType = Event type LabelOfBooth=Booth label LabelOfconference=Conference label ConferenceIsNotConfirmed=Subcription not available, conference is not confirmed yet +DateMustBeBeforeThan=%s must be before %s +DateMustBeAfterThan=%s must be after %s # # Vote page diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 2f566d4bb31..4db8a62a625 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -1031,6 +1031,8 @@ if ($ispaymentok) { if ($resultattendee < 0) { setEventMessages(null, $attendeetovalidate->errors, "errors"); } else { + $attendeetovalidate->amount=$FinalPaymentAmt; + $attendeetovalidate->update($user); $attendeetovalidate->validate($user); // Sending mail @@ -1051,8 +1053,9 @@ if ($ispaymentok) { $arraydefaultmessage = null; $labeltouse = $conf->global->EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_EVENT; + if (!empty($labeltouse)) { - $arraydefaultmessage = $formmail->getEMailTemplate($db, 'eventorganization_send', $user, $outputlangs, $labeltouse, 1, ''); + $arraydefaultmessage = $formmail->getEMailTemplate($db, 'conferenceorbooth', $user, $outputlangs, $labeltouse, 1, ''); } if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) { @@ -1066,7 +1069,7 @@ if ($ispaymentok) { $subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs); $texttosend = make_substitutions($msg, $substitutionarray, $outputlangs); - $sendto = $thirdparty->email; + $sendto = $attendeetovalidate->email; $from = $conf->global->MAILING_EMAIL_FROM; $urlback = $_SERVER["REQUEST_URI"]; @@ -1233,7 +1236,7 @@ if ($ispaymentok) { $labeltouse = $conf->global->EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_EVENT; if (!empty($labeltouse)) { - $arraydefaultmessage = $formmail->getEMailTemplate($db, 'eventorganization_send', $user, $outputlangs, $labeltouse, 1, ''); + $arraydefaultmessage = $formmail->getEMailTemplate($db, 'conferenceorbooth', $user, $outputlangs, $labeltouse, 1, ''); } if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) { diff --git a/htdocs/public/project/suggestbooth.php b/htdocs/public/project/suggestbooth.php index 3ab8e165c7e..c695ea9cec1 100644 --- a/htdocs/public/project/suggestbooth.php +++ b/htdocs/public/project/suggestbooth.php @@ -81,9 +81,8 @@ $email = GETPOST("email"); $societe = GETPOST("societe"); $label = GETPOST("label"); $note = GETPOST("note"); -$datestart = GETPOST("datestart"); -$dateend = GETPOST("dateend"); - +$datestart = dol_mktime(0, 0, 0, GETPOST('datestartmonth', 'int'), GETPOST('datestartday', 'int'), GETPOST('datestartyear', 'int')); +$dateend = dol_mktime(23, 59, 59, GETPOST('dateendmonth', 'int'), GETPOST('dateendday', 'int'), GETPOST('dateendyear', 'int')); $id = GETPOST('id'); $project = new Project($db); @@ -225,13 +224,19 @@ if (empty($reshook) && $action == 'add') { $error++; $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Note"))."
\n"; } - if (!GETPOST("datestart")) { + if (empty($datestart)) { $error++; $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateStart"))."
\n"; + } elseif ($datestart < $project->date_start) { + $error++; + $errmsg .= $langs->trans("DateMustBeAfterThan", $langs->transnoentitiesnoconv("DateStart"), dol_print_date($project->date_start))."
\n"; } - if (!GETPOST("dateend")) { + if (empty($dateend)) { $error++; $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateEnd"))."
\n"; + } elseif ($dateend > dol_mktime(23, 59, 59, dol_print_date($project->date_end, '%m'), dol_print_date($project->date_end, '%d'), dol_print_date($project->date_end, '%Y'))) { + $error++; + $errmsg .= $langs->trans("DateMustBeBeforeThan", $langs->transnoentitiesnoconv("DateEnd"), dol_print_date($project->date_end))."
\n"; } if (!GETPOST("email")) { $error++; @@ -376,7 +381,7 @@ if (empty($reshook) && $action == 'add') { $conforbooth->fk_project = $project->id; $conforbooth->note = $note; $conforbooth->fk_action = $eventtype; - $conforbooth->datep =$datestart; + $conforbooth->datep = $datestart; $conforbooth->datep2 = $dateend; $conforbooth->datec = dol_now(); $conforbooth->tms = dol_now(); @@ -423,7 +428,7 @@ if (empty($reshook) && $action == 'add') { $error++; } else { $db->commit(); - $facture->add_object_linked($contact->element, $contact->id); + $facture->add_object_linked($conforbooth->element, $conforbooth->id); } } @@ -436,7 +441,7 @@ if (empty($reshook) && $action == 'add') { $contact->errors = $facture->errors; $error++; } - if (!$error) { + /*if (!$error) { $valid = true; $sourcetouse = 'boothlocation'; $reftouse = $facture->id; @@ -450,54 +455,12 @@ if (empty($reshook) && $action == 'add') { } Header("Location: ".$redirection); exit; - } + }*/ } } else { // If no price has been set for the booth, we confirm it as suggested and we update $conforbooth->status = ConferenceOrBooth::STATUS_SUGGESTED; $conforbooth->update($user); - // Sending mail - require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - // Set output language - $outputlangs = new Translate('', $conf); - $outputlangs->setDefaultLang(empty($thirdparty->default_lang) ? $mysoc->default_lang : $thirdparty->default_lang); - // Load traductions files required by page - $outputlangs->loadLangs(array("main", "members")); - // Get email content from template - $arraydefaultmessage = null; - - $labeltouse = $conf->global->EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_BOOTH; - if (!empty($labeltouse)) { - $arraydefaultmessage = $formmail->getEMailTemplate($db, 'conferenceorbooth', $user, $outputlangs, $labeltouse, 1, ''); - } - - if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) { - $subject = $arraydefaultmessage->topic; - $msg = $arraydefaultmessage->content; - } - - $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $thirdparty); - complete_substitutions_array($substitutionarray, $outputlangs, $object); - - $subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs); - $texttosend = make_substitutions($msg, $substitutionarray, $outputlangs); - - $sendto = $thirdparty->email; - $from = $conf->global->MAILING_EMAIL_FROM; - $urlback = $_SERVER["REQUEST_URI"]; - - $ishtml = dol_textishtml($texttosend); // May contain urls - - $mailfile = new CMailFile($subjecttosend, $sendto, $from, $texttosend, array(), array(), array(), '', '', 0, $ishtml); - - $result = $mailfile->sendfile(); - if ($result) { - dol_syslog("EMail sent to ".$sendto, LOG_DEBUG, 0, '_payment'); - } else { - dol_syslog("Failed to send EMail to ".$sendto, LOG_ERR, 0, '_payment'); - } } } } @@ -505,6 +468,50 @@ if (empty($reshook) && $action == 'add') { } if (!$error) { $db->commit(); + + // Sending mail + require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + // Set output language + $outputlangs = new Translate('', $conf); + $outputlangs->setDefaultLang(empty($thirdparty->default_lang) ? $mysoc->default_lang : $thirdparty->default_lang); + // Load traductions files required by page + $outputlangs->loadLangs(array("main", "members")); + // Get email content from template + $arraydefaultmessage = null; + + $labeltouse = $conf->global->EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_BOOTH; + if (!empty($labeltouse)) { + $arraydefaultmessage = $formmail->getEMailTemplate($db, 'conferenceorbooth', $user, $outputlangs, $labeltouse, 1, ''); + } + + if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) { + $subject = $arraydefaultmessage->topic; + $msg = $arraydefaultmessage->content; + } + + $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $thirdparty); + complete_substitutions_array($substitutionarray, $outputlangs, $object); + + $subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs); + $texttosend = make_substitutions($msg, $substitutionarray, $outputlangs); + + $sendto = $thirdparty->email; + $from = $conf->global->MAILING_EMAIL_FROM; + $urlback = $_SERVER["REQUEST_URI"]; + + $ishtml = dol_textishtml($texttosend); // May contain urls + + $mailfile = new CMailFile($subjecttosend, $sendto, $from, $texttosend, array(), array(), array(), '', '', 0, $ishtml); + + $result = $mailfile->sendfile(); + if ($result) { + dol_syslog("EMail sent to ".$sendto, LOG_DEBUG, 0, '_payment'); + } else { + dol_syslog("Failed to send EMail to ".$sendto, LOG_ERR, 0, '_payment'); + } + $securekeyurl = dol_hash($conf->global->EVENTORGANIZATION_SECUREKEY.'conferenceorbooth'.$id, 2); $redirection = $dolibarr_main_url_root.'/public/eventorganization/subscriptionok.php?id='.$id.'&securekey='.$securekeyurl; Header("Location: ".$redirection); @@ -630,12 +637,23 @@ print '*'."\n"; print ''."\n"; // Start Date -print ''.$langs->trans("DateStart").'*'."\n"; -print ''."\n"; +print ''.$langs->trans("DateStart").'*'; +if (!empty($project->date_start)) { + print '('.$langs->trans('Min'). ' '.dol_print_date($project->date_start).')'; +} +print ''."\n"; +print ''; +print $form->selectDate((empty($datestart)?$project->date_start:$datestart), 'datestart'); +print ''."\n"; // End Date -print ''.$langs->trans("DateEnd").'*'."\n"; -print ''."\n"; - +print ''.$langs->trans("DateEnd").'*'; +if (!empty($project->date_end)) { + print '('.$langs->trans('Max'). ' '.dol_print_date($project->date_end).')'; +} +print ''."\n"; +print ''; +print $form->selectDate(empty($dateend)?$project->date_end:$dateend, 'dateend'); +print ''."\n"; print "\n"; From 78646d10bb80f5b94ccaf7475ff6a544822d5b09 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 29 Jul 2021 17:26:17 +0200 Subject: [PATCH 19/52] tpl object linked --- .../tpl/linkedobjectblock.tpl.php | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php b/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php index f67e086a575..f2bb6f0c3ae 100644 --- a/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php +++ b/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php @@ -36,10 +36,24 @@ foreach ($linkedObjectBlock as $key => $objectlink) { echo ''; echo '' . $langs->trans(get_class($objectlink)) . ''; echo ''.$objectlink->getNomUrl(1).''; - echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + if (get_class($objectlink)=='ConferenceOrBooth') { + print dol_trunc($objectlink->label, 20); + } + print ''; + echo ''; + if (get_class($objectlink)=='ConferenceOrBoothAttendee') { + print dol_print_date($objectlink->date_subscription); + } else { + print dol_print_date($objectlink->datep); + } + print ''; + echo ''; + if (get_class($objectlink)=='ConferenceOrBoothAttendee') { + print price($objectlink->amount); + } + print ''; + echo ''.$objectlink->getLibStatut(3).''; echo ''.img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink').''; echo ''; } From 12b2ba64eb7a8a2dd5f6b84c0d692e1bdf0e040b Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Thu, 29 Jul 2021 17:49:37 +0200 Subject: [PATCH 20/52] Fix right check on thirdparty set on ticket card --- htdocs/ticket/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php index aaf5b29a985..08d9330a4c6 100644 --- a/htdocs/ticket/card.php +++ b/htdocs/ticket/card.php @@ -449,7 +449,7 @@ if (empty($reshook)) { } // Set parent company - if ($action == 'set_thirdparty' && $user->rights->societe->creer) { + if ($action == 'set_thirdparty' && $user->rights->ticket->write) { if ($object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')) >= 0) { $result = $object->setCustomer(GETPOST('editcustomer', 'int')); $url = 'card.php?action=view&track_id=' . GETPOST('track_id', 'alpha'); From 6f3080c67c1e1bb5678e4f3cbc1b488568ae8b82 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 29 Jul 2021 19:24:12 +0200 Subject: [PATCH 21/52] send mail from ConfOrBooth list to attendees or santd company --- htdocs/core/class/html.formmail.class.php | 2 +- .../conferenceorbooth_contact.php | 10 +- .../conferenceorbooth_document.php | 11 +- .../conferenceorbooth_list.php | 15 +- .../conferenceorboothattendee_list.php | 10 +- .../core/actions_massactions_mail.inc.php | 315 ++++++++++++++++++ .../tpl/massactions_mail_pre.tpl.php | 130 ++++++++ .../mysql/data/llx_c_email_templates.sql | 12 +- htdocs/langs/fr_FR/eventorganization.lang | 4 +- 9 files changed, 492 insertions(+), 17 deletions(-) create mode 100644 htdocs/eventorganization/core/actions_massactions_mail.inc.php create mode 100644 htdocs/eventorganization/tpl/massactions_mail_pre.tpl.php diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index 06b6a18b870..9da814f3369 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -1255,7 +1255,7 @@ class FormMail extends Form */ public function getEMailTemplate($db, $type_template, $user, $outputlangs, $id = 0, $active = 1, $label = '') { - global $conf; + global $conf, $langs; $ret = new ModelMail(); diff --git a/htdocs/eventorganization/conferenceorbooth_contact.php b/htdocs/eventorganization/conferenceorbooth_contact.php index 4906a4e05e3..8595da92652 100644 --- a/htdocs/eventorganization/conferenceorbooth_contact.php +++ b/htdocs/eventorganization/conferenceorbooth_contact.php @@ -309,7 +309,15 @@ if (!empty($withproject)) { print ""; print ''.$langs->trans("EventOrganizationICSLink").''; - print ''; + // Define $urlwithroot + $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); + $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; + + // Show message + $message = 'global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...'); + $message .= "&project=".$projectstatic->id.'&module='.urlencode('@eventorganization').'&status='.ConferenceOrBooth::STATUS_CONFIRMED.'">'.$langs->trans('DownloadICSLink').''; + print $message; print ""; print ''; diff --git a/htdocs/eventorganization/conferenceorbooth_document.php b/htdocs/eventorganization/conferenceorbooth_document.php index fc3673d618f..8b064c12b72 100644 --- a/htdocs/eventorganization/conferenceorbooth_document.php +++ b/htdocs/eventorganization/conferenceorbooth_document.php @@ -266,8 +266,15 @@ if (!empty($withproject)) { print ""; print ''.$langs->trans("EventOrganizationICSLink").''; - print ''; - //TODO fill with ics + // Define $urlwithroot + $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); + $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; + + // Show message + $message = 'global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...'); + $message .= "&project=".$projectstatic->id.'&module='.urlencode('@eventorganization').'&status='.ConferenceOrBooth::STATUS_CONFIRMED.'">'.$langs->trans('DownloadICSLink').''; + print $message; print ""; print ''; diff --git a/htdocs/eventorganization/conferenceorbooth_list.php b/htdocs/eventorganization/conferenceorbooth_list.php index ab595e8b86e..270c87fb15c 100644 --- a/htdocs/eventorganization/conferenceorbooth_list.php +++ b/htdocs/eventorganization/conferenceorbooth_list.php @@ -173,7 +173,10 @@ if (GETPOST('cancel', 'alpha')) { $action = 'list'; $massaction = ''; } -if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { +if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' + && $massaction != 'presend_attendees' + && $massaction != 'confirm_presend' + && $massaction != 'confirm_presend_attendees') { $massaction = ''; } @@ -211,6 +214,7 @@ if (empty($reshook)) { $objectclass = 'ConferenceOrBooth'; $objectlabel = 'ConferenceOrBooth'; $uploaddir = $conf->eventorganization->dir_output; + include DOL_DOCUMENT_ROOT.'/eventorganization/core/actions_massactions_mail.inc.php'; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } @@ -581,12 +585,13 @@ $arrayofmassactions = array( //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"), //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"), //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), - //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), + 'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail").' - '.$langs->trans("ConferenceOrBooth"), + 'presend_attendees'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail").' - '.$langs->trans("Attendees"), ); if ($permissiontodelete) { $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); } -if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) { +if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'presend_attendees', 'predelete'))) { $arrayofmassactions = array(); } $massactionbutton = $form->selectMassAction('', $arrayofmassactions); @@ -610,9 +615,11 @@ print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sort $topicmail = "SendConferenceOrBoothRef"; $modelmail = "conferenceorbooth"; $objecttmp = new ConferenceOrBooth($db); -$trackid = 'xxxx'.$object->id; +$trackid = 'conferenceorbooth_'.$object->id; +include DOL_DOCUMENT_ROOT.'/eventorganization/tpl/massactions_mail_pre.tpl.php'; include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; + if ($search_all) { foreach ($fieldstosearchall as $key => $val) { $fieldstosearchall[$key] = $langs->trans($val); diff --git a/htdocs/eventorganization/conferenceorboothattendee_list.php b/htdocs/eventorganization/conferenceorboothattendee_list.php index 658640d5834..e8e86a2641a 100644 --- a/htdocs/eventorganization/conferenceorboothattendee_list.php +++ b/htdocs/eventorganization/conferenceorboothattendee_list.php @@ -499,7 +499,15 @@ if ($confOrBooth->id > 0) { print ""; print ''.$langs->trans("EventOrganizationICSLink").''; - print ''; + // Define $urlwithroot + $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); + $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; + + // Show message + $message = 'global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...'); + $message .= "&project=".$projectstatic->id.'&module='.urlencode('@eventorganization').'&status='.ConferenceOrBooth::STATUS_CONFIRMED.'">'.$langs->trans('DownloadICSLink').''; + print $message; print ""; print ''; diff --git a/htdocs/eventorganization/core/actions_massactions_mail.inc.php b/htdocs/eventorganization/core/actions_massactions_mail.inc.php new file mode 100644 index 00000000000..483a1e5bc84 --- /dev/null +++ b/htdocs/eventorganization/core/actions_massactions_mail.inc.php @@ -0,0 +1,315 @@ + + * Copyright (C) 2018-2021 Nicolas ZABOURI + * Copyright (C) 2018 Juanjo Menent + * Copyright (C) 2019 Ferran Marcet + * Copyright (C) 2019-2021 Frédéric 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 . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/core/actions_massactions.inc.php + * \brief Code for actions done with massaction button (send by email, merge pdf, delete, ...) + */ + + +// $massaction must be defined +// $objectclass and $objectlabel must be defined +// $parameters, $object, $action must be defined for the hook. + +// $permissiontoread, $permissiontoadd, $permissiontodelete, $permissiontoclose may be defined +// $uploaddir may be defined (example to $conf->projet->dir_output."/";) +// $toselect may be defined +// $diroutputmassaction may be defined + + +// Protection +if (empty($objectclass) || empty($uploaddir)) { + dol_print_error(null, 'include of actions_massactions.inc.php is done but var $objectclass or $uploaddir was not defined'); + exit; +} + +// For backward compatibility +if (!empty($permtoread) && empty($permissiontoread)) { + $permissiontoread = $permtoread; +} +if (!empty($permtocreate) && empty($permissiontoadd)) { + $permissiontoadd = $permtocreate; +} +if (!empty($permtodelete) && empty($permissiontodelete)) { + $permissiontodelete = $permtodelete; +} + + +// Mass actions. Controls on number of lines checked. +$maxformassaction = (empty($conf->global->MAIN_LIMIT_FOR_MASS_ACTIONS) ? 1000 : $conf->global->MAIN_LIMIT_FOR_MASS_ACTIONS); +if (!empty($massaction) && is_array($toselect) && count($toselect) < 1) { + $error++; + setEventMessages($langs->trans("NoRecordSelected"), null, "warnings"); +} +if (!$error && is_array($toselect) && count($toselect) > $maxformassaction) { + setEventMessages($langs->trans('TooManyRecordForMassAction', $maxformassaction), null, 'errors'); + $error++; +} + +if (!$error && $massaction == 'confirm_presend_attendees' && !GETPOST('sendmail')) { // If we do not choose button send (for example when we change template or limit), we must not send email, but keep on send email form + $massaction = 'presend_attendees'; +} +if (!$error && $massaction == 'confirm_presend_attendees') { + $resaction = ''; + $nbsent = 0; + $nbignored = 0; + $langs->load("mails"); + include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + + $listofobjectid = array(); + + $listofobjectref = array(); + $oneemailperrecipient = (GETPOST('oneemailperrecipient') == 'on' ? 1 : 0); + + if (!$error) { + require_once DOL_DOCUMENT_ROOT . '/eventorganization/class/conferenceorboothattendee.class.php'; + $attendee = new ConferenceOrBoothAttendee($db); + $listofselectedid = array(); + $listofselectedref = array(); + $objecttmp = new $objectclass($db); + + foreach ($toselect as $toselectid) { + $result = $objecttmp->fetch($toselectid); + if ($result > 0) { + $attendees = $attendee->fetchAll('', '', 0, 0, array('t.fk_actioncomm' => $objecttmp->id)); + if (is_array($attendees) && count($attendees) > 0) { + foreach ($attendees as $attmail) { + if (!empty($attmail->email)) { + $attmail->fetch_thirdparty(); + $listofselectedid[$attmail->email] = $attmail; + $listofselectedref[$attmail->email] = $objecttmp; + } + } + } + } + } + } + + // Check mandatory parameters + if (GETPOST('fromtype', 'alpha') === 'user' && empty($user->email)) { + $error++; + setEventMessages($langs->trans("NoSenderEmailDefined"), null, 'warnings'); + $massaction = 'presend_attendees'; + } + + $receiver = $_POST['receiver']; + if (!is_array($receiver)) { + if (empty($receiver) || $receiver == '-1') { + $receiver = array(); + } else { + $receiver = array($receiver); + } + } + if (!trim($_POST['sendto']) && count($receiver) == 0 && count($listofselectedid) == 1) { // if only one recipient, receiver is mandatory + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Recipient")), null, 'warnings'); + $massaction = 'presend_attendees'; + } + + if (!GETPOST('subject', 'restricthtml')) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("MailTopic")), null, 'warnings'); + $massaction = 'presend_attendees'; + } + + if (!$error) { + $objecttmp->fetch_thirdparty(); + foreach ($listofselectedid as $email => $attendees) { + $sendto = ''; + $sendtocc = ''; + $sendtobcc = ''; + $sendtoid = array(); + + // Define $sendto + $sendto = $attendees->thirdparty->name . '<' . trim($attendees->email) . '>'; + + // Define $sendtocc + $receivercc = $_POST['receivercc']; + if (!is_array($receivercc)) { + if ($receivercc == '-1') { + $receivercc = array(); + } else { + $receivercc = array($receivercc); + } + } + $tmparray = array(); + if (trim($_POST['sendtocc'])) { + $tmparray[] = trim($_POST['sendtocc']); + } + $sendtocc = implode(',', $tmparray); + + + $langs->load("commercial"); + + $reg = array(); + $fromtype = GETPOST('fromtype'); + if ($fromtype === 'user') { + $from = $user->getFullName($langs) . ' <' . $user->email . '>'; + } elseif ($fromtype === 'company') { + $from = $conf->global->MAIN_INFO_SOCIETE_NOM . ' <' . $conf->global->MAIN_INFO_SOCIETE_MAIL . '>'; + } elseif (preg_match('/user_aliases_(\d+)/', $fromtype, $reg)) { + $tmp = explode(',', $user->email_aliases); + $from = trim($tmp[($reg[1] - 1)]); + } elseif (preg_match('/global_aliases_(\d+)/', $fromtype, $reg)) { + $tmp = explode(',', $conf->global->MAIN_INFO_SOCIETE_MAIL_ALIASES); + $from = trim($tmp[($reg[1] - 1)]); + } elseif (preg_match('/senderprofile_(\d+)_(\d+)/', $fromtype, $reg)) { + $sql = 'SELECT rowid, label, email FROM ' . MAIN_DB_PREFIX . 'c_email_senderprofile WHERE rowid = ' . (int) $reg[1]; + $resql = $db->query($sql); + $obj = $db->fetch_object($resql); + if ($obj) { + $from = $obj->label . ' <' . $obj->email . '>'; + } + } else { + $from = $_POST['fromname'] . ' <' . $_POST['frommail'] . '>'; + } + + $replyto = $from; + $subject = GETPOST('subject', 'restricthtml'); + $message = GETPOST('message', 'restricthtml'); + + $sendtobcc = GETPOST('sendtoccc'); + + // $objecttmp is a real object or an empty object if we choose to send one email per thirdparty instead of one per object + // Make substitution in email content + $substitutionarray = getCommonSubstitutionArray($langs, 0, null, $attendees); + + if (!empty($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY)) { + $urlwithouturlroot = preg_replace('/' . preg_quote(DOL_URL_ROOT, '/') . '$/i', '', trim($dolibarr_main_url_root)); + $urlwithroot = $urlwithouturlroot . DOL_URL_ROOT; + $url_link = $urlwithroot . '/public/agenda/agendaexport.php?format=ical' . ($conf->entity > 1 ? "&entity=" . $conf->entity : ""); + $url_link .= '&exportkey=' . ($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ? urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...'); + $url_link .= "&project=" . $listofselectedref[$email]->fk_project . '&module=' . urlencode('@eventorganization') . '&status=' . ConferenceOrBooth::STATUS_CONFIRMED; + $html_link = '' . $langs->trans('DownloadICSLink') . ''; + } + $substitutionarray['__EVENTORGANIZATION_ICS_LINK__'] = $html_link; + $substitutionarray['__EVENTORGANIZATION_URL_LINK__'] = $url_link; + $substitutionarray['__CHECK_READ__'] = ''; + + $parameters = array('mode' => 'formemail'); + + if (!empty($listofobjectref)) { + $parameters['listofobjectref'] = $listofobjectref; + } + + complete_substitutions_array($substitutionarray, $langs, $attendees, $parameters); + + $subjectreplaced = make_substitutions($subject, $substitutionarray); + $messagereplaced = make_substitutions($message, $substitutionarray); + + + if (empty($sendcontext)) { + $sendcontext = 'standard'; + } + + // Send mail (substitutionarray must be done just before this) + require_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subjectreplaced, $sendto, $from, $messagereplaced, array(), array(), array(), $sendtocc, $sendtobcc, $deliveryreceipt, -1, '', '', "attendees_".$attendees->id, '', $sendcontext); + if ($mailfile->error) { + $resaction .= '
' . $mailfile->error . '
'; + } else { + $result = $mailfile->sendfile(); + if ($result) { + $resaction .= $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($from, 2), $mailfile->getValidAddress($sendto, 2)) . '
'; // Must not contain " + $error = 0; + + dol_syslog("Try to insert email event into agenda for objid=" . $attendees->id . " => objectobj=" . get_class($attendees)); + + $actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto; + if ($message) { + if ($sendtocc) { + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc); + } + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subjectreplaced); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":"); + $actionmsg = dol_concatdesc($actionmsg, $messagereplaced); + } + $actionmsg2 = ''; + + $objectobj2 = $listofselectedref[$email]; + // Initialisation donnees + $objectobj2->actionmsg = $actionmsg; // Long text + $objectobj2->actionmsg2 = $actionmsg2; // Short text + $objectobj2->fk_element = $objectobj2->id; + $objectobj2->elementtype = $objectobj2->element; + + $triggername = 'CONFERENCEORBOOTHATTENDEE_SENTBYMAIL'; + if (!empty($triggername)) { + // Call trigger + $result = $objectobj2->call_trigger($triggername, $user); + if ($result < 0) { + $error++; + } + // End call triggers + + if ($error) { + setEventMessages($db->lasterror(), $objectobj2->errors, 'errors'); + dol_syslog("Error in trigger " . $triggername . ' ' . $db->lasterror(), LOG_ERR); + } + } + + $nbsent++; // Nb of object sent + } else { + $langs->load("other"); + if ($mailfile->error) { + $resaction .= $langs->trans('ErrorFailedToSendMail', $from, $sendto); + $resaction .= '
' . $mailfile->error . '
'; + } elseif (!empty($conf->global->MAIN_DISABLE_ALL_MAILS)) { + $resaction .= '
No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS
'; + } else { + $resaction .= $langs->trans('ErrorFailedToSendMail', $from, $sendto) . '
(unhandled error)
'; + } + } + } + } + } + $resaction .= ($resaction ? '
' : $resaction); + $resaction .= '' . $langs->trans("ResultOfMailSending") . ':
' . "\n"; + $resaction .= $langs->trans("NbSelected") . ': ' . count($toselect) . "\n
"; + $resaction .= $langs->trans("NbIgnored") . ': ' . ($nbignored ? $nbignored : 0) . "\n
"; + $resaction .= $langs->trans("NbSent") . ': ' . ($nbsent ? $nbsent : 0) . "\n
"; + + if ($nbsent) { + $action = ''; // Do not show form post if there was at least one successfull sent + //setEventMessages($langs->trans("EMailSentToNRecipients", $nbsent.'/'.count($toselect)), null, 'mesgs'); + setEventMessages($langs->trans("EMailSentForNElements", $nbsent . '/' . count($toselect)), null, 'mesgs'); + setEventMessages($resaction, null, 'mesgs'); + } else { + //setEventMessages($langs->trans("EMailSentToNRecipients", 0), null, 'warnings'); // May be object has no generated PDF file + setEventMessages($resaction, null, 'warnings'); + } + + $action = 'list'; + $massaction = ''; +} + + + +$parameters['toselect'] = $toselect; +$parameters['uploaddir'] = $uploaddir; +$parameters['massaction'] = $massaction; +$parameters['diroutputmassaction'] = isset($diroutputmassaction) ? $diroutputmassaction : null; + +$reshook = $hookmanager->executeHooks('doMassActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} diff --git a/htdocs/eventorganization/tpl/massactions_mail_pre.tpl.php b/htdocs/eventorganization/tpl/massactions_mail_pre.tpl.php new file mode 100644 index 00000000000..17c78babfea --- /dev/null +++ b/htdocs/eventorganization/tpl/massactions_mail_pre.tpl.php @@ -0,0 +1,130 @@ + + * Copyright (C) 2013-2014 Laurent Destailleur + * Copyright (C) 2015 Marcos García + * + * 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/ + */ + +// Following var must be set: +// $arrayofselected = array of id selected +// $object +// $objecttmp=new Propal($db); +// $topicmail="SendSupplierProposalRef"; +// $modelmail="supplier_proposal_send"; +// $trackid='ord'.$object->id; + +if ($massaction == 'presend_attendees') { + $langs->load("mails"); + require_once DOL_DOCUMENT_ROOT.'/eventorganization/class/conferenceorboothattendee.class.php'; + $attendee = new ConferenceOrBoothAttendee($db); + $listofselectedid = array(); + $listofselectedref = array(); + + if (!GETPOST('cancel', 'alpha')) { + foreach ($arrayofselected as $toselectid) { + $result = $objecttmp->fetch($toselectid); + if ($result > 0) { + $attendees = $attendee->fetchAll('', '', 0, 0, array('t.fk_actioncomm'=>$objecttmp->id)); + if (is_array($attendees) && count($attendees)>0) { + foreach ($attendees as $attmail) { + if (!empty($attmail->email)) { + $listofselectedid[$attmail->email] = $attmail->id; + $listofselectedref[$attmail->id][$toselectid] = $objecttmp->ref; + } + } + } + } + } + } + + print ''; + print ''; + + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + + print dol_get_fiche_head(null, '', ''); + + // Cree l'objet formulaire mail + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + $formmail->withform = -1; + $formmail->fromtype = (GETPOST('fromtype') ? GETPOST('fromtype') : (!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE) ? $conf->global->MAIN_MAIL_DEFAULT_FROMTYPE : 'user')); + + if ($formmail->fromtype === 'user') { + $formmail->fromid = $user->id; + } + $formmail->trackid = $trackid; + if (!empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) { // If bit 2 is set + include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $formmail->frommail = dolAddEmailTrackId($formmail->frommail, $trackid); + } + $formmail->withfrom = 1; + $liste = $langs->trans("AllRecipientSelected", count($listofselectedid)); + $formmail->withtoreadonly = 1; + + $formmail->withoptiononeemailperrecipient = ((count($listofselectedref) == 1 && count(reset($listofselectedref)) == 1) || empty($liste)) ? 0 : ((GETPOST('oneemailperrecipient') == 'on') ? 1 : -1); + + $formmail->withto = empty($liste) ? (GETPOST('sendto', 'alpha') ?GETPOST('sendto', 'alpha') : array()) : $liste; + $formmail->withtofree = empty($liste) ? 1 : 0; + $formmail->withtocc = 1; + $formmail->withtoccc = $conf->global->MAIN_EMAIL_USECCC; + $formmail->withtopic = $langs->transnoentities($topicmail, '__REF__', '__REF_CLIENT__'); + $formmail->withfile = 0; + // $formmail->withfile = 2; Not yet supported in mass action + $formmail->withmaindocfile = 0; // Add a checkbox "Attach also main document" + $formmail->withbody = 1; + $formmail->withdeliveryreceipt = 1; + $formmail->withcancel = 1; + + // Make substitution in email content + $substitutionarray = getCommonSubstitutionArray($langs, 0, null, $object); + + $substitutionarray['__EMAIL__'] = $sendto; + $substitutionarray['__CHECK_READ__'] = (is_object($object) && is_object($object->thirdparty)) ? '' : ''; + $substitutionarray['__PERSONALIZED__'] = ''; // deprecated + $substitutionarray['__CONTACTCIVNAME__'] = ''; + + $parameters = array( + 'mode' => 'formemail' + ); + complete_substitutions_array($substitutionarray, $langs, $object, $parameters); + + // Tableau des substitutions + $formmail->substit = $substitutionarray; + + // Tableau des parametres complementaires du post + $formmail->param['action'] = $action; + $formmail->param['models'] = $modelmail; + $formmail->param['models_id'] = empty(GETPOST('modelmailselected', 'int'))?$conf->global->EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_ATTENDES:GETPOST('modelmailselected', 'int'); + $formmail->param['id'] = join(',', $arrayofselected); + // $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; + if (!empty($conf->global->MAILING_LIMIT_SENDBYWEB) && count($listofselectedid) > $conf->global->MAILING_LIMIT_SENDBYWEB) { + $langs->load("errors"); + print img_warning().' '.$langs->trans('WarningNumberOfRecipientIsRestrictedInMassAction', $conf->global->MAILING_LIMIT_SENDBYWEB); + print ' - '.$langs->trans("GoBack").''; + $arrayofmassactions = array(); + } else { + print $formmail->get_form(); + } + + print dol_get_fiche_end(); +} +// Allow Pre-Mass-Action hook (eg for confirmation dialog) +$parameters = array( + 'toselect' => $toselect, + 'uploaddir' => isset($uploaddir) ? $uploaddir : null +); diff --git a/htdocs/install/mysql/data/llx_c_email_templates.sql b/htdocs/install/mysql/data/llx_c_email_templates.sql index e2b1cd65077..393875dd40f 100644 --- a/htdocs/install/mysql/data/llx_c_email_templates.sql +++ b/htdocs/install/mysql/data/llx_c_email_templates.sql @@ -35,9 +35,9 @@ INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0,'recruitment','recruitmentcandidature_send','',0,null,null,'(AnswerCandidature)' ,100,'$conf->recruitment->enabled',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourCandidature)__', '__(Hello)__ __CANDIDATE_FULLNAME__,

\n\n__(YourCandidatureAnswerMessage)__
__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__\n

\n__(Sincerely)__
__USER_SIGNATURE__',null, 0); -- Event organization -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, 'EventOrganizationEmailAskConf', 10, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskConf)__', '__(Hello)__ __THIRDPARTY_NAME__,

__(ThisIsContentOfYourOrganizationEventConfRequestWasReceived)__

__ONLINE_PAYMENT_TEXT_AND_URL__


__(Sincerely)__
__USER_SIGNATURE__', null, '1', null); -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, 'EventOrganizationEmailAskBooth', 20, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskBooth)__', '__(Hello)__ __THIRDPARTY_NAME__,

__(ThisIsContentOfYourOrganizationEventBoothRequestWasReceived)__

__ONLINE_PAYMENT_TEXT_AND_URL__


__(Sincerely)__
__USER_SIGNATURE__', null, '1', null); -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, 'EventOrganizationEmailSubsBooth', 30, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailSubsBooth)__', '__(Hello)__ __THIRDPARTY_NAME__,

__(ThisIsContentOfYourOrganizationEventBoothSubscriptionWasReceived)__

__ONLINE_PAYMENT_TEXT_AND_URL__


__(Sincerely)__
__USER_SIGNATURE__', null, '1', null); -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, 'EventOrganizationEmailSubsEvent', 40, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailSubsEvent)__', '__(Hello)__ __THIRDPARTY_NAME__,

__(ThisIsContentOfYourOrganizationEventEventSubscriptionWasReceived)__

__(Sincerely)__

__MYCOMPANY_NAME__
__USER_SIGNATURE__', null, '1', null); -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, 'EventOrganizationMassEmailAttendees', 50, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailAttendees)__', '__(Hello)__ __THIRDPARTY_NAME__,

__(ThisIsContentOfYourOrganizationEventBulkMailToAttendees)__

__(Sincerely)__
__USER_SIGNATURE__', null, '1', null); -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, 'EventOrganizationMassEmailSpeakers', 60, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailSpeakers)__', '__(Hello)__ __THIRDPARTY_NAME__,

__(ThisIsContentOfYourOrganizationEventBulkMailToSpeakers)__

__(Sincerely)__
__USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailAskConf)', 10, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskConf)__', '__(Hello)__ __THIRDPARTY_NAME__,

__(ThisIsContentOfYourOrganizationEventConfRequestWasReceived)__

__ONLINE_PAYMENT_TEXT_AND_URL__


__(Sincerely)__
__USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailAskBooth)', 20, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskBooth)__', '__(Hello)__ __THIRDPARTY_NAME__,

__(ThisIsContentOfYourOrganizationEventBoothRequestWasReceived)__

__ONLINE_PAYMENT_TEXT_AND_URL__


__(Sincerely)__
__USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailSubsBooth)', 30, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailSubsBooth)__', '__(Hello)__ __THIRDPARTY_NAME__,

__(ThisIsContentOfYourOrganizationEventBoothSubscriptionWasReceived)__

__ONLINE_PAYMENT_TEXT_AND_URL__


__(Sincerely)__
__USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailSubsEvent)', 40, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailSubsEvent)__', '__(Hello)__ __THIRDPARTY_NAME__,

__(ThisIsContentOfYourOrganizationEventEventSubscriptionWasReceived)__

__(Sincerely)__

__MYCOMPANY_NAME__
__USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationMassEmailAttendees)', 50, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailAttendees)__', '__(Hello)__ __THIRDPARTY_NAME__,

__(ThisIsContentOfYourOrganizationEventBulkMailToAttendees)__

__(Sincerely)__
__USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationMassEmailSpeakers)', 60, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailSpeakers)__', '__(Hello)__ __THIRDPARTY_NAME__,

__(ThisIsContentOfYourOrganizationEventBulkMailToSpeakers)__

__(Sincerely)__
__USER_SIGNATURE__', null, '1', null); diff --git a/htdocs/langs/fr_FR/eventorganization.lang b/htdocs/langs/fr_FR/eventorganization.lang index 7ef2977adc3..ef7de0fd710 100644 --- a/htdocs/langs/fr_FR/eventorganization.lang +++ b/htdocs/langs/fr_FR/eventorganization.lang @@ -40,8 +40,8 @@ EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_CONF = Modèle de courriel à envoyer aprè EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_BOOTH = Modèle de courriel à envoyer après avoir reçu une suggestion d'un stand. EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_BOOTH = Modèle de courriel à envoyer après paiement d'une inscription à un stand. EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_EVENT = Modèle de courriel à envoyer après paiement d'une inscription à un événement. -EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_SPEAKER = Modèle de courriel pour action de masse aux participants -EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_ATTENDES = Modèle de courriel pour action de masse aux intervenants +EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_SPEAKER = Modèle de courriel pour action de masse aux intervenants +EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_ATTENDES = Modèle de courriel pour action de masse aux participants EVENTORGANIZATION_FILTERATTENDEES_CAT = Filtrer la liste de sélection des tiers dans la fiche/le formulaire de création des participants avec/selon la catégorie EVENTORGANIZATION_FILTERATTENDEES_TYPE = Filtrer la liste de sélection des tiers dans la fiche/le formulaire de création des participants avec le type de client From f02dee2e2128e07b5f11082fcc8eb307085cf941 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 29 Jul 2021 23:47:59 +0200 Subject: [PATCH 22/52] Fix test on missing install.lock --- htdocs/admin/system/security.php | 13 ++++++++++++- htdocs/langs/en_US/admin.lang | 3 ++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 032a23a68c8..79690032901 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -30,7 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/events.class.php'; // Load translation files required by the page -$langs->loadLangs(array("install", "other", "admin")); +$langs->loadLangs(array("install", "other", "admin", "errors")); if (!$user->admin) { accessforbidden(); @@ -198,6 +198,7 @@ if (empty($fileswithwritepermission)) { } } print '
'; +print '
'; print ''.$langs->trans("PermissionsOnFile", $conffile).': '; // $conffile is defined into filefunc.inc.php $perms = fileperms($dolibarr_main_document_root.'/'.$conffile); @@ -219,6 +220,16 @@ if ($perms) { print img_warning().' '.$langs->trans("FailedToReadFile", $conffile); } print '
'; +print '
'; + +$installlock = DOL_DATA_ROOT.'/install.lock'; +print ''.$langs->trans("DolibarrSetup").': '; +if (file_exists($installlock)) { + print img_picto('', 'tick').' '.$langs->trans("InstallAndUpgradeLockedBy", $installlock); +} else { + print img_warning().' '.$langs->trans("WarningLockFileDoesNotExists", DOL_DATA_ROOT); +} +print '
'; // File conf.php diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index aca631eef99..76f5c18b70b 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2148,4 +2148,5 @@ RandomlySelectedIfSeveral=Randomly selected if several pictures are available DatabasePasswordObfuscated=Database password is obfuscated in conf file DatabasePasswordNotObfuscated=Database password is NOT obfuscated in conf file APIsAreNotEnabled=APIs modules are not enabled -YouShouldSetThisToOff=You should set this to 0 or off \ No newline at end of file +YouShouldSetThisToOff=You should set this to 0 or off +InstallAndUpgradeLockedBy=Install and upgrades are locked by the file %s \ No newline at end of file From 9954a0e4bb654dae4cfe40ced290e3ad8c48cb01 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 30 Jul 2021 00:40:06 +0200 Subject: [PATCH 23/52] Fix status of tickets --- htdocs/langs/en_US/ticket.lang | 8 +++++--- htdocs/ticket/card.php | 20 ++++++++++++++++---- htdocs/ticket/class/ticket.class.php | 27 ++++++++++++++------------- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/htdocs/langs/en_US/ticket.lang b/htdocs/langs/en_US/ticket.lang index 3c074688b8e..0b54b1d5fa8 100644 --- a/htdocs/langs/en_US/ticket.lang +++ b/htdocs/langs/en_US/ticket.lang @@ -66,7 +66,7 @@ NeedMoreInformation=Waiting for reporter feedback NeedMoreInformationShort=Waiting for feedback Answered=Answered Waiting=Waiting -Closed=Closed +SolvedClosed=Solved Deleted=Deleted # Dict @@ -186,9 +186,11 @@ TicketSeverity=Severity ShowTicket=See ticket RelatedTickets=Related tickets TicketAddIntervention=Create intervention -CloseTicket=Close ticket -CloseATicket=Close a ticket +CloseTicket=Close|Solve ticket +AbandonTicket=Abandon ticket +CloseATicket=Close|Solve a ticket ConfirmCloseAticket=Confirm ticket closing +ConfirmAbandonTicket=Do you confirm the closing of the ticket to status 'Abandonned' ConfirmDeleteTicket=Please confirm ticket deleting TicketDeletedSuccess=Ticket deleted with success TicketMarkedAsClosed=Ticket marked as closed diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php index 5faa7b201b7..cbdb0f7a6df 100644 --- a/htdocs/ticket/card.php +++ b/htdocs/ticket/card.php @@ -426,10 +426,10 @@ if (empty($reshook)) { } } - if ($action == "confirm_close" && GETPOST('confirm', 'alpha') == 'yes' && $user->rights->ticket->write) { + if (($action == "confirm_close" || $action == "confirm_abandon") && GETPOST('confirm', 'alpha') == 'yes' && $user->rights->ticket->write) { $object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')); - if ($object->close($user)) { + if ($object->close($user, ($action == "confirm_abandon" ? 1 : 0))) { setEventMessages($langs->trans('TicketMarkedAsClosed'), null, 'mesgs'); $url = 'card.php?action=view&track_id='.GETPOST('track_id', 'alpha'); @@ -749,7 +749,7 @@ if ($action == 'create' || $action == 'presend') { print ''; print ''; */ -} elseif (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'dellink' || $action == 'presend' || $action == 'presend_addmessage' || $action == 'close' || $action == 'delete' || $action == 'editcustomer' || $action == 'progression' || $action == 'reopen' +} elseif (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'dellink' || $action == 'presend' || $action == 'presend_addmessage' || $action == 'close' || $action == 'abandon' || $action == 'delete' || $action == 'editcustomer' || $action == 'progression' || $action == 'reopen' || $action == 'editsubject' || $action == 'edit_extras' || $action == 'update_extras' || $action == 'edit_extrafields' || $action == 'set_extrafields' || $action == 'classify' || $action == 'sel_contract' || $action == 'edit_message_init' || $action == 'set_status' || $action == 'dellink') { if ($res > 0) { // or for unauthorized internals users @@ -764,6 +764,13 @@ if ($action == 'create' || $action == 'presend') { print '
'; } } + // Confirmation abandon + if ($action == 'abandon') { + print $form->formconfirm($url_page_current."?track_id=".$object->track_id, $langs->trans("AbandonTicket"), $langs->trans("ConfirmAbandonTicket"), "confirm_abandon", '', '', 1); + if ($ret == 'html') { + print '
'; + } + } // Confirmation delete if ($action == 'delete') { print $form->formconfirm($url_page_current."?track_id=".$object->track_id, $langs->trans("Delete"), $langs->trans("ConfirmDeleteTicket"), "confirm_delete_ticket", '', '', 1); @@ -1296,8 +1303,13 @@ if ($action == 'create' || $action == 'presend') { print ''; } + // Abadon ticket if statut is read + if ($object->fk_statut > 0 && $object->fk_statut < Ticket::STATUS_CLOSED && $user->rights->ticket->write) { + print ''; + } + // Re-open ticket - if (!$user->socid && $object->fk_statut == Ticket::STATUS_CLOSED && !$user->socid) { + if (!$user->socid && ($object->fk_statut == Ticket::STATUS_CLOSED || $object->fk_statut == Ticket::STATUS_CANCELED) && !$user->socid) { print ''; } diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 89f239db6c6..b67d7922d97 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -218,8 +218,8 @@ class Ticket extends CommonObject const STATUS_IN_PROGRESS = 3; const STATUS_NEED_MORE_INFO = 5; const STATUS_WAITING = 7; // on hold - const STATUS_CLOSED = 8; - const STATUS_CANCELED = 9; + const STATUS_CLOSED = 8; // Closed - Solved + const STATUS_CANCELED = 9; // Closed - Not solved /** @@ -272,8 +272,8 @@ class Ticket extends CommonObject 'message' => array('type'=>'text', 'label'=>'Message', 'visible'=>-2, 'enabled'=>1, 'position'=>540, 'notnull'=>-1,), 'email_msgid' => array('type'=>'varchar(255)', 'label'=>'EmailMsgID', 'visible'=>-2, 'enabled'=>1, 'position'=>540, 'notnull'=>-1, 'help'=>'EmailMsgIDDesc'), 'progress' => array('type'=>'varchar(100)', 'label'=>'Progression', 'visible'=>-1, 'enabled'=>1, 'position'=>540, 'notnull'=>-1, 'css'=>'right', 'help'=>"", 'isameasure'=>1), - 'resolution' => array('type'=>'integer', 'label'=>'Resolution', 'visible'=>-1, 'enabled'=>1, 'position'=>550, 'notnull'=>1), - 'fk_statut' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>600, 'notnull'=>1, 'index'=>1, 'arrayofkeyval'=>array(0 => 'Unread', 1 => 'Read', 3 => 'Answered', 4 => 'Assigned', 5 => 'InProgress', 6 => 'Waiting', 8 => 'Closed', 9 => 'Deleted')), + //'resolution' => array('type'=>'integer', 'label'=>'Resolution', 'visible'=>-1, 'enabled'=>1, 'position'=>550, 'notnull'=>1), + 'fk_statut' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>600, 'notnull'=>1, 'index'=>1, 'arrayofkeyval'=>array(0 => 'Unread', 1 => 'Read', 3 => 'Answered', 4 => 'Assigned', 5 => 'InProgress', 6 => 'Waiting', 8 => 'SolvedClosed', 9 => 'Deleted')), 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>900), ); // END MODULEBUILDER PROPERTIES @@ -295,7 +295,7 @@ class Ticket extends CommonObject self::STATUS_IN_PROGRESS => 'InProgress', self::STATUS_WAITING => 'OnHold', self::STATUS_NEED_MORE_INFO => 'NeedMoreInformationShort', - self::STATUS_CLOSED => 'Closed', + self::STATUS_CLOSED => 'SolvedClosed', self::STATUS_CANCELED => 'Canceled' ); $this->statuts = array( @@ -305,7 +305,7 @@ class Ticket extends CommonObject self::STATUS_IN_PROGRESS => 'InProgress', self::STATUS_WAITING => 'OnHold', self::STATUS_NEED_MORE_INFO => 'NeedMoreInformation', - self::STATUS_CLOSED => 'Closed', + self::STATUS_CLOSED => 'SolvedClosed', self::STATUS_CANCELED => 'Canceled' ); } @@ -1747,21 +1747,22 @@ class Ticket extends CommonObject /** * Close a ticket * - * @param User $user User that close - * @return int <0 if KO, >0 if OK + * @param User $user User that close + * @param int $mode 0=Close solved, 1=Close abandonned + * @return int <0 if KO, >0 if OK */ - public function close(User $user) + public function close(User $user, $mode = 0) { global $conf, $langs; - if ($this->fk_statut != Ticket::STATUS_CLOSED) { // not closed + if ($this->fk_statut != Ticket::STATUS_CLOSED && $this->fk_statut != Ticket::STATUS_CANCELED) { // not closed $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."ticket"; - $sql .= " SET fk_statut=".Ticket::STATUS_CLOSED.", progress=100, date_close='".$this->db->idate(dol_now())."'"; - $sql .= " WHERE rowid = ".$this->id; + $sql .= " SET fk_statut=".($mode ? Ticket::STATUS_CANCELED : Ticket::STATUS_CLOSED).", progress=100, date_close='".$this->db->idate(dol_now())."'"; + $sql .= " WHERE rowid = ".((int) $this->id); - dol_syslog(get_class($this)."::close sql=".$sql); + dol_syslog(get_class($this)."::close mode=".$mode); $resql = $this->db->query($sql); if ($resql) { $error = 0; From 0c3bf536f2e2b5aaa82d87185f9026139696cd72 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 30 Jul 2021 01:10:15 +0200 Subject: [PATCH 24/52] Fix field resolution --- htdocs/core/modules/modTicket.class.php | 16 +++++++++++--- htdocs/ticket/class/ticket.class.php | 4 +++- htdocs/ticket/list.php | 28 +++++++++++++++++-------- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/htdocs/core/modules/modTicket.class.php b/htdocs/core/modules/modTicket.class.php index 8b1a1dc8525..b78125753b2 100644 --- a/htdocs/core/modules/modTicket.class.php +++ b/htdocs/core/modules/modTicket.class.php @@ -122,8 +122,18 @@ class modTicket extends DolibarrModules } $this->dictionaries = array( 'langs' => 'ticket', - 'tabname' => array(MAIN_DB_PREFIX."c_ticket_type", MAIN_DB_PREFIX."c_ticket_severity", MAIN_DB_PREFIX."c_ticket_category", MAIN_DB_PREFIX."c_ticket_resolution"), - 'tablib' => array("TicketDictType", "TicketDictSeverity", "TicketDictCategory", "TicketDictResolution"), + 'tabname' => array( + MAIN_DB_PREFIX."c_ticket_type", + MAIN_DB_PREFIX."c_ticket_severity", + MAIN_DB_PREFIX."c_ticket_category", + MAIN_DB_PREFIX."c_ticket_resolution" + ), + 'tablib' => array( + "TicketDictType", + "TicketDictSeverity", + "TicketDictCategory", + "TicketDictResolution" + ), 'tabsql' => array( 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM '.MAIN_DB_PREFIX.'c_ticket_type as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM '.MAIN_DB_PREFIX.'c_ticket_severity as f', @@ -135,7 +145,7 @@ class modTicket extends DolibarrModules 'tabfieldvalue' => array("code,label,pos,use_default", "code,label,pos,use_default", "code,label,pos,use_default,public", "code,label,pos,use_default"), 'tabfieldinsert' => array("code,label,pos,use_default", "code,label,pos,use_default", "code,label,pos,use_default,public", "code,label,pos,use_default"), 'tabrowid' => array("rowid", "rowid", "rowid", "rowid"), - 'tabcond' => array($conf->ticket->enabled, $conf->ticket->enabled, $conf->ticket->enabled, $conf->ticket->enabled), + 'tabcond' => array($conf->ticket->enabled, $conf->ticket->enabled, $conf->ticket->enabled, $conf->ticket->enabled && !empty($conf->global->TICKET_ENABLE_RESOLUTION)), 'tabhelp' => array( array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")), array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")), diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index b67d7922d97..1d449a57e17 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -272,7 +272,7 @@ class Ticket extends CommonObject 'message' => array('type'=>'text', 'label'=>'Message', 'visible'=>-2, 'enabled'=>1, 'position'=>540, 'notnull'=>-1,), 'email_msgid' => array('type'=>'varchar(255)', 'label'=>'EmailMsgID', 'visible'=>-2, 'enabled'=>1, 'position'=>540, 'notnull'=>-1, 'help'=>'EmailMsgIDDesc'), 'progress' => array('type'=>'varchar(100)', 'label'=>'Progression', 'visible'=>-1, 'enabled'=>1, 'position'=>540, 'notnull'=>-1, 'css'=>'right', 'help'=>"", 'isameasure'=>1), - //'resolution' => array('type'=>'integer', 'label'=>'Resolution', 'visible'=>-1, 'enabled'=>1, 'position'=>550, 'notnull'=>1), + 'resolution' => array('type'=>'integer', 'label'=>'Resolution', 'visible'=>-1, 'enabled'=>'$conf->global->TICKET_ENABLE_RESOLUTION', 'position'=>550, 'notnull'=>1), 'fk_statut' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>600, 'notnull'=>1, 'index'=>1, 'arrayofkeyval'=>array(0 => 'Unread', 1 => 'Read', 3 => 'Answered', 4 => 'Assigned', 5 => 'InProgress', 6 => 'Waiting', 8 => 'SolvedClosed', 9 => 'Deleted')), 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>900), ); @@ -286,6 +286,8 @@ class Ticket extends CommonObject */ public function __construct($db) { + global $conf; + $this->db = $db; $this->statuts_short = array( diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index 6a65efc8bac..5a55a1ab324 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -45,9 +45,9 @@ $show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk $confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation $cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button $toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list -$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'tickep#selectedfieldstlist'; // To manage different context of search +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'tickep#selectedfieldstlist'; // To manage different context of search $backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page -$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') +$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') $id = GETPOST('id', 'int'); $msg_id = GETPOST('msg_id', 'int'); @@ -73,8 +73,9 @@ $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) { + // If $page is not defined, or '' or -1 or if we click on clear filters $page = 0; -} // If $page is not defined, or '' or -1 or if we click on clear filters +} $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; @@ -107,12 +108,16 @@ if (GETPOST('search_fk_status', 'alpha') == 'non_closed') { } // Initialize array of search criterias -$search_all = trim(GETPOSTISSET("search_all") ?GETPOSTISSET("search_all", 'alpha') : GETPOST('sall')); +$search_all = (GETPOSTISSET("search_all") ? GETPOST("search_all", 'alpha') : GETPOST('sall')); $search = array(); foreach ($object->fields as $key => $val) { - if (GETPOST('search_'.$key, 'alpha')) { + if (GETPOST('search_'.$key, 'alpha') !== '') { $search[$key] = GETPOST('search_'.$key, 'alpha'); } + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int')); + $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int')); + } } // List of fields to search into when doing a "search in all" @@ -126,12 +131,19 @@ $fieldstosearchall['s.name_alias'] = "AliasNameShort"; $fieldstosearchall['s.zip'] = "Zip"; $fieldstosearchall['s.town'] = "Town"; -// Definition of fields for list +// Definition of array of fields for columns $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $arrayfields['t.'.$key] = array('label'=>$val['label'], 'checked'=>(($val['visible'] < 0) ? 0 : 1), 'enabled'=>$val['enabled'], 'position'=>$val['position']); + $visible = (int) dol_eval($val['visible'], 1); + $arrayfields['t.'.$key] = array( + 'label'=>$val['label'], + 'checked'=>(($visible < 0) ? 0 : 1), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'position'=>$val['position'], + 'help'=> isset($val['help']) ? $val['help'] : '' + ); } } // Extra fields @@ -139,8 +151,6 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; $object->fields = dol_sort_array($object->fields, 'position'); $arrayfields = dol_sort_array($arrayfields, 'position'); -//if ($socid > 0) $arrayfields['t.fk_soc']['enabled']=0; -//if ($projectid > 0) $arrayfields['t.fk_project']['enabled']=0; // Security check From 593e84906b93f09414b9aeb225bfbed395efe391 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 30 Jul 2021 01:16:04 +0200 Subject: [PATCH 25/52] FIX bad closing div on error message --- htdocs/public/ticket/create_ticket.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/public/ticket/create_ticket.php b/htdocs/public/ticket/create_ticket.php index 1d0339f83f8..8f2657b9db6 100644 --- a/htdocs/public/ticket/create_ticket.php +++ b/htdocs/public/ticket/create_ticket.php @@ -390,7 +390,7 @@ if ($action != "infos_success") { print '
'; print $langs->trans("ErrorFieldRequired", $langs->transnoentities("TicketEmailNotificationFrom")).'
'; print $langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentities("Ticket")); - print '
'; + print '
'; } else { print '
'.$langs->trans('TicketPublicInfoCreateTicket').'
'; $formticket->showForm(0, 'edit', 1); From 047c575d613070117ec363ecf270d410ef364b56 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 30 Jul 2021 01:42:52 +0200 Subject: [PATCH 26/52] Fix some errors on ticket module --- .../interface_50_modAgenda_ActionsAuto.class.php | 6 +++++- htdocs/public/ticket/create_ticket.php | 3 +-- htdocs/public/ticket/view.php | 6 ++++-- htdocs/ticket/card.php | 12 +++++++++--- htdocs/ticket/class/ticket.class.php | 2 +- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php index 8e23c258d88..d0597f617fb 100644 --- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php +++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php @@ -936,7 +936,11 @@ class InterfaceActionsAuto extends DolibarrTriggers } } - $object->actionmsg = dol_concatdesc($langs->transnoentities("Author").': '.$user->login, $object->actionmsg); + if (!empty($user->login)) { + $object->actionmsg = dol_concatdesc($langs->transnoentities("Author").': '.$user->login, $object->actionmsg); + } elseif (isset($object->origin_email)) { + $object->actionmsg = dol_concatdesc($langs->transnoentities("Author").': '.$object->origin_email, $object->actionmsg); + } dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); diff --git a/htdocs/public/ticket/create_ticket.php b/htdocs/public/ticket/create_ticket.php index 8f2657b9db6..b911e7480d3 100644 --- a/htdocs/public/ticket/create_ticket.php +++ b/htdocs/public/ticket/create_ticket.php @@ -258,7 +258,7 @@ if (empty($reshook) && $action == 'create_ticket' && GETPOST('add', 'alpha')) { $sendto = GETPOST('email', 'alpha'); - $from = $conf->global->MAIN_INFO_SOCIETE_NOM.'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>'; + $from = $conf->global->MAIN_INFO_SOCIETE_NOM.' <'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>'; $replyto = $from; $sendtocc = ''; $deliveryreceipt = 0; @@ -298,7 +298,6 @@ if (empty($reshook) && $action == 'create_ticket' && GETPOST('add', 'alpha')) { } $message_admin .= ''; - $message_admin .= ''; $message_admin .= '

'.$langs->trans('Message').' :
'.$object->message.'

'; $message_admin .= '

'.$langs->trans('SeeThisTicketIntomanagementInterface').'

'; diff --git a/htdocs/public/ticket/view.php b/htdocs/public/ticket/view.php index 3fec075160b..6485f9fcee2 100644 --- a/htdocs/public/ticket/view.php +++ b/htdocs/public/ticket/view.php @@ -262,8 +262,10 @@ if ($action == "view_ticket" || $action == "presend" || $action == "close" || $a // Category print ''.$langs->trans("Category").''; - print img_picto('', 'category', 'class="pictofixedwidth"'); - print dol_escape_htmltag($object->dao->category_label); + if ($object->dao->category_label) { + print img_picto('', 'category', 'class="pictofixedwidth"'); + print dol_escape_htmltag($object->dao->category_label); + } print ''; // Severity diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php index cbdb0f7a6df..bbb563a1486 100644 --- a/htdocs/ticket/card.php +++ b/htdocs/ticket/card.php @@ -1126,15 +1126,21 @@ if ($action == 'create' || $action == 'presend') { } else { // Type print ''.$langs->trans("Type").''; - print $langs->getLabelFromKey($db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code); + if (!empty($object->type_code)) { + print $langs->getLabelFromKey($db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code); + } print ''; // Group print ''.$langs->trans("TicketCategory").''; - print $langs->getLabelFromKey($db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code); + if (!empty($object->category_code)) { + print $langs->getLabelFromKey($db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code); + } print ''; // Severity print ''.$langs->trans("TicketSeverity").''; - print $langs->getLabelFromKey($db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code); + if (!empty($object->severity_code)) { + print $langs->getLabelFromKey($db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code); + } print ''; } print ''; // End table actions diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 1d449a57e17..d29a4913b6b 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -461,7 +461,7 @@ class Ticket extends CommonObject $sql .= " ".(!isset($this->progress) ? '0' : "'".$this->db->escape($this->progress)."'").","; $sql .= " ".(!isset($this->timing) ? 'NULL' : "'".$this->db->escape($this->timing)."'").","; $sql .= " ".(!isset($this->type_code) ? 'NULL' : "'".$this->db->escape($this->type_code)."'").","; - $sql .= " ".(!isset($this->category_code) ? 'NULL' : "'".$this->db->escape($this->category_code)."'").","; + $sql .= " ".(empty($this->category_code) || $this->category_code == '-1' ? 'NULL' : "'".$this->db->escape($this->category_code)."'").","; $sql .= " ".(!isset($this->severity_code) ? 'NULL' : "'".$this->db->escape($this->severity_code)."'").","; $sql .= " ".(!isset($this->datec) || dol_strlen($this->datec) == 0 ? 'NULL' : "'".$this->db->idate($this->datec)."'").","; $sql .= " ".(!isset($this->date_read) || dol_strlen($this->date_read) == 0 ? 'NULL' : "'".$this->db->idate($this->date_read)."'").","; From 57d637ac713b5e2004614c683974e9701673c54d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 30 Jul 2021 01:49:43 +0200 Subject: [PATCH 27/52] Fix set status of a ticket --- htdocs/ticket/class/actions_ticket.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/ticket/class/actions_ticket.class.php b/htdocs/ticket/class/actions_ticket.class.php index b787a437899..d7d971b4edc 100644 --- a/htdocs/ticket/class/actions_ticket.class.php +++ b/htdocs/ticket/class/actions_ticket.class.php @@ -408,7 +408,7 @@ class ActionsTicket if ($status == 1) { $urlforbutton = $_SERVER['PHP_SELF'].'?track_id='.$object->track_id.'&action=mark_ticket_read'; // To set as read, we use a dedicated action } else { - $urlforbutton = $_SERVER['PHP_SELF'].'?track_id='.$object->track_id.'&action=set_status&token='.newToken().'&new_status='.$status; + $urlforbutton = $_SERVER['PHP_SELF'].'?track_id='.$object->track_id.'&action=confirm_set_status&token='.newToken().'&new_status='.$status; } print ''; From 8ea6fc3174e4e4d7fcd55bf3fe241ff5e7f85427 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Fri, 30 Jul 2021 09:38:29 +0200 Subject: [PATCH 28/52] fix: add hook management into product translation tab --- htdocs/product/traduction.php | 180 +++++++++++++++++++--------------- 1 file changed, 100 insertions(+), 80 deletions(-) diff --git a/htdocs/product/traduction.php b/htdocs/product/traduction.php index b2c3b0d0b2f..0cae81e36c7 100644 --- a/htdocs/product/traduction.php +++ b/htdocs/product/traduction.php @@ -62,98 +62,108 @@ if ($object->id > 0) { restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); } +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('producttranslationcard', 'globalcard')); + /* * Actions */ -// retour a l'affichage des traduction si annulation -if ($cancel == $langs->trans("Cancel")) { - $action = ''; +$parameters = array('id'=>$id, 'ref'=>$ref); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } - -if ($action == 'delete' && GETPOST('langtodelete', 'alpha')) { - $object = new Product($db); - $object->fetch($id); - $object->delMultiLangs(GETPOST('langtodelete', 'alpha'), $user); - setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs'); - $action = ''; -} - -// Add translation -if ($action == 'vadd' && $cancel != $langs->trans("Cancel") && ($user->rights->produit->creer || $user->rights->service->creer)) { - $object = new Product($db); - $object->fetch($id); - $current_lang = $langs->getDefaultLang(); - - // update de l'objet - if (GETPOST("forcelangprod") == $current_lang) { - $object->label = GETPOST("libelle"); - $object->description = dol_htmlcleanlastbr(GETPOST("desc", 'restricthtml')); - $object->other = dol_htmlcleanlastbr(GETPOST("other", 'restricthtml')); - - $object->update($object->id, $user); - } else { - $object->multilangs[GETPOST("forcelangprod")]["label"] = GETPOST("libelle"); - $object->multilangs[GETPOST("forcelangprod")]["description"] = dol_htmlcleanlastbr(GETPOST("desc", 'restricthtml')); - $object->multilangs[GETPOST("forcelangprod")]["other"] = dol_htmlcleanlastbr(GETPOST("other", 'restricthtml')); - } - - // save in database - if (GETPOST("forcelangprod")) { - $result = $object->setMultiLangs($user); - } else { - $object->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Language")); - $result = -1; - } - - if ($result > 0) { +if (empty($reshook)) { + // retour a l'affichage des traduction si annulation + if ($cancel == $langs->trans("Cancel")) { $action = ''; - } else { - $action = 'add'; - setEventMessages($object->error, $object->errors, 'errors'); } -} -// Edit translation -if ($action == 'vedit' && $cancel != $langs->trans("Cancel") && ($user->rights->produit->creer || $user->rights->service->creer)) { - $object = new Product($db); - $object->fetch($id); - $current_lang = $langs->getDefaultLang(); + if ($action == 'delete' && GETPOST('langtodelete', 'alpha')) { + $object = new Product($db); + $object->fetch($id); + $object->delMultiLangs(GETPOST('langtodelete', 'alpha'), $user); + setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs'); + $action = ''; + } - foreach ($object->multilangs as $key => $value) { // enregistrement des nouvelles valeurs dans l'objet - if ($key == $current_lang) { - $object->label = GETPOST("libelle-".$key); - $object->description = dol_htmlcleanlastbr(GETPOST("desc-".$key, 'restricthtml')); - $object->other = dol_htmlcleanlastbr(GETPOST("other-".$key, 'restricthtml')); + // Add translation + if ($action == 'vadd' && $cancel != $langs->trans("Cancel") && ($user->rights->produit->creer || $user->rights->service->creer)) { + $object = new Product($db); + $object->fetch($id); + $current_lang = $langs->getDefaultLang(); + + // update de l'objet + if (GETPOST("forcelangprod") == $current_lang) { + $object->label = GETPOST("libelle"); + $object->description = dol_htmlcleanlastbr(GETPOST("desc", 'restricthtml')); + $object->other = dol_htmlcleanlastbr(GETPOST("other", 'restricthtml')); + + $object->update($object->id, $user); } else { - $object->multilangs[$key]["label"] = GETPOST("libelle-".$key); - $object->multilangs[$key]["description"] = dol_htmlcleanlastbr(GETPOST("desc-".$key, 'restricthtml')); - $object->multilangs[$key]["other"] = dol_htmlcleanlastbr(GETPOST("other-".$key, 'restricthtml')); + $object->multilangs[GETPOST("forcelangprod")]["label"] = GETPOST("libelle"); + $object->multilangs[GETPOST("forcelangprod")]["description"] = dol_htmlcleanlastbr(GETPOST("desc", 'restricthtml')); + $object->multilangs[GETPOST("forcelangprod")]["other"] = dol_htmlcleanlastbr(GETPOST("other", 'restricthtml')); + } + + // save in database + if (GETPOST("forcelangprod")) { + $result = $object->setMultiLangs($user); + } else { + $object->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Language")); + $result = -1; + } + + if ($result > 0) { + $action = ''; + } else { + $action = 'add'; + setEventMessages($object->error, $object->errors, 'errors'); } } - $result = $object->setMultiLangs($user); - if ($result > 0) { - $action = ''; - } else { - $action = 'edit'; - setEventMessages($object->error, $object->errors, 'errors'); + // Edit translation + if ($action == 'vedit' && $cancel != $langs->trans("Cancel") && ($user->rights->produit->creer || $user->rights->service->creer)) { + $object = new Product($db); + $object->fetch($id); + $current_lang = $langs->getDefaultLang(); + + foreach ($object->multilangs as $key => $value) { // enregistrement des nouvelles valeurs dans l'objet + if ($key == $current_lang) { + $object->label = GETPOST("libelle-" . $key); + $object->description = dol_htmlcleanlastbr(GETPOST("desc-" . $key, 'restricthtml')); + $object->other = dol_htmlcleanlastbr(GETPOST("other-" . $key, 'restricthtml')); + } else { + $object->multilangs[$key]["label"] = GETPOST("libelle-" . $key); + $object->multilangs[$key]["description"] = dol_htmlcleanlastbr(GETPOST("desc-" . $key, 'restricthtml')); + $object->multilangs[$key]["other"] = dol_htmlcleanlastbr(GETPOST("other-" . $key, 'restricthtml')); + } + } + + $result = $object->setMultiLangs($user); + if ($result > 0) { + $action = ''; + } else { + $action = 'edit'; + setEventMessages($object->error, $object->errors, 'errors'); + } } -} -// Delete translation -if ($action == 'vdelete' && $cancel != $langs->trans("Cancel") && ($user->rights->produit->creer || $user->rights->service->creer)) { - $object = new Product($db); - $object->fetch($id); - $langtodelete = GETPOST('langdel', 'alpha'); + // Delete translation + if ($action == 'vdelete' && $cancel != $langs->trans("Cancel") && ($user->rights->produit->creer || $user->rights->service->creer)) { + $object = new Product($db); + $object->fetch($id); + $langtodelete = GETPOST('langdel', 'alpha'); - $result = $object->delMultiLangs($langtodelete, $user); - if ($result > 0) { - $action = ''; - } else { - $action = 'edit'; - setEventMessages($object->error, $object->errors, 'errors'); + $result = $object->delMultiLangs($langtodelete, $user); + if ($result > 0) { + $action = ''; + } else { + $action = 'edit'; + setEventMessages($object->error, $object->errors, 'errors'); + } } } @@ -216,11 +226,15 @@ print dol_get_fiche_end(); */ print "\n".'
'."\n"; -if ($action == '') { - if ($user->rights->produit->creer || $user->rights->service->creer) { - print ''.$langs->trans("Add").''; - if ($cnt_trans > 0) { - print ''.$langs->trans("Update").''; +$parameters = array(); +$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been +if (empty($reshook)) { + if ($action == '') { + if ($user->rights->produit->creer || $user->rights->service->creer) { + print '' . $langs->trans("Add") . ''; + if ($cnt_trans > 0) { + print '' . $langs->trans("Update") . ''; + } } } } @@ -263,6 +277,9 @@ if ($action == 'edit') { } } + $parameters = array(); + $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + print '
'; print '
'; @@ -334,6 +351,9 @@ if ($action == 'add' && ($user->rights->produit->creer || $user->rights->service } print ''; + $parameters = array(); + $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + print dol_get_fiche_end(); print '
'; From 63898426d23559a690e4d623dba3c59cf461f1b0 Mon Sep 17 00:00:00 2001 From: atm-florian Date: Fri, 30 Jul 2021 13:36:54 +0200 Subject: [PATCH 29/52] FIX: on admin/pdf.php (with javascript enabled) if you set some boolean confs then click on "save", all boolean values are reset --- htdocs/admin/pdf.php | 46 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/htdocs/admin/pdf.php b/htdocs/admin/pdf.php index d5873e2a50e..cee63fd91fd 100644 --- a/htdocs/admin/pdf.php +++ b/htdocs/admin/pdf.php @@ -52,22 +52,22 @@ if ($cancel) { } if ($action == 'update') { - dolibarr_set_const($db, "MAIN_PDF_FORMAT", GETPOST("MAIN_PDF_FORMAT"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_PDF_FORMAT')) dolibarr_set_const($db, "MAIN_PDF_FORMAT", GETPOST("MAIN_PDF_FORMAT"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PDF_MARGIN_LEFT", GETPOST("MAIN_PDF_MARGIN_LEFT"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PDF_MARGIN_RIGHT", GETPOST("MAIN_PDF_MARGIN_TOP"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PDF_MARGIN_BOTTOM", GETPOST("MAIN_PDF_MARGIN_BOTTOM"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_PDF_MARGIN_LEFT')) dolibarr_set_const($db, "MAIN_PDF_MARGIN_LEFT", GETPOST("MAIN_PDF_MARGIN_LEFT"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_PDF_MARGIN_RIGHT')) dolibarr_set_const($db, "MAIN_PDF_MARGIN_RIGHT", GETPOST("MAIN_PDF_MARGIN_TOP"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_PDF_MARGIN_BOTTOM')) dolibarr_set_const($db, "MAIN_PDF_MARGIN_BOTTOM", GETPOST("MAIN_PDF_MARGIN_BOTTOM"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PROFID1_IN_ADDRESS", GETPOST("MAIN_PROFID1_IN_ADDRESS"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PROFID2_IN_ADDRESS", GETPOST("MAIN_PROFID2_IN_ADDRESS"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PROFID3_IN_ADDRESS", GETPOST("MAIN_PROFID3_IN_ADDRESS"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PROFID4_IN_ADDRESS", GETPOST("MAIN_PROFID4_IN_ADDRESS"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PROFID5_IN_ADDRESS", GETPOST("MAIN_PROFID5_IN_ADDRESS"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PROFID6_IN_ADDRESS", GETPOST("MAIN_PROFID6_IN_ADDRESS"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_PROFID1_IN_ADDRESS')) dolibarr_set_const($db, "MAIN_PROFID1_IN_ADDRESS", GETPOST("MAIN_PROFID1_IN_ADDRESS"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_PROFID2_IN_ADDRESS')) dolibarr_set_const($db, "MAIN_PROFID2_IN_ADDRESS", GETPOST("MAIN_PROFID2_IN_ADDRESS"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_PROFID3_IN_ADDRESS')) dolibarr_set_const($db, "MAIN_PROFID3_IN_ADDRESS", GETPOST("MAIN_PROFID3_IN_ADDRESS"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_PROFID4_IN_ADDRESS')) dolibarr_set_const($db, "MAIN_PROFID4_IN_ADDRESS", GETPOST("MAIN_PROFID4_IN_ADDRESS"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_PROFID5_IN_ADDRESS')) dolibarr_set_const($db, "MAIN_PROFID5_IN_ADDRESS", GETPOST("MAIN_PROFID5_IN_ADDRESS"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_PROFID6_IN_ADDRESS')) dolibarr_set_const($db, "MAIN_PROFID6_IN_ADDRESS", GETPOST("MAIN_PROFID6_IN_ADDRESS"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT", GETPOST("MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT", GETPOST("MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_TVAINTRA_NOT_IN_ADDRESS", GETPOST("MAIN_TVAINTRA_NOT_IN_ADDRESS"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_TVAINTRA_NOT_IN_ADDRESS')) dolibarr_set_const($db, "MAIN_TVAINTRA_NOT_IN_ADDRESS", GETPOST("MAIN_TVAINTRA_NOT_IN_ADDRESS"), 'chaine', 0, '', $conf->entity); if (!empty($conf->projet->enabled)) { if (GETPOST('PDF_SHOW_PROJECT_REF_OR_LABEL') == 'no') { @@ -82,20 +82,20 @@ if ($action == 'update') { } } - dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS", GETPOST("MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_HIDE_DESC", GETPOST("MAIN_GENERATE_DOCUMENTS_HIDE_DESC"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_HIDE_REF", GETPOST("MAIN_GENERATE_DOCUMENTS_HIDE_REF"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS')) dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS", GETPOST("MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_GENERATE_DOCUMENTS_HIDE_DESC')) dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_HIDE_DESC", GETPOST("MAIN_GENERATE_DOCUMENTS_HIDE_DESC"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_GENERATE_DOCUMENTS_HIDE_REF')) dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_HIDE_REF", GETPOST("MAIN_GENERATE_DOCUMENTS_HIDE_REF"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_DOCUMENTS_LOGO_HEIGHT", GETPOST("MAIN_DOCUMENTS_LOGO_HEIGHT", 'int'), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_INVERT_SENDER_RECIPIENT", GETPOST("MAIN_INVERT_SENDER_RECIPIENT"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PDF_USE_ISO_LOCATION", GETPOST("MAIN_PDF_USE_ISO_LOCATION"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS", GETPOST("MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_DOCUMENTS_LOGO_HEIGHT')) dolibarr_set_const($db, "MAIN_DOCUMENTS_LOGO_HEIGHT", GETPOST("MAIN_DOCUMENTS_LOGO_HEIGHT", 'int'), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_INVERT_SENDER_RECIPIENT')) dolibarr_set_const($db, "MAIN_INVERT_SENDER_RECIPIENT", GETPOST("MAIN_INVERT_SENDER_RECIPIENT"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_PDF_USE_ISO_LOCATION')) dolibarr_set_const($db, "MAIN_PDF_USE_ISO_LOCATION", GETPOST("MAIN_PDF_USE_ISO_LOCATION"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS')) dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS", GETPOST("MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PDF_MAIN_HIDE_SECOND_TAX", GETPOST("MAIN_PDF_MAIN_HIDE_SECOND_TAX"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PDF_MAIN_HIDE_THIRD_TAX", GETPOST("MAIN_PDF_MAIN_HIDE_THIRD_TAX"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_PDF_MAIN_HIDE_SECOND_TAX')) dolibarr_set_const($db, "MAIN_PDF_MAIN_HIDE_SECOND_TAX", GETPOST("MAIN_PDF_MAIN_HIDE_SECOND_TAX"), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('MAIN_PDF_MAIN_HIDE_THIRD_TAX')) dolibarr_set_const($db, "MAIN_PDF_MAIN_HIDE_THIRD_TAX", GETPOST("MAIN_PDF_MAIN_HIDE_THIRD_TAX"), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "PDF_USE_ALSO_LANGUAGE_CODE", GETPOST('PDF_USE_ALSO_LANGUAGE_CODE', 'alpha'), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "SHOW_SUBPRODUCT_REF_IN_PDF", GETPOST('SHOW_SUBPRODUCT_REF_IN_PDF', 'alpha'), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('PDF_USE_ALSO_LANGUAGE_CODE')) dolibarr_set_const($db, "PDF_USE_ALSO_LANGUAGE_CODE", GETPOST('PDF_USE_ALSO_LANGUAGE_CODE', 'alpha'), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET('SHOW_SUBPRODUCT_REF_IN_PDF')) dolibarr_set_const($db, "SHOW_SUBPRODUCT_REF_IN_PDF", GETPOST('SHOW_SUBPRODUCT_REF_IN_PDF', 'alpha'), 'chaine', 0, '', $conf->entity); setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); From 0d70c8189778ac9ca348573a9e2b2193304b452b Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Fri, 30 Jul 2021 15:16:38 +0200 Subject: [PATCH 30/52] ix error in website module -> sitemap --- 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 aa2b357a794..23be98a3b8c 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -2326,7 +2326,7 @@ if ($action == 'generatesitemaps' && $usercanedit) { $domainname = $objp->virtualhost; } if (! preg_match('/^http/i', $domainname)) { - $domainname .= 'https://'.$domainname; + $domainname = 'https://'.$domainname; } //$pathofpage = $dolibarr_main_url_root.'/'.$pageurl.'.php'; From f830a0f5e243dd40306d1db216c3fa5da16f2e7a Mon Sep 17 00:00:00 2001 From: Christian Foellmann Date: Thu, 29 Jul 2021 17:32:06 +0200 Subject: [PATCH 31/52] fix `tomail` param in mail form usage --- htdocs/core/actions_sendmails.inc.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index 83a823edeb2..3c8e4a5fe73 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -186,6 +186,11 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST $tmparray[] = trim($_POST['sendto']); } + if (trim($_POST['tomail'])) { + // Recipients are provided as free text + $tmparray[] = trim($_POST['tomail']); + } + if (count($receiver) > 0) { // Recipient was provided from combo list foreach ($receiver as $key => $val) { From 9c626bede47eb796c7bffba059891e493d9c6200 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 30 Jul 2021 18:43:35 +0200 Subject: [PATCH 32/52] Fix dol_hash for sha256 --- htdocs/core/lib/security.lib.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 598802ea574..d64069aa923 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -98,7 +98,7 @@ function dol_decode($chain, $key = '1') * If constant MAIN_SECURITY_SALT is defined, we use it as a salt (used only if hashing algorightm is something else than 'password_hash'). * * @param string $chain String to hash - * @param string $type Type of hash ('0':auto will use MAIN_SECURITY_HASH_ALGO else md5, '1':sha1, '2':sha1+md5, '3':md5, '4':md5 for OpenLdap with no salt, '5':sha256). Use '3' here, if hash is not needed for security purpose, for security need, prefer '0'. + * @param string $type Type of hash ('0':auto will use MAIN_SECURITY_HASH_ALGO else md5, '1':sha1, '2':sha1+md5, '3':md5, '4':md5 for OpenLdap with no salt, '5':sha256, '6':password_hash). Use '3' here, if hash is not needed for security purpose, for security need, prefer '0'. * @return string Hash of string * @see getRandomPassword() */ @@ -124,8 +124,10 @@ function dol_hash($chain, $type = '0') return md5($chain); } elseif ($type == '4' || $type == 'md5openldap') { return '{md5}'.base64_encode(mhash(MHASH_MD5, $chain)); // For OpenLdap with md5 (based on an unencrypted password in base) - } elseif ($type == '5') { + } elseif ($type == '5' || $type == 'sha256') { return hash('sha256', $chain); + } elseif ($type == '6' || $type == 'password_hash') { + return password_hash($chain, PASSWORD_DEFAULT); } elseif (!empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'sha1') { return sha1($chain); } elseif (!empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'sha1md5') { From 9811569b2be6d8ebe6876d1a302f237cff30e43d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 31 Jul 2021 16:22:50 +0200 Subject: [PATCH 33/52] FIX #18289 #18294 --- htdocs/imports/emptyexample.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/imports/emptyexample.php b/htdocs/imports/emptyexample.php index a50a2fc9996..b919a3c4c3e 100644 --- a/htdocs/imports/emptyexample.php +++ b/htdocs/imports/emptyexample.php @@ -102,13 +102,13 @@ if ($attachment) { // List of targets fields -$headerlinefields = array(); -$contentlinevalues = array(); +$headerlinefields = array(); // Array of fields (label to show) +$contentlinevalues = array(); // Array of example values $i = 0; foreach ($fieldstarget as $code => $label) { $withoutstar = preg_replace('/\*/', '', $fieldstarget[$code]); $headerlinefields[] = $langs->transnoentities($withoutstar).($withoutstar != $fieldstarget[$code] ? '*' : '').' ('.$code.')'; - $contentlinevalues[] = $valuestarget[$code]; + $contentlinevalues[] = (isset($valuestarget[$code]) ? $valuestarget[$code] : ''); } //var_dump($headerlinefields); //var_dump($contentlinevalues); From af95169d1d0656dcb415757c2d87c8ba1f6972bc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 31 Jul 2021 16:54:18 +0200 Subject: [PATCH 34/52] Update actions_sendmails.inc.php --- htdocs/core/actions_sendmails.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index 3c8e4a5fe73..e5c75a2e7c3 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -182,12 +182,12 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST $tmparray = array(); if (trim($_POST['sendto'])) { - // Recipients are provided into free text + // Recipients are provided into free text field $tmparray[] = trim($_POST['sendto']); } if (trim($_POST['tomail'])) { - // Recipients are provided as free text + // Recipients are provided into free hidden text field $tmparray[] = trim($_POST['tomail']); } From bd35d8626834daac53eee835e220dbbe1a2fada2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 31 Jul 2021 17:20:48 +0200 Subject: [PATCH 35/52] Debug v14 --- htdocs/comm/mailing/cibles.php | 7 ++++--- htdocs/core/modules/mailings/contacts1.modules.php | 14 +++++++++----- htdocs/langs/en_US/mails.lang | 4 ++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/htdocs/comm/mailing/cibles.php b/htdocs/comm/mailing/cibles.php index 08e223ed89f..3f2cfc2974c 100644 --- a/htdocs/comm/mailing/cibles.php +++ b/htdocs/comm/mailing/cibles.php @@ -1,6 +1,6 @@ - * Copyright (C) 2005-2016 Laurent Destailleur + * Copyright (C) 2005-2021 Laurent Destailleur * Copyright (C) 2005-2010 Regis Houssin * Copyright (C) 2014 Florian Henry * @@ -337,6 +337,7 @@ if ($object->fetch($id) >= 0) { if (is_resource($handle)) { while (($file = readdir($handle)) !== false) { if (substr($file, 0, 1) <> '.' && substr($file, 0, 3) <> 'CVS') { + $reg = array(); if (preg_match("/(.*)\.modules\.php$/i", $file, $reg)) { if ($reg[1] == 'example') { continue; @@ -534,9 +535,9 @@ if ($object->fetch($id) >= 0) { $morehtmlcenter = ''; if ($allowaddtarget) { - $morehtmlcenter = ''.$langs->trans("ToClearAllRecipientsClickHere").' id.'" class="button reposition">'.$langs->trans("TargetsReset").''; + $morehtmlcenter = ''.$langs->trans("ToClearAllRecipientsClickHere").' id.'" class="button reposition smallpaddingimp">'.$langs->trans("TargetsReset").''; } - $morehtmlcenter .= ' id.'">'.$langs->trans("Download").''; + $morehtmlcenter .= '   id.'">'.$langs->trans("Download").''; print_barre_liste($langs->trans("MailSelectedRecipients"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $morehtmlcenter, $num, $nbtotalofrecords, 'generic', 0, '', '', $limit); diff --git a/htdocs/core/modules/mailings/contacts1.modules.php b/htdocs/core/modules/mailings/contacts1.modules.php index 4bd03593e09..6be129b8815 100644 --- a/htdocs/core/modules/mailings/contacts1.modules.php +++ b/htdocs/core/modules/mailings/contacts1.modules.php @@ -141,15 +141,19 @@ class mailing_contacts1 extends MailingTargets $resql = $this->db->query($sql); $s .= $langs->trans("PostOrFunction").': '; - $s .= ''; $s .= ''; if ($resql) { $num = $this->db->num_rows($resql); $i = 0; - while ($i < $num) { - $obj = $this->db->fetch_object($resql); - $s .= ''; - $i++; + if ($num > 0) { + while ($i < $num) { + $obj = $this->db->fetch_object($resql); + $s .= ''; + $i++; + } + } else { + $s .= ''; } } else { dol_print_error($this->db); diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index 24c86cc885a..1c0dd638eeb 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -162,8 +162,8 @@ AdvTgtDeleteFilter=Delete filter AdvTgtSaveFilter=Save filter AdvTgtCreateFilter=Create filter AdvTgtOrCreateNewFilter=Name of new filter -NoContactWithCategoryFound=No contact/address with a category found -NoContactLinkedToThirdpartieWithCategoryFound=No contact/address with a category found +NoContactWithCategoryFound=No category found linked to some contacts/addresses +NoContactLinkedToThirdpartieWithCategoryFound=No category found linked to some thirdparties OutGoingEmailSetup=Outgoing emails InGoingEmailSetup=Incoming emails OutGoingEmailSetupForEmailing=Outgoing emails (for module %s) From b67487b2ca544d1803642bf176d077f78e67c073 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 31 Jul 2021 17:28:43 +0200 Subject: [PATCH 36/52] Fix reposition --- .../modules/mailings/contacts1.modules.php | 20 +++++++++---------- .../core/modules/mailings/pomme.modules.php | 12 +++++------ .../modules/mailings/thirdparties.modules.php | 8 ++++---- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/htdocs/core/modules/mailings/contacts1.modules.php b/htdocs/core/modules/mailings/contacts1.modules.php index 6be129b8815..0ca62392c82 100644 --- a/htdocs/core/modules/mailings/contacts1.modules.php +++ b/htdocs/core/modules/mailings/contacts1.modules.php @@ -140,8 +140,8 @@ class mailing_contacts1 extends MailingTargets $sql .= " ORDER BY sp.poste"; $resql = $this->db->query($sql); - $s .= $langs->trans("PostOrFunction").': '; - $s .= ''; $s .= ''; if ($resql) { $num = $this->db->num_rows($resql); @@ -163,7 +163,7 @@ class mailing_contacts1 extends MailingTargets $s .= ' '; // Filter on contact category - $s .= $langs->trans("ContactCategoriesShort").': '; + $s .= $langs->trans("ContactCategoriesShort").' '; $sql = "SELECT c.label, count(distinct(sp.email)) AS nb"; $sql .= " FROM "; $sql .= " ".MAIN_DB_PREFIX."socpeople as sp,"; @@ -179,7 +179,7 @@ class mailing_contacts1 extends MailingTargets $sql .= " ORDER BY c.label"; $resql = $this->db->query($sql); - $s .= ''; $s .= ''; if ($resql) { $num = $this->db->num_rows($resql); @@ -201,8 +201,8 @@ class mailing_contacts1 extends MailingTargets $s .= '
'; // Add prospect of a particular level - $s .= $langs->trans("NatureOfThirdParty").': '; - $s .= ''; $sql = "SELECT code, label"; $sql .= " FROM ".MAIN_DB_PREFIX."c_prospectlevel"; $sql .= " WHERE active > 0"; @@ -238,7 +238,7 @@ class mailing_contacts1 extends MailingTargets $s .= ' '; // Filter on thirdparty category - $s .= $langs->trans("CustomersProspectsCategoriesShort").': '; + $s .= $langs->trans("CustomersProspectsCategoriesShort").' '; $sql = "SELECT c.label, count(distinct(sp.email)) AS nb"; $sql .= " FROM "; $sql .= " ".MAIN_DB_PREFIX."socpeople as sp,"; @@ -254,7 +254,7 @@ class mailing_contacts1 extends MailingTargets $sql .= " ORDER BY c.label"; $resql = $this->db->query($sql); - $s .= ''; $s .= ''; if ($resql) { $num = $this->db->num_rows($resql); @@ -276,7 +276,7 @@ class mailing_contacts1 extends MailingTargets $s .= ' '; // Filter on thirdparty category - $s .= $langs->trans("SuppliersCategoriesShort").': '; + $s .= $langs->trans("SuppliersCategoriesShort").' '; $sql = "SELECT c.label, count(distinct(sp.email)) AS nb"; $sql .= " FROM "; $sql .= " ".MAIN_DB_PREFIX."socpeople as sp,"; @@ -292,7 +292,7 @@ class mailing_contacts1 extends MailingTargets $sql .= " ORDER BY c.label"; $resql = $this->db->query($sql); - $s .= ''; $s .= ''; if ($resql) { $num = $this->db->num_rows($resql); diff --git a/htdocs/core/modules/mailings/pomme.modules.php b/htdocs/core/modules/mailings/pomme.modules.php index a2a54c02c55..6880452a416 100644 --- a/htdocs/core/modules/mailings/pomme.modules.php +++ b/htdocs/core/modules/mailings/pomme.modules.php @@ -20,13 +20,13 @@ /** * \file htdocs/core/modules/mailings/pomme.modules.php * \ingroup mailing - * \brief File of class to offer a selector of emailing targets with Rule 'Pomme'. + * \brief File of class to offer a selector of emailing targets of users. */ include_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php'; /** - * Class to offer a selector of emailing targets with Rule 'Peche'. + * Class to offer a selector of emailing targets with Rule 'Pomme'. */ class mailing_pomme extends MailingTargets { @@ -119,16 +119,16 @@ class mailing_pomme extends MailingTargets $langs->load("users"); $s = ''; - $s .= $langs->trans("Status").': '; - $s .= ''; $s .= ''; $s .= ''; $s .= ''; $s .= ''; $s .= ' '; - $s .= $langs->trans("Employee").': '; - $s .= ''; $s .= ''; $s .= ''; $s .= ''; diff --git a/htdocs/core/modules/mailings/thirdparties.modules.php b/htdocs/core/modules/mailings/thirdparties.modules.php index f764c3f5f71..ae26dfc19fd 100644 --- a/htdocs/core/modules/mailings/thirdparties.modules.php +++ b/htdocs/core/modules/mailings/thirdparties.modules.php @@ -226,8 +226,8 @@ class mailing_thirdparties extends MailingTargets $langs->load("companies"); - $s = $langs->trans("Categories").': '; - $s .= ''; // Show categories $sql = "SELECT rowid, label, type, visible"; @@ -276,7 +276,7 @@ class mailing_thirdparties extends MailingTargets $s .= ' '; $s .= $langs->trans('ProspectCustomer'); - $s .= ': '; $s .= ''; if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) { $s .= ''; @@ -292,7 +292,7 @@ class mailing_thirdparties extends MailingTargets $s .= ' '; $s .= $langs->trans("Status"); - $s .= ': '; $s .= ''; $s .= ''; $s .= ''; From 5256d6e046894a007664b002ef1b1be0ee94c973 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 31 Jul 2021 17:34:41 +0200 Subject: [PATCH 37/52] css --- htdocs/accountancy/bookkeeping/list.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index ce91219c306..bc260c77ed3 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -576,7 +576,7 @@ if (!empty($sortfield)) { // Export into a file with format defined into setup (FEC, CSV, ...) // Must be after definition of $sql if ($action == 'export_fileconfirm' && $user->rights->accounting->mouvements->export) { - // TODO Replace the fetchAll + ->export later that consume too much memory on large export with the query($sql) and loop on each line to export them. + // TODO Replace the fetchAll to get all ->line followed by call to ->export(). It consumew too much memory on large export. Replace this with the query($sql) and loop on each line to export them. $result = $object->fetchAll($sortorder, $sortfield, 0, 0, $filter, 'AND', (empty($conf->global->ACCOUNTING_REEXPORT) ? 0 : 1)); if ($result < 0) { @@ -822,7 +822,7 @@ if (!empty($arrayfields['t.piece_num']['checked'])) { // Code journal if (!empty($arrayfields['t.code_journal']['checked'])) { print ''; - print $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1); + print $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1, 'maxwidth150'); print ''; } // Date document @@ -865,7 +865,7 @@ if (!empty($arrayfields['t.subledger_account']['checked'])) { print $formaccounting->select_auxaccount($search_accountancy_aux_code_end, 'search_accountancy_aux_code_end', $langs->trans('to'), 'maxwidth250', 'subledgeraccount'); print '
'; } else { - print ''; + print ''; } print ''; } From 04fc2c0ce73c2019d552e781eb068ee1e1fd53e1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 2 Aug 2021 17:49:27 +0200 Subject: [PATCH 38/52] css --- htdocs/admin/paymentbybanktransfer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/paymentbybanktransfer.php b/htdocs/admin/paymentbybanktransfer.php index 7cf522abc33..be5dc4e76e6 100644 --- a/htdocs/admin/paymentbybanktransfer.php +++ b/htdocs/admin/paymentbybanktransfer.php @@ -150,7 +150,7 @@ print ''; print ''; print ''; -print ''; +print ''; print ''; print ""; From 8077fae42e1458e45e7c800512fd9e4726ea0b43 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 2 Aug 2021 17:56:58 +0200 Subject: [PATCH 39/52] Code comment --- htdocs/compta/facture/prelevement.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/htdocs/compta/facture/prelevement.php b/htdocs/compta/facture/prelevement.php index f5ac0f19509..6fdc74a7539 100644 --- a/htdocs/compta/facture/prelevement.php +++ b/htdocs/compta/facture/prelevement.php @@ -148,12 +148,6 @@ if ($type == 'bank-transfer') { llxHeader('', $title, $helpurl); -/* *************************************************************************** */ -/* */ -/* Mode fiche */ -/* */ -/* *************************************************************************** */ - if ($object->id > 0) { $selleruserevenustamp = $mysoc->useRevenueStamp(); @@ -471,6 +465,7 @@ if ($object->id > 0) { print ""; print ''; + // IBAN of seller or supplier $title = 'CustomerIBAN'; if ($type == 'bank-transfer') { $title = 'SupplierIBAN'; From efda27000eaabc22649a3f5bc1a925e4226feb99 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 2 Aug 2021 18:13:35 +0200 Subject: [PATCH 40/52] Fix set of date of rum signature --- .../societe/class/companybankaccount.class.php | 7 ++++--- htdocs/societe/paymentmodes.php | 16 ++++++++-------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/htdocs/societe/class/companybankaccount.class.php b/htdocs/societe/class/companybankaccount.class.php index 6c52359979e..9b767cde34c 100644 --- a/htdocs/societe/class/companybankaccount.class.php +++ b/htdocs/societe/class/companybankaccount.class.php @@ -83,7 +83,7 @@ class CompanyBankAccount extends Account $now = dol_now(); $error = 0; // Correct default_rib to be sure to have always one default - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_rib where fk_soc = ".$this->socid." AND default_rib = 1 AND type = 'ban'"; + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_rib where fk_soc = ".((int) $this->socid)." AND default_rib = 1 AND type = 'ban'"; $result = $this->db->query($sql); if ($result) { $numrows = $this->db->num_rows($result); @@ -96,7 +96,7 @@ class CompanyBankAccount extends Account } $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_rib (fk_soc, type, datec)"; - $sql .= " VALUES (".$this->socid.", 'ban', '".$this->db->idate($now)."')"; + $sql .= " VALUES (".((int) $this->socid).", 'ban', '".$this->db->idate($now)."')"; $resql = $this->db->query($sql); if ($resql) { if ($this->db->affected_rows($resql)) { @@ -135,6 +135,7 @@ class CompanyBankAccount extends Account public function update(User $user = null, $notrigger = 0) { global $conf; + $error = 0; if (!$this->id) { @@ -160,7 +161,7 @@ class CompanyBankAccount extends Account $sql .= ",proprio = '".$this->db->escape($this->proprio)."'"; $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'"; $sql .= ",default_rib = ".((int) $this->default_rib); - if ($conf->prelevement->enabled) { + if (!empty($conf->prelevement->enabled)) { $sql .= ",frstrecur = '".$this->db->escape($this->frstrecur)."'"; $sql .= ",rum = '".$this->db->escape($this->rum)."'"; $sql .= ",date_rum = ".($this->date_rum ? "'".$this->db->idate($this->date_rum)."'" : "null"); diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index 93c4fbc2202..97d92007885 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -161,9 +161,6 @@ if (empty($reshook)) { if (empty($companybankaccount->rum)) { $companybankaccount->rum = $prelevement->buildRumNumber($object->code_client, $companybankaccount->datec, $companybankaccount->id); } - if (empty($companybankaccount->date_rum)) { - $companybankaccount->date_rum = dol_now(); - } $result = $companybankaccount->update($user); if (!$result) { @@ -268,9 +265,9 @@ if (empty($reshook)) { $companybankaccount->domiciliation = GETPOST('domiciliation', 'alpha'); $companybankaccount->proprio = GETPOST('proprio', 'alpha'); $companybankaccount->owner_address = GETPOST('owner_address', 'alpha'); - $companybankaccount->frstrecur = GETPOST('frstrecur'); + $companybankaccount->frstrecur = GETPOST('frstrecur', 'alpha'); $companybankaccount->rum = GETPOST('rum', 'alpha'); - $companybankaccount->date_rum = dol_mktime(0, 0, 0, GETPOST('date_rummonth'), GETPOST('date_rumday'), GETPOST('date_rumyear')); + $companybankaccount->date_rum = dol_mktime(0, 0, 0, GETPOST('date_rummonth', 'int'), GETPOST('date_rumday', 'int'), GETPOST('date_rumyear', 'int')); $companybankaccount->datec = dol_now(); $companybankaccount->status = 1; @@ -300,7 +297,6 @@ if (empty($reshook)) { if (empty($companybankaccount->rum)) { $companybankaccount->rum = $prelevement->buildRumNumber($object->code_client, $companybankaccount->datec, $companybankaccount->id); - $companybankaccount->date_rum = dol_now(); } } @@ -1638,8 +1634,10 @@ if ($socid && $action == 'edit' && $user->rights->societe->creer) { print ''; print ''; + $date_rum = dol_mktime(0, 0, 0, GETPOST('date_rummonth'), GETPOST('date_rumday'), GETPOST('date_rumyear')); + print ''; - print ''; + print ''; print ''; print ''; + $date_rum = dol_mktime(0, 0, 0, GETPOST('date_rummonth'), GETPOST('date_rumday'), GETPOST('date_rumyear')); + print ''; - print ''; + print ''; print ''; print ''; -print ''; print ''; @@ -225,7 +225,11 @@ print ''; print ''; if ($nb) { if ($pricetowithdraw) { - print $langs->trans('BankToReceiveWithdraw').': '; + $title = print $langs->trans('BankToReceiveWithdraw').': '; + if ($type == 'bank-transfer') { + $title .= $langs->trans('BankToPayCreditTransfer').': '; + } + print $title; $form->select_comptes($conf->global->PRELEVEMENT_ID_BANKACCOUNT, 'id_bankaccount', 0, "courant=1"); print ' - '; From 2deaac0fc4f8e689d9407605cf7f5e0487e83e5e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 2 Aug 2021 18:34:38 +0200 Subject: [PATCH 42/52] Fix changelog --- ChangeLog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5b296aa88e2..b54d8df615e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -228,8 +228,9 @@ Following changes may create regressions for some external modules, but were nec * If your database is PostgreSQL, you must use version 9.1.0 or more (Dolibarr need the SQL function CONCAT) * If your database is MySQL or MariaDB, you need at least version 5.1 * Function set_price_level() has been renamed into setPriceLevel() to follow camelcase rules -* removed deprecated substitution key __REFCLIENT__ (replaced with __REF_CLIENT__) +* Removed deprecated substitution key __REFCLIENT__ (replaced with __REF_CLIENT__) * Removed constant MAIN_COUNTRIES_IN_EEC. You can now set if country is in Europe or not from the dictionary of countries. +* v14 seems to work correctly on PHP v8 but it generates a lot of verbose warnings. Currently, v14 i snot yet officialy supported with PHP 8. ***** ChangeLog for 13.0.4 compared to 13.0.3 ***** From fc33d46c7731abb52e79fb489460f290e1fbcf69 Mon Sep 17 00:00:00 2001 From: atm-florian Date: Mon, 2 Aug 2021 18:56:45 +0200 Subject: [PATCH 43/52] FIX: using Tulip, deposit mask doesn't get saved --- htdocs/admin/supplier_invoice.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/htdocs/admin/supplier_invoice.php b/htdocs/admin/supplier_invoice.php index f307a5905b8..bc587845cda 100644 --- a/htdocs/admin/supplier_invoice.php +++ b/htdocs/admin/supplier_invoice.php @@ -59,8 +59,10 @@ $specimenthirdparty->initAsSpecimen(); if ($action == 'updateMask') { $maskconstinvoice = GETPOST('maskconstinvoice', 'alpha'); $maskconstcredit = GETPOST('maskconstcredit', 'alpha'); + $maskconstdeposit = GETPOST('maskconstdeposit', 'alpha'); $maskinvoice = GETPOST('maskinvoice', 'alpha'); $maskcredit = GETPOST('maskcredit', 'alpha'); + $maskdeposit = GETPOST('maskdeposit', 'alpha'); if ($maskconstinvoice) { $res = dolibarr_set_const($db, $maskconstinvoice, $maskinvoice, 'chaine', 0, '', $conf->entity); @@ -68,6 +70,9 @@ if ($action == 'updateMask') { if ($maskconstcredit) { $res = dolibarr_set_const($db, $maskconstcredit, $maskcredit, 'chaine', 0, '', $conf->entity); } + if ($maskconstdeposit) { + $res = dolibarr_set_const($db, $maskconstdeposit, $maskdeposit, 'chaine', 0, '', $conf->entity); + } if (!($res > 0)) { $error++; From 000c32c13735dedb826aa3d59f85171eac4ac545 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 2 Aug 2021 20:20:52 +0200 Subject: [PATCH 44/52] FIx #18313 --- htdocs/variants/combinations.php | 9 ++++++--- htdocs/variants/list.php | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index 0d9de5d857f..c29fc519258 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -30,10 +30,13 @@ $langs->loadLangs(array("products", "other")); $id = GETPOST('id', 'int'); $valueid = GETPOST('valueid', 'int'); $ref = GETPOST('ref', 'alpha'); -$weight_impact = GETPOST('weight_impact', 'alpha'); -$price_impact = GETPOST('price_impact', 'alpha'); +$weight_impact = price2num(GETPOST('weight_impact', 'alpha'), 2); $price_impact_percent = (bool) GETPOST('price_impact_percent'); - +if ($price_impact_percent) { + $price_impact = price2num(GETPOST('price_impact', 'alpha'), 2); +} else { + $price_impact = price2num(GETPOST('price_impact', 'alpha'), 'MU'); +} $level_price_impact = GETPOST('level_price_impact', 'array'); $level_price_impact_percent = GETPOST('level_price_impact_percent', 'array'); diff --git a/htdocs/variants/list.php b/htdocs/variants/list.php index dcf4fdcdb43..ecb42ba25e2 100644 --- a/htdocs/variants/list.php +++ b/htdocs/variants/list.php @@ -16,8 +16,8 @@ */ require '../main.inc.php'; -require DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; -require DOL_DOCUMENT_ROOT.'/variants/class/ProductAttribute.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttribute.class.php'; $action = GETPOST('action', 'aZ09'); $object = new ProductAttribute($db); From d0c57dac3496df06a91d98297a9f105d91a8d0a7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 3 Aug 2021 15:02:09 +0200 Subject: [PATCH 45/52] FIx #18217 - Salary - link 'salary' of bank_url not managed --- .../accountancy/bookkeeping/listbyaccount.php | 37 ++++------ .../bookkeeping/listbysubaccount.php | 37 ++++------ htdocs/accountancy/journal/bankjournal.php | 69 +++++++++++++++---- htdocs/compta/bank/bankentries_list.php | 17 +++-- htdocs/compta/bank/class/account.class.php | 12 ++-- htdocs/core/menus/standard/eldy.lib.php | 6 +- htdocs/langs/en_US/accountancy.lang | 4 +- htdocs/salaries/class/paymentsalary.class.php | 44 ++++++++---- htdocs/salaries/class/salary.class.php | 6 ++ 9 files changed, 148 insertions(+), 84 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 522576350e7..27f23d36a74 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -509,10 +509,9 @@ $moreforfilter = ''; $moreforfilter .= '
'; $moreforfilter .= $langs->trans('AccountAccounting').': '; $moreforfilter .= '
'; -$moreforfilter .= $langs->trans('From').' '; -$moreforfilter .= $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', 1, array(), 1, 1, 'maxwidth200'); -$moreforfilter .= ' '.$langs->trans('to').' '; -$moreforfilter .= $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', 1, array(), 1, 1, 'maxwidth200'); +$moreforfilter .= $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth200'); +$moreforfilter .= ' '; +$moreforfilter .= $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth200'); $moreforfilter .= '
'; $moreforfilter .= '
'; @@ -671,23 +670,19 @@ while ($i < min($num, $limit)) { $accountg = length_accountg($line->numero_compte); //if (empty($accountg)) $accountg = '-'; + $colspan = 0; // colspan before field 'label of operation' + $colspanend = 3; // colspan after debit/credit + if (!empty($arrayfields['t.piece_num']['checked'])) { $colspan++; } + if (!empty($arrayfields['t.code_journal']['checked'])) { $colspan++; } + if (!empty($arrayfields['t.doc_date']['checked'])) { $colspan++; } + if (!empty($arrayfields['t.doc_ref']['checked'])) { $colspan++; } + if (!empty($arrayfields['t.label_operation']['checked'])) { $colspan++; } + if (!empty($arrayfields['t.date_export']['checked'])) { $colspanend++; } + if (!empty($arrayfields['t.date_validating']['checked'])) { $colspanend++; } + if (!empty($arrayfields['t.lettering_code']['checked'])) { $colspanend++; } + // Is it a break ? if ($accountg != $displayed_account_number || !isset($displayed_account_number)) { - $colnumber = 5; - $colnumberend = 8; - - if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING) || empty($arrayfields['t.lettering_code']['checked'])) { - $colnumber--; - } - if (empty($arrayfields['t.date_export']['checked'])) { - $colnumber--; - } - if (empty($arrayfields['t.date_validated']['checked'])) { - $colnumber--; - } - - $colspan = $totalarray['nbfield'] - $colnumber; - $colspanend = $totalarray['nbfield'] - $colnumberend; // Show a subtotal by accounting account if (isset($displayed_account_number)) { print '
'; @@ -926,9 +921,7 @@ while ($i < min($num, $limit)) { $i++; } -if ($num > 0) { - $colspan = $totalarray['nbfield'] - $colnumber; - $colspanend = $totalarray['nbfield'] - $colnumberend; +if ($num > 0 && $colspan > 0) { print ''; print ''; print ''; diff --git a/htdocs/accountancy/bookkeeping/listbysubaccount.php b/htdocs/accountancy/bookkeeping/listbysubaccount.php index efc93f1b96c..5e83c729fb1 100644 --- a/htdocs/accountancy/bookkeeping/listbysubaccount.php +++ b/htdocs/accountancy/bookkeeping/listbysubaccount.php @@ -511,10 +511,9 @@ $moreforfilter = ''; $moreforfilter .= '
'; $moreforfilter .= $langs->trans('AccountAccounting').': '; $moreforfilter .= '
'; -$moreforfilter .= $langs->trans('From').' '; -$moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_start, 'search_accountancy_code_start', 1, 'maxwidth200'); -$moreforfilter .= ' '.$langs->trans('to').' '; -$moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_end, 'search_accountancy_code_end', 1, 'maxwidth200'); +$moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), 'maxwidth200'); +$moreforfilter .= ' '; +$moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), 'maxwidth200'); $moreforfilter .= '
'; $moreforfilter .= '
'; @@ -673,23 +672,19 @@ while ($i < min($num, $limit)) { $accountg = length_accounta($line->subledger_account); //if (empty($accountg)) $accountg = '-'; + $colspan = 0; // colspan before field 'label of operation' + $colspanend = 3; // colspan after debit/credit + if (!empty($arrayfields['t.piece_num']['checked'])) { $colspan++; } + if (!empty($arrayfields['t.code_journal']['checked'])) { $colspan++; } + if (!empty($arrayfields['t.doc_date']['checked'])) { $colspan++; } + if (!empty($arrayfields['t.doc_ref']['checked'])) { $colspan++; } + if (!empty($arrayfields['t.label_operation']['checked'])) { $colspan++; } + if (!empty($arrayfields['t.date_export']['checked'])) { $colspanend++; } + if (!empty($arrayfields['t.date_validating']['checked'])) { $colspanend++; } + if (!empty($arrayfields['t.lettering_code']['checked'])) { $colspanend++; } + // Is it a break ? if ($accountg != $displayed_account_number || !isset($displayed_account_number)) { - $colnumber = 5; - $colnumberend = 8; - - if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING) || empty($arrayfields['t.lettering_code']['checked'])) { - $colnumber--; - } - if (empty($arrayfields['t.date_export']['checked'])) { - $colnumber--; - } - if (empty($arrayfields['t.date_validated']['checked'])) { - $colnumber--; - } - - $colspan = $totalarray['nbfield'] - $colnumber; - $colspanend = $totalarray['nbfield'] - $colnumberend; // Show a subtotal by accounting account if (isset($displayed_account_number)) { print ''; @@ -937,9 +932,7 @@ while ($i < min($num, $limit)) { $i++; } -if ($num > 0) { - $colspan = $totalarray['nbfield'] - $colnumber; - $colspanend = $totalarray['nbfield'] - $colnumberend; +if ($num > 0 && $colspan > 0) { print ''; print ''; print ''; diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index 34e533974fc..bdda4583d54 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -177,7 +177,7 @@ $accountingjournalstatic->fetch($id_journal); $journal = $accountingjournalstatic->code; $journal_label = $accountingjournalstatic->label; - +//print $sql; dol_syslog("accountancy/journal/bankjournal.php", LOG_DEBUG); $result = $db->query($sql); if ($result) { @@ -252,6 +252,7 @@ if ($result) { ); // Set accountancy code for user + // $obj->accountancy_code is the accountancy_code of table u=user but it is defined only if a link with type 'user' exists) $compta_user = (!empty($obj->accountancy_code) ? $obj->accountancy_code : ''); $tabuser[$obj->rowid] = array( @@ -277,7 +278,7 @@ if ($result) { $tabpay[$obj->rowid]["lib"] = dol_trunc($obj->label, 60); } - // Load of url links to the line into llx_bank + // Load of url links to the line into llx_bank (so load llx_bank_url) $links = $object->get_url($obj->rowid); // Get an array('url'=>, 'url_id'=>, 'label'=>, 'type'=> 'fk_bank'=> ) // By default @@ -287,7 +288,7 @@ if ($result) { // get_url may return -1 which is not traversable if (is_array($links) && count($links) > 0) { - // Now loop on each link of record in bank. + // Now loop on each link of record in bank (code similar to bankentries_list.php) foreach ($links as $key => $val) { if (in_array($links[$key]['type'], array('sc', 'payment_sc', 'payment', 'payment_supplier', 'payment_vat', 'payment_expensereport', 'banktransfert', 'payment_donation', 'member', 'payment_loan', 'payment_salary', 'payment_various'))) { // So we excluded 'company' and 'user' here. We want only payment lines @@ -302,6 +303,7 @@ if ($result) { } } + // Special case to ask later to add more request to get information for old links without company link. if ($links[$key]['type'] == 'withdraw') { $tabmoreinfo[$obj->rowid]['withdraw'] = 1; } @@ -401,6 +403,44 @@ if ($result) { $paymentsalstatic->label = $links[$key]['label']; $tabpay[$obj->rowid]["lib"] .= ' '.$paymentsalstatic->getNomUrl(2); $tabpay[$obj->rowid]["paymentsalid"] = $paymentsalstatic->id; + + // This part of code is no more required. it is here to solve case where a link were missing (ith v14.0.0) and keep writing in accountancy complete. + // Note: A better way to fix this is to delete payement of salary and recreate it, or to fix the bookkeeping table manually after. + if (!empty($conf->global->ACCOUNTANCY_AUTOFIX_MISSING_LINK_TO_USEr_ON_SALARY_BANK_PAYMENT)) { + $tmpsalary = new Salary($db); + $tmpsalary->fetch($paymentsalstatic->id); + $tmpsalary->fetch_user($tmpsalary->fk_user); + + $userstatic->id = $tmpsalary->user->id; + $userstatic->name = $tmpsalary->user->name; + $userstatic->email = $tmpsalary->user->email; + $userstatic->firstname = $tmpsalary->user->firstname; + $userstatic->lastname = $tmpsalary->user->lastname; + $userstatic->statut = $tmpsalary->user->statut; + $userstatic->accountancy_code = $tmpsalary->user->accountancy_code; + + if ($userstatic->id > 0) { + $tabpay[$obj->rowid]["soclib"] = $userstatic->getNomUrl(1, 'accountancy', 0); + } else { + $tabpay[$obj->rowid]["soclib"] = '???'; // Should not happen + } + + if (empty($obj->typeop_user)) { // Add test to avoid to add amount twice if a link already exists also on user. + $compta_user = $userstatic->accountancy_code; + if ($compta_user) { + $tabtp[$obj->rowid][$compta_user] += $obj->amount; + $tabuser[$obj->rowid] = array( + 'id' => $userstatic->id, + 'name' => dolGetFirstLastname($userstatic->firstname, $userstatic->lastname), + 'lastname' => $userstatic->lastname, + 'firstname' => $userstatic->firstname, + 'email' => $userstatic->email, + 'accountancy_code' => $compta_user, + 'status' => $userstatic->statut + ); + } + } + } } elseif ($links[$key]['type'] == 'payment_expensereport') { $paymentexpensereportstatic->id = $links[$key]['url_id']; $tabpay[$obj->rowid]["lib"] .= $paymentexpensereportstatic->getNomUrl(2); @@ -468,7 +508,7 @@ if ($result) { } } - // If no links were found to know the amount on thirdparty, we init it to account 'NotDefined'. + // If no links were found to know the amount on thirdparty/user, we init it to account 'NotDefined'. if (empty($tabtp[$obj->rowid])) { $tabtp[$obj->rowid]['NotDefined'] = $tabbq[$obj->rowid][$compta_bank]; } @@ -1162,9 +1202,9 @@ if (empty($action) || $action == 'view') { if ($tabtype[$key] == 'unknown') { // We will accept writing, but into a waiting account if (empty($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) || $conf->global->ACCOUNTING_ACCOUNT_SUSPENSE == '-1') { - print ''.$langs->trans('UnknownAccountForThirdpartyAndWaitingAccountNotDefinedBlocking').''; + print ''.$langs->trans('UnknownAccountForThirdpartyAndWaitingAccountNotDefinedBlocking').''; } else { - print ''.$langs->trans('UnknownAccountForThirdparty', length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE)).''; // We will use a waiting account + print ''.$langs->trans('UnknownAccountForThirdparty', length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE)).''; // We will use a waiting account } } else { // We will refuse writing @@ -1187,7 +1227,7 @@ if (empty($action) || $action == 'view') { if ($tabtype[$key] == 'member') { $errorstring = 'MainAccountForSubscriptionPaymentNotDefined'; } - print ''.$langs->trans($errorstring).''; + print ''.$langs->trans($errorstring).''; } } else { print $accounttoshow; @@ -1196,7 +1236,7 @@ if (empty($action) || $action == 'view') { // Subledger account print ""; + print ""; + print '"; + print '"; + print '"; + print ""; } } diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index 666621cbdd6..14aeee29d69 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -1346,7 +1346,7 @@ if ($resql) { print '"; // Bank account (from Banks module) print ''; -print ''; /* Moved to bank account data // ICS print ''; -print ''; print ''; */ //User print ''; -print ''; print ''; /* //EntToEnd print ''; -print ''; +print ''; print ''; //USTRD print ''; -print ''; +print ''; print ''; */ @@ -195,7 +197,7 @@ print ''; +print ''; print ''; print '
'.$langs->trans("Parameter").''.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("RUM").'
'.$langs->trans("DateRUM").''.$form->selectDate(GETPOST('date_rum') ?GETPOST('date_rum') : $companybankaccount->date_rum, 'date_rum', 0, 0, 1, 'date_rum').'
'.$form->selectDate($date_rum ? $date_rum : $companybankaccount->date_rum, 'date_rum', 0, 0, 1, 'date_rum', 1, 1).'
'.$langs->trans("WithdrawMode").''; $tblArraychoice = array("FRST" => $langs->trans("FRST"), "RECUR" => $langs->trans("RECUR")); @@ -1800,8 +1798,10 @@ if ($socid && $action == 'create' && $user->rights->societe->creer) { print '
'.$langs->trans("RUM").'
'.$langs->trans("RUMWillBeGenerated").'
'.$langs->trans("DateRUM").''.$form->selectDate(GETPOST('date_rum'), 'date_rum', 0, 0, 1, 'date_rum').'
'.$form->selectDate($date_rum, 'date_rum', 0, 0, 1, 'date_rum', 1, 1).'
'.$langs->trans("WithdrawMode").''; $tblArraychoice = array("FRST" => $langs->trans("FRST"), "RECUR" => $langs->trans("RECUR")); From 61e3a57de701c2ecbe77095bd1fa466fbe31fbaf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 2 Aug 2021 18:23:05 +0200 Subject: [PATCH 41/52] Fix label --- htdocs/compta/prelevement/create.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php index 6793fb0a893..937750648bb 100644 --- a/htdocs/compta/prelevement/create.php +++ b/htdocs/compta/prelevement/create.php @@ -206,7 +206,7 @@ print $nb; print '
'.$langs->trans("AmountTotal").''; +print ''; print price($pricetowithdraw); print '
'.$langs->trans("TotalForAccount").' '.$accountg.':'.price($sous_total_debit).'
'.$langs->trans("TotalForAccount").' '.$accountg.':'.price($sous_total_debit).'"; - if (in_array($tabtype[$key], array('payment', 'payment_supplier', 'payment_expensereport', 'payment_salary', 'payment_various'))) { // Type of payment with subledger + if (in_array($tabtype[$key], array('payment', 'payment_supplier', 'payment_expensereport', 'payment_salary', 'payment_various'))) { // Type of payments that uses a subledger $accounttoshowsubledger = length_accounta($k); if ($accounttoshow != $accounttoshowsubledger) { if (empty($accounttoshowsubledger) || $accounttoshowsubledger == 'NotDefined') { @@ -1205,14 +1245,14 @@ if (empty($action) || $action == 'view') { var_dump($tabbq[$key]);*/ //print ''.$langs->trans("ThirdpartyAccountNotDefined").''; if (!empty($tabcompany[$key]['code_compta'])) { - if (in_array($tabtype[$key], array('payment_various'))) { + if (in_array($tabtype[$key], array('payment_various', 'payment_salary'))) { // For such case, if subledger is not defined, we won't use subledger accounts. - print ''.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknownSubledgerIgnored").''; + print ''.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknownSubledgerIgnored").''; } else { - print ''.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknown", $tabcompany[$key]['code_compta']).''; + print ''.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknown", $tabcompany[$key]['code_compta']).''; } } else { - print ''.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknownBlocking").''; + print ''.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknownBlocking").''; } } else { print $accounttoshowsubledger; @@ -1220,10 +1260,15 @@ if (empty($action) || $action == 'view') { } } print "".$reflabel."'.$val["type_payment"]."'.($mt < 0 ? price(-$mt) : '')."'.($mt >= 0 ? price($mt) : '')."
'; print $labeltoshow; // Already escaped - // Add links after description + // Add info about links after description $cachebankaccount = array(); foreach ($links as $key => $val) { print ''; @@ -1424,6 +1424,7 @@ if ($resql) { } elseif ($links[$key]['type'] == 'sc') { } elseif ($links[$key]['type'] == 'vat') { } elseif ($links[$key]['type'] == 'salary') { + // Information is already shown using the payment_salary link. No need of this link. } else { // Show link with label $links[$key]['label'] if (!empty($objp->label) && !empty($links[$key]['label'])) { @@ -1530,15 +1531,21 @@ if ($resql) { } if ($companylinked_id) { - // TODO Add a cache of loaded companies here + // TODO Add a cache of loaded companies here ? $companystatic->fetch($companylinked_id); print $companystatic->getNomUrl(1); } elseif ($userlinked_id && (($type_link == 'payment_salary' && !empty($user->rights->salaries->read)) || ($type_link == 'payment_sc' && !empty($user->rights->tax->charges->lire)))) { - // TODO Add a cache of loaded users here - $userstatic->fetch($userlinked_id); - print $userstatic->getNomUrl(1); + // Get object user from cache or load it + if (!empty($conf->cache['user'][$userlinked_id])) { + $tmpuser = $conf->cache['user'][$userlinked_id]; + } else { + $tmpuser = new User($db); + $tmpuser->fetch($userlinked_id); + $conf->cache['user'][$userlinked_id] = $tmpuser; + } + print $tmpuser->getNomUrl(1); } else { print ' '; } diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 8619ff25dae..ed61da3592e 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -399,9 +399,9 @@ class Account extends CommonObject /** * Add a link between bank line record and its source * - * @param int $line_id Id ecriture bancaire - * @param int $url_id Id parametre url - * @param string $url Url + * @param int $line_id Id of bank entry + * @param int $url_id Id of object related to link + * @param string $url Url (deprecated, we use now 'url_id' and 'type' instead) * @param string $label Link label * @param string $type Type of link ('payment', 'company', 'member', ...) * @return int <0 if KO, id line if OK @@ -412,13 +412,13 @@ class Account extends CommonObject $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_url ("; $sql .= "fk_bank"; $sql .= ", url_id"; - $sql .= ", url"; + $sql .= ", url"; // deprecated $sql .= ", label"; $sql .= ", type"; $sql .= ") VALUES ("; $sql .= " ".((int) $line_id); - $sql .= ", '".$this->db->escape($url_id)."'"; - $sql .= ", '".$this->db->escape($url)."'"; + $sql .= ", ".((int) $url_id); + $sql .= ", '".$this->db->escape($url)."'"; // dperecated $sql .= ", '".$this->db->escape($label)."'"; $sql .= ", '".$this->db->escape($type)."'"; $sql .= ")"; diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 2f36290c8d4..1fbd91cb623 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1344,15 +1344,15 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM // Accounting $newmenu->add("/accountancy/index.php?leftmenu=accountancy_accountancy", $langs->trans("MenuAccountancy"), 0, $user->rights->accounting->mouvements->lire, '', $mainmenu, 'accountancy', 1, '', '', '', img_picto('', 'accountancy', 'class="paddingright pictofixedwidth"')); - // Balance - $newmenu->add("/accountancy/bookkeeping/balance.php?mainmenu=accountancy&leftmenu=accountancy_accountancy", $langs->trans("AccountBalance"), 1, $user->rights->accounting->mouvements->lire); - // General Ledger $newmenu->add("/accountancy/bookkeeping/listbyaccount.php?mainmenu=accountancy&leftmenu=accountancy_accountancy", $langs->trans("Bookkeeping"), 1, $user->rights->accounting->mouvements->lire); // Journals $newmenu->add("/accountancy/bookkeeping/list.php?mainmenu=accountancy&leftmenu=accountancy_accountancy", $langs->trans("Journals"), 1, $user->rights->accounting->mouvements->lire); + // Account Balance + $newmenu->add("/accountancy/bookkeeping/balance.php?mainmenu=accountancy&leftmenu=accountancy_accountancy", $langs->trans("AccountBalance"), 1, $user->rights->accounting->mouvements->lire); + // Files if (empty($conf->global->ACCOUNTANCY_HIDE_EXPORT_FILES_MENU)) { $newmenu->add("/compta/accounting-files.php?mainmenu=accountancy&leftmenu=accountancy_files", $langs->trans("AccountantFiles"), 1, $user->rights->accounting->mouvements->lire); diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index ec74c9361f5..771f0a83e7b 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -246,9 +246,9 @@ DescThirdPartyReport=Consult here the list of third-party customers and vendors ListAccounts=List of the accounting accounts UnknownAccountForThirdparty=Unknown third-party account. We will use %s UnknownAccountForThirdpartyBlocking=Unknown third-party account. Blocking error -ThirdpartyAccountNotDefinedOrThirdPartyUnknown=Third-party account not defined or third party unknown. We will use %s +ThirdpartyAccountNotDefinedOrThirdPartyUnknown=Subledger account not defined or third party or user unknown. We will use %s ThirdpartyAccountNotDefinedOrThirdPartyUnknownSubledgerIgnored=Third-party unknown and subledger not defined on the payment. We will keep the subledger account value empty. -ThirdpartyAccountNotDefinedOrThirdPartyUnknownBlocking=Third-party account not defined or third party unknown. Blocking error. +ThirdpartyAccountNotDefinedOrThirdPartyUnknownBlocking=Subledger account not defined or third party or user unknown. Blocking error. UnknownAccountForThirdpartyAndWaitingAccountNotDefinedBlocking=Unknown third-party account and waiting account not defined. Blocking error PaymentsNotLinkedToProduct=Payment not linked to any product / service OpeningBalance=Opening balance diff --git a/htdocs/salaries/class/paymentsalary.class.php b/htdocs/salaries/class/paymentsalary.class.php index e2b199780f0..76236bb88aa 100644 --- a/htdocs/salaries/class/paymentsalary.class.php +++ b/htdocs/salaries/class/paymentsalary.class.php @@ -477,7 +477,7 @@ class PaymentSalary extends CommonObject * All payment properties must have been set first like after a call to create(). * * @param User $user Object of user making payment - * @param string $mode 'payment_sc' + * @param string $mode 'payment_salary' * @param string $label Label to use in bank record * @param int $accountid Id of bank account to do link with * @param string $emetteur_nom Name of transmitter @@ -516,8 +516,8 @@ class PaymentSalary extends CommonObject $this->datev ); - // Mise a jour fk_bank dans llx_paiement. - // On connait ainsi le paiement qui a genere l'ecriture bancaire + // Update fk_bank into llx_paiement_salary. + // so we know the payment that was used to generated the bank entry. if ($bank_line_id > 0) { $result = $this->update_fk_bank($bank_line_id); if ($result <= 0) { @@ -525,9 +525,12 @@ class PaymentSalary extends CommonObject dol_print_error($this->db); } - // Add link 'payment', 'payment_supplier', 'payment_sc' in bank_url between payment and bank transaction + // Add link 'payment_salary' in bank_url between payment and bank transaction $url = ''; - if ($mode == 'payment_salary') $url = DOL_URL_ROOT.'/salaries/payment_salary/card.php?id='; + if ($mode == 'payment_salary') { + $url = DOL_URL_ROOT.'/salaries/payment_salary/card.php?id='; + } + if ($url) { $result = $acc->add_url_line($bank_line_id, $this->id, $url, '(paiement)', $mode); if ($result <= 0) { @@ -536,14 +539,31 @@ class PaymentSalary extends CommonObject } } - // Add link 'company' in bank_url between invoice and bank transaction (for each invoice concerned by payment) - $linkaddedforthirdparty = array(); + // Add link 'user' in bank_url between user and bank transaction foreach ($this->amounts as $key => $value) { - if ($mode == 'payment_salary') { - $salary = new Salary($this->db); - $salary->fetch($key); - $result = $acc->add_url_line($bank_line_id, $salary->id, DOL_URL_ROOT.'/salaries/card.php?id=', '('.$salary->label.')', 'salary'); - if ($result <= 0) dol_print_error($this->db); + if (!$error) { + if ($mode == 'payment_salary') { + $salary = new Salary($this->db); + $salary->fetch($key); + $salary->fetch_user($salary->fk_user); + + $fuser = $salary->user; + + if ($fuser->id > 0) { + $result = $acc->add_url_line( + $bank_line_id, + $fuser->id, + DOL_URL_ROOT.'/user/card.php?id=', + $fuser->getFullName($langs), + 'user' + ); + } + if ($result <= 0) { + $this->error = $this->db->lasterror(); + dol_syslog(get_class($this) . '::addPaymentToBank ' . $this->error); + $error++; + } + } } } } else { diff --git a/htdocs/salaries/class/salary.class.php b/htdocs/salaries/class/salary.class.php index 35ceb8a1931..cc50c57ec84 100644 --- a/htdocs/salaries/class/salary.class.php +++ b/htdocs/salaries/class/salary.class.php @@ -88,6 +88,12 @@ class Salary extends CommonObject */ public $fk_user_modif; + /** + * @var user User + */ + public $user; + + const STATUS_UNPAID = 0; const STATUS_PAID = 1; From ce5acda635e62378a8495b4bd212e8d702017da8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 3 Aug 2021 15:03:41 +0200 Subject: [PATCH 46/52] Fix phpcs --- htdocs/accountancy/class/accountancyexport.class.php | 4 ++-- htdocs/projet/tasks/time.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index 5ac3ebcb37d..a96c672608a 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -488,8 +488,8 @@ class AccountancyExport foreach ($TData as $data) { $code_compta = length_accountg($data->numero_compte); if (!empty($data->subledger_account)) { - $code_compta = length_accounta($data->subledger_account); - } + $code_compta = length_accounta($data->subledger_account); + } $date_document = dol_print_date($data->doc_date, '%Y%m%d'); $date_echeance = dol_print_date($data->date_lim_reglement, '%Y%m%d'); diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 1923bde17b2..0daf5439dc0 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -1423,9 +1423,9 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0) { $totalarray['nbfield']++; } } - } elseif ($action !== 'createtime') { - print ''; - } + } elseif ($action !== 'createtime') { + print ''; + } // Task label if (!empty($arrayfields['t.task_label']['checked'])) { From 8b746b64a0601c4c15a6a18ff0d23326e079f98a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 3 Aug 2021 15:04:29 +0200 Subject: [PATCH 47/52] Prepare 14.0.1 --- htdocs/filefunc.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index 8aa64da85f1..e55ca5b6e04 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -34,7 +34,7 @@ if (!defined('DOL_APPLICATION_TITLE')) { define('DOL_APPLICATION_TITLE', 'Dolibarr'); } if (!defined('DOL_VERSION')) { - define('DOL_VERSION', '14.0.0'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c + define('DOL_VERSION', '14.0.1'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c } if (!defined('EURO')) { From 19f17ed1145685a625d2c7ab9c0bb742fb138f5e Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Wed, 21 Jul 2021 14:52:37 +0200 Subject: [PATCH 48/52] fix: bad setEventMessages input --- htdocs/product/stock/massstockmove.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/product/stock/massstockmove.php b/htdocs/product/stock/massstockmove.php index f2432ea25af..9f3390d34af 100644 --- a/htdocs/product/stock/massstockmove.php +++ b/htdocs/product/stock/massstockmove.php @@ -209,7 +209,7 @@ if ($action == 'createmovements' && !empty($user->rights->stock->mouvement->cree ); if ($result1 < 0) { $error++; - setEventMessages($product->errors, $product->errorss, 'errors'); + setEventMessages($product->error, $product->errors, 'errors'); } // Add stock @@ -224,7 +224,7 @@ if ($action == 'createmovements' && !empty($user->rights->stock->mouvement->cree ); if ($result2 < 0) { $error++; - setEventMessages($product->errors, $product->errorss, 'errors'); + setEventMessages($product->error, $product->errors, 'errors'); } } else { $arraybatchinfo = $product->loadBatchInfo($batch); @@ -253,7 +253,7 @@ if ($action == 'createmovements' && !empty($user->rights->stock->mouvement->cree ); if ($result1 < 0) { $error++; - setEventMessages($product->errors, $product->errorss, 'errors'); + setEventMessages($product->error, $product->errors, 'errors'); } // Add stock @@ -271,7 +271,7 @@ if ($action == 'createmovements' && !empty($user->rights->stock->mouvement->cree ); if ($result2 < 0) { $error++; - setEventMessages($product->errors, $product->errorss, 'errors'); + setEventMessages($product->error, $product->errors, 'errors'); } } } else { From 9ceab9b86b9adedd37ef6204b483fe969d82c484 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 3 Aug 2021 15:47:00 +0200 Subject: [PATCH 49/52] Doc --- htdocs/product/class/productbatch.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/product/class/productbatch.class.php b/htdocs/product/class/productbatch.class.php index f10adee334e..4408afd9ff1 100644 --- a/htdocs/product/class/productbatch.class.php +++ b/htdocs/product/class/productbatch.class.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2007-2021 Laurent Destailleur * Copyright (C) 2013-2014 Cedric GROSS * * This program is free software; you can redistribute it and/or modify @@ -44,8 +44,8 @@ class Productbatch extends CommonObject public $tms = ''; public $fk_product_stock; - public $sellby = ''; - public $eatby = ''; + public $sellby = ''; // dlc + public $eatby = ''; // dmd/dluo public $batch = ''; public $qty; public $warehouseid; From 1c981ccb9d137aa7324001bc9eee463464f722fe Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 3 Aug 2021 17:03:34 +0200 Subject: [PATCH 50/52] Fix look and feel v14 --- htdocs/admin/paymentbybanktransfer.php | 22 ++++++++++++---------- htdocs/admin/prelevement.php | 20 +++++++++++--------- htdocs/compta/bank/line.php | 8 ++++---- htdocs/compta/prelevement/create.php | 7 ++++++- htdocs/core/class/html.form.class.php | 11 +++++++---- 5 files changed, 40 insertions(+), 28 deletions(-) diff --git a/htdocs/admin/paymentbybanktransfer.php b/htdocs/admin/paymentbybanktransfer.php index be5dc4e76e6..43ad8c15929 100644 --- a/htdocs/admin/paymentbybanktransfer.php +++ b/htdocs/admin/paymentbybanktransfer.php @@ -156,36 +156,38 @@ print "
'.$langs->trans("BankToPayCreditTransfer").''; -$form->select_comptes($conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT, 'PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT', 0, "courant=1", 1); +print ''; +print img_picto('', 'bank_account', 'class="pictofixedwidth"'); +print $form->select_comptes($conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT, 'PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT', 0, "courant=1", 1, '', 0, 'minwidth200', 1); print '
'.$langs->trans("ICS").''; +print ''; print '
'.$langs->trans("ResponsibleUser").''; -print $form->select_dolusers($conf->global->PAYMENTBYBANKTRANSFER_USER, 'PAYMENTBYBANKTRANSFER_USER', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); +print ''; +print img_picto('', 'user', 'class="pictofixedwidth"'); +print $form->select_dolusers($conf->global->PAYMENTBYBANKTRANSFER_USER, 'PAYMENTBYBANKTRANSFER_USER', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'minwidth200 maxwidth500'); print '
'.$langs->trans("END_TO_END").''; -print ''; +print '
'.$langs->trans("USTRD").''; -print ''; +print '
'; if (!$conf->global->PAYMENTBYBANKTRANSFER_ADDDAYS) { $conf->global->PAYMENTBYBANKTRANSFER_ADDDAYS = 0; } -print '
'; print '
'; diff --git a/htdocs/admin/prelevement.php b/htdocs/admin/prelevement.php index c7de6d59896..01e3b6d4913 100644 --- a/htdocs/admin/prelevement.php +++ b/htdocs/admin/prelevement.php @@ -160,8 +160,9 @@ print ""; // Bank account (from Banks module) print ''.$langs->trans("BankToReceiveWithdraw").''; -print ''; -$form->select_comptes($conf->global->PRELEVEMENT_ID_BANKACCOUNT, 'PRELEVEMENT_ID_BANKACCOUNT', 0, "courant=1", 1); +print ''; +print img_picto('', 'bank_account', 'class="pictofixedwidth"'); +print $form->select_comptes($conf->global->PRELEVEMENT_ID_BANKACCOUNT, 'PRELEVEMENT_ID_BANKACCOUNT', 0, "courant=1", 1, '', 0, 'minwidth200', 1); print ''; /* Moved to bank account data @@ -179,8 +180,9 @@ print ''; //User print ''.$langs->trans("ResponsibleUser").''; -print ''; -print $form->select_dolusers($conf->global->PRELEVEMENT_USER, 'PRELEVEMENT_USER', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); +print ''; +print img_picto('', 'user', 'class="pictofixedwidth"'); +print $form->select_dolusers($conf->global->PRELEVEMENT_USER, 'PRELEVEMENT_USER', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'minwidth200 maxwidth500'); print ''; print ''; @@ -189,8 +191,8 @@ print ''; $htmltext = $langs->trans("KeepThisEmptyInMostCases"); print $form->textwithpicto($langs->trans("END_TO_END"), $htmltext); print ''; -print ''; -print ''; +print ''; +print ''; print ''; //USTRD @@ -199,16 +201,16 @@ $htmltext = $langs->trans("KeepThisEmptyInMostCases"); print $form->textwithpicto($langs->trans("USTRD"), $htmltext); print ''; print ''; -print ''; +print ''; print ''; //ADDDAYS print ''.$langs->trans("ADDDAYS").''; -print ''; +print ''; if (empty($conf->global->PRELEVEMENT_ADDDAYS)) { $conf->global->PRELEVEMENT_ADDDAYS = 0; } -print ''; +print ''; print ''; print ''; diff --git a/htdocs/compta/bank/line.php b/htdocs/compta/bank/line.php index 2c33085aa6d..05aed6a215e 100644 --- a/htdocs/compta/bank/line.php +++ b/htdocs/compta/bank/line.php @@ -624,21 +624,21 @@ if ($result) { print ''; - print '"; + print '"; if ($user->rights->banque->consolidate) { print ''; } else { - print ''; + print ''; } print ''; diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php index 937750648bb..be18099b6a8 100644 --- a/htdocs/compta/prelevement/create.php +++ b/htdocs/compta/prelevement/create.php @@ -67,6 +67,7 @@ $hookmanager->initHooks(array('directdebitcreatecard', 'globalcard')); /* * Actions */ + if (GETPOST('cancel', 'alpha')) { $massaction = ''; } @@ -165,7 +166,11 @@ llxHeader('', $langs->trans("NewStandingOrder")); if (prelevement_check_config($type) < 0) { $langs->load("errors"); - setEventMessages($langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv("Withdraw")), null, 'errors'); + $modulenametoshow = "Withdraw"; + if ($type == 'bank-transfer') { + $modulenametoshow = "PaymentByBankTransfer"; + } + setEventMessages($langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv($modulenametoshow)), null, 'errors'); } diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 9e46d55d6a8..4e9da790f28 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1952,15 +1952,12 @@ class Form } dol_syslog(get_class($this)."::select_dolusers", LOG_DEBUG); + $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); $i = 0; if ($num) { - // Enhance with select2 - include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; - $out .= ajax_combobox($htmlname); - // do not use maxwidthonsmartphone by default. Set it by caller so auto size to 100% will work when not defined $out .= ''; + + if ($num) { + // Enhance with select2 + include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; + $out .= ajax_combobox($htmlname); + } } else { dol_print_error($this->db); } From a571fab1773af3d38299cfa8a36a65c64ae1af8c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 3 Aug 2021 23:54:36 +0200 Subject: [PATCH 51/52] css --- htdocs/comm/index.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/comm/index.php b/htdocs/comm/index.php index 9d0d9f1befc..2fafb5636e2 100644 --- a/htdocs/comm/index.php +++ b/htdocs/comm/index.php @@ -182,7 +182,7 @@ if (!empty($conf->propal->enabled) && $user->rights->propal->lire) { print ''; print ''; print ''; - print ''; + print ''; print ''; $i++; @@ -278,7 +278,7 @@ if (!empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposa print ''; print ''; print ''; - print ''; + print ''; print ''; $i++; @@ -375,7 +375,7 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire) { print ''; print ''; print ''; - print ''; + print ''; print ''; $i++; @@ -472,7 +472,7 @@ if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SU print ''; print ''; print ''; - print ''; + print ''; print ''; $i++; @@ -862,7 +862,7 @@ if (!empty($conf->propal->enabled) && $user->rights->propal->lire) { print ''; print ''; - print ''; + print ''; print ''; print ''; @@ -979,7 +979,7 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire) { print ''; print ''; - print ''; + print ''; print ''; print ''; From 5f5734e9af8b9f0669b050a2cb129e39b1a47007 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 4 Aug 2021 00:09:33 +0200 Subject: [PATCH 52/52] css --- htdocs/admin/clicktodial.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/clicktodial.php b/htdocs/admin/clicktodial.php index 25ada4d2d89..d6525335ad8 100644 --- a/htdocs/admin/clicktodial.php +++ b/htdocs/admin/clicktodial.php @@ -134,7 +134,7 @@ if (!empty($conf->global->CLICKTODIAL_URL)) { print ''; print $langs->trans("LinkToTestClickToDial", $user->login).' : '; print ''; - print ''; + print ''; print ''; $setupcomplete = 1; @@ -149,7 +149,7 @@ if (!empty($conf->global->CLICKTODIAL_URL)) { } if ($setupcomplete) { - print $langs->trans("LinkToTest", $user->login).': '.dol_print_phone($phonefortest, '', 0, 0, 'AC_TEL'); + print $langs->trans("LinkToTest", $user->login).': '.dol_print_phone($phonefortest, '', 0, 0, 'AC_TEL', '', 1); } else { $langs->load("errors"); print '
'.$langs->trans("WarningClickToDialUserSetupNotComplete").'
';
'.$langs->trans("Conciliation")."
'.$form->textwithpicto($langs->trans("AccountStatement"), $langs->trans("InputReceiptNumber"))."'; if ($objp->rappro) { - print $langs->trans("AccountStatement").' rappro ? ' disabled' : '').'>'; + print 'rappro ? ' disabled' : '').'>'; print ''; } else { - print $langs->trans("AccountStatement").' rappro ? ' disabled' : '').'>'; + print 'rappro ? ' disabled' : '').'>'; } if ($objp->num_releve) { print '   ('.$langs->trans("AccountStatement").' '.$objp->num_releve.')'; } print ''.$objp->num_releve.' '.$objp->num_releve.'
'.$propalstatic->getNomUrl(1).''.$companystatic->getNomUrl(1, 'customer').''.price((!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT) ? $obj->total_ht : $obj->total_ttc)).''.price((!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT) ? $obj->total_ht : $obj->total_ttc)).'
'.$supplierproposalstatic->getNomUrl(1).''.$companystatic->getNomUrl(1, 'supplier').''.price(!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT) ? $obj->total_ht : $obj->total_ttc).''.price(!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT) ? $obj->total_ht : $obj->total_ttc).'
'.$orderstatic->getNomUrl(1).''.$companystatic->getNomUrl(1, 'customer').''.price(!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT) ? $obj->total_ht : $obj->total_ttc).''.price(!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT) ? $obj->total_ht : $obj->total_ttc).'
'.$supplierorderstatic->getNomUrl(1).''.$companystatic->getNomUrl(1, 'supplier').''.price(!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT) ? $obj->total_ht : $obj->total_ttc).''.price(!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT) ? $obj->total_ht : $obj->total_ttc).'
'.$companystatic->getNomUrl(1, 'customer', 44).''.dol_print_date($db->jdate($obj->dp), 'day').''.price(!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT) ? $obj->total_ht : $obj->total_ttc).''.price(!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT) ? $obj->total_ht : $obj->total_ttc).''.$propalstatic->LibStatut($obj->fk_statut, 3).'
'.$companystatic->getNomUrl(1, 'customer', 44).''.dol_print_date($db->jdate($obj->dv), 'day').''.price(!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT) ? $obj->total_ht : $obj->total_ttc).''.price(!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT) ? $obj->total_ht : $obj->total_ttc).''.$orderstatic->LibStatut($obj->fk_statut, $obj->billed, 3).'