diff --git a/ChangeLog b/ChangeLog index 48ba5daa562..c477a17d684 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,33 +2,12 @@ English Dolibarr ChangeLog -------------------------------------------------------------- -***** ChangeLog for 13.0.4 compared to 13.0.2 ***** - -FIX: Allow disabling of a module (not a dangerous action) even if there is problem with token (due to bugged modules). -FIX: 13.0 - fatal - missing inclusion of ajax.lib.php for calling `ajax_autocompleter()` -FIX: #17919 pictures in docs. -FIX: #18006 -FIX: Accountancy - if we define a date start, automatic binding try to continue to solve old binding -FIX: Accoutancy Limit date payment not registered on purchases operations -FIX: Can't edit replacement invoice -FIX: deposit can create credit note in payment conf -FIX: division by zero on create -FIX: holiday: balances not updated correctly with pgsql because of case sensitivity field -FIX: holiday: status filter parameter has been renamed but not in links it was used -FIX: List and Create Companies Left Menus -FIX: method exists -FIX: need to add payment sum to getlibstatus function in object linked block -FIX: permission to close a proposal when using advanced permissions -FIX: Problem of z-index with popup and top menu -FIX: same thing on supplier orders -FIX: Status of invoice when making a replacement invoice -FIX: update contact birthday alert ***** ChangeLog for 14.0.0 compared to 13.0.0 ***** For users: ---------- -NEW: Module Recruitement to follow application to job positions is now stable. +NEW: Module Recruitment to follow application to job positions is now stable. NEW: Feature to make Stock Inventories NEW: Several security issues after a second private bug hunting campaign. NEW: A lot of fix into english text after a small proofreading campaign (still not perfect, but really better) @@ -71,7 +50,7 @@ NEW: Make public bookmarks editable by admin users only NEW: If main logo not defined, can use the squarred logo on login page NEW: The manifest file can use the squared image if available NEW: Enhance the multicurrency rate editor -NEW: Normalyse Type company field with ajax combobox +NEW: Normalise Type company field with ajax combobox NEW: preload product description on selection for customer propal/order/invoice NEW: Search usergroups & resources NEW: Setup Page for module creation with module builder enhancement #FoundationFunding @@ -88,14 +67,15 @@ NEW: #16378 more E-Mail Contact substitution Values for better salutation NEW: option to keep the "Automatically create the payment" checkbox empty on the tax creation page Accountancy -NEW: Accountancy - Add FEC import -NEW: Accountancy - Add a confirmation form with options on export -NEW: Accountancy - Add select date from/to in already bind customer and supplier list -NEW: Accountancy - Format FEC - Add new field DateLimitReglmt -NEW: Accountancy - In ledger & journals, show link on bank transaction -NEW: Accountancy - Possibility to filter on journals in balance -NEW: Accountancy - Add a page to list subledger accounts -NEW: Multiselect ledger account code filter on book keeping list +NEW: Add FEC import +NEW: Add a confirmation form with options on export (for notified export and validate operations) +NEW: Add select date from/to in already bind customer and supplier list +NEW: FEC / FEC2 export - Add new field DateLimitReglmt +NEW: In ledger & journals, show link on bank transaction +NEW: Possibility to filter on journals in balance +NEW: Add a page to list subledger accounts +NEW: Multiselect journal code filter on journal / balance / ledger +NEW: Add first step to close fiscal year Agenda NEW: add support for Friday as a non working day @@ -114,7 +94,7 @@ NEW: can filter files in ECM/GED on status Shared / Not shared NEW: add a check to avoid an invoice date in the future NEW: add the total of margin in invoice list NEW: can set a percentage when creating an invoice from another object -NEW: Support down payment on supplier invoice (& somes ajustments) +NEW: Support down payment on supplier invoice (& some adjustments) Margin NEW: add the total of margin in invoice list @@ -183,7 +163,7 @@ NEW: Add a security center page with all information and advices related to the NEW: Add a performance center page with all information and advices related to the performance of your instance Modules -NEW: Module Recruitement is now stable +NEW: Module Recruitment is now stable NEW: start new experimental module Event Organization Management NEW: start new experimental module Partnership Management NEW: start new experimental module Knowledge Management @@ -192,11 +172,14 @@ NEW: Check update availability for externals modules using a button on module pa Module SimplePOS is deprecated - TakePOS is recommended for the future new Options -NEW: add option CONTRACT_ALLOW_EXTERNAL_DOWNLOAD to make generated doc automatically shared -NEW: add option SUPPLIER_PROPOSAL_ALLOW_EXTERNAL_DOWNLOAD to make generated doc automatically shared -NEW: add option MAIN_SECURITY_ANTI_SSRF_SERVER_IP to define list of IPs that are local IPs -NEW: add option SOCIETE_DISABLE_WORKFORCE to hide staff field -NEW: add constant MAIN_BUGTRACK_URL to set a custom url to redirect to when clicking on link "declare a bug" +NEW: add option CONTRACT_ALLOW_EXTERNAL_DOWNLOAD to make generated doc automatically shared +NEW: add option SUPPLIER_PROPOSAL_ALLOW_EXTERNAL_DOWNLOAD to make generated doc automatically shared +NEW: add option MAIN_SECURITY_ANTI_SSRF_SERVER_IP to define list of IPs that are local IPs +NEW: add option SOCIETE_DISABLE_WORKFORCE to hide staff field +NEW: add constant MAIN_BUGTRACK_URL to set a custom url to redirect to when clicking on link "declare a bug" +NEW: add constant ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY to manage binding with accountancy account declared on thirdparty card +NEW: add constant MAIN_PRODUCT_PERENTITY_SHARED to manage some informations (Accounting account) when product is shared on several entities +NEW: add constant MAIN_COMPANY_PERENTITY_SHARED to manage some informations (Accounting account) when company is shared on several entities For developers: @@ -230,7 +213,7 @@ NEW: hook printFieldListTitle for cabyprodserv.php NEW: hook to allow external modules to add their own shortlist of recent objects NEW: SQL-altering hooks in the turnover by product report NEW: add form confirm hook on company card -NEW: add hook addSectionECMAuto method to add custom diretory into ECM auto files +NEW: add hook addSectionECMAuto method to add custom directory into ECM auto files WARNING: @@ -240,13 +223,37 @@ Following changes may create regressions for some external modules, but were nec * The ICS value for direct debit or credit transfer is now stored on each bank account instead of into the global setup. * API /setup/shipment_methods has been replaced with API /setup/shipping_methods * Field "total" renamed into "total_ht" for table llx_facture, llx_facture_rec for better field name consistency -* Field "tva" renamed into "total_tva" for table llx_propal, llx_supplier_proposal, llx_commande, llx_commande_fournisseur for better field name consistency +* Field "tva" renamed into "total_tva" for llx_facture, table llx_propal, llx_supplier_proposal, llx_commande, llx_commande_fournisseur for better field name consistency * Field "total" renamed into "total_ttc" for table llx_propal, llx_supplier_proposal for better field name consistency * 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 subtituion 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 ***** + +FIX: Allow disabling of a module (not a dangerous action) even if there is problem with token (due to bugged modules). +FIX: 13.0 - fatal - missing inclusion of ajax.lib.php for calling 'ajax_autocompleter()' +FIX: #17919 pictures in docs +FIX: #18006 +FIX: Accountancy - if we define a date start, automatic binding try to continue to solve old binding +FIX: Accountancy - Limit date payment not registered on purchases operations +FIX: Can't edit replacement invoice +FIX: deposit can create credit note in payment conf +FIX: division by zero on create +FIX: holiday: balances not updated correctly with pgsql because of case sensitivity field +FIX: holiday: status filter parameter has been renamed but not in links it was used +FIX: List and Create Companies Left Menus +FIX: method exists +FIX: need to add payment sum to getlibstatus function in object linked block +FIX: permission to close a proposal when using advanced permissions +FIX: Problem of z-index with popup and top menu +FIX: same thing on supplier orders +FIX: Status of invoice when making a replacement invoice +FIX: update contact birthday alert ***** ChangeLog for 13.0.3 compared to 13.0.2 ***** @@ -337,7 +344,7 @@ FIX: File attachment on lots/batches FIX: handling $heightforinfotot when he's superior to a page height on Supplier Invoice FIX: hourglass and hide button to pay FIX: massaction validate invoice do not regenerate PDF -FIX: missing mp4 video mime +FIX: #16627 fix missing mp4 video mime FIX: picto on shipment to reset qty to 0. Some quantities were not reset. FIX: Protection to avoid #16504 FIX: rounding amount on card updating diff --git a/htdocs/accountancy/admin/index.php b/htdocs/accountancy/admin/index.php index 98320613bfc..f8c0c95d3c1 100644 --- a/htdocs/accountancy/admin/index.php +++ b/htdocs/accountancy/admin/index.php @@ -91,7 +91,6 @@ if ($action == 'update') { if (!$error) { foreach ($list as $constname) { $constvalue = GETPOST($constname, 'alpha'); - var_dump($constname); if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) { $error++; } diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php index 4c7194b2255..c156a388735 100644 --- a/htdocs/accountancy/bookkeeping/card.php +++ b/htdocs/accountancy/bookkeeping/card.php @@ -637,6 +637,8 @@ if ($action == 'create') { print_liste_field_titre("Credit", "", "", "", "", 'class="right"'); if (empty($object->date_validation)) { print_liste_field_titre("Action", "", "", "", "", 'width="60" class="center"'); + } else { + print_liste_field_titre(""); } print "\n"; @@ -683,8 +685,8 @@ if ($action == 'create') { print ''.price($line->debit).''; print ''.price($line->credit).''; - if (empty($line->date_export) || empty($line->date_validation)) { - print ''; + print ''; + if (empty($line->date_export) && empty($line->date_validation)) { print 'id . '&piece_num=' . urlencode($line->piece_num) . '&mode=' . urlencode($mode) . '&token=' . urlencode(newToken()) . '">'; print img_edit('', 0, 'class="marginrightonly"'); print '  '; @@ -713,7 +715,7 @@ if ($action == 'create') { setEventMessages(null, array($langs->trans('MvtNotCorrectlyBalanced', $total_debit, $total_credit)), 'warnings'); } - if (empty($object->date_export) || empty($object->date_validation)) { + if (empty($object->date_export) && empty($object->date_validation)) { if ($action == "" || $action == 'add') { print ''; print ''; diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index a70bb710937..bc260c77ed3 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -366,42 +366,42 @@ if (empty($reshook)) { if (!empty($search_date_creation_start)) { $filter['t.date_creation>='] = $search_date_creation_start; $tmp = dol_getdate($search_date_creation_start); - $param .= '&date_creation_startmonth='.urlencode($tmp['mon']).'&date_creation_startday='.urlencode($tmp['mday']).'&date_creation_startyear='.urlencode($tmp['year']); + $param .= '&search_date_creation_startmonth='.urlencode($tmp['mon']).'&search_date_creation_startday='.urlencode($tmp['mday']).'&search_date_creation_startyear='.urlencode($tmp['year']); } if (!empty($search_date_creation_end)) { $filter['t.date_creation<='] = $search_date_creation_end; $tmp = dol_getdate($search_date_creation_end); - $param .= '&date_creation_endmonth='.urlencode($tmp['mon']).'&date_creation_endday='.urlencode($tmp['mday']).'&date_creation_endyear='.urlencode($tmp['year']); + $param .= '&search_date_creation_endmonth='.urlencode($tmp['mon']).'&search_date_creation_endday='.urlencode($tmp['mday']).'&search_date_creation_endyear='.urlencode($tmp['year']); } if (!empty($search_date_modification_start)) { $filter['t.tms>='] = $search_date_modification_start; $tmp = dol_getdate($search_date_modification_start); - $param .= '&date_modification_startmonth='.urlencode($tmp['mon']).'&date_modification_startday='.urlencode($tmp['mday']).'&date_modification_startyear='.urlencode($tmp['year']); + $param .= '&search_date_modification_startmonth='.urlencode($tmp['mon']).'&search_date_modification_startday='.urlencode($tmp['mday']).'&search_date_modification_startyear='.urlencode($tmp['year']); } if (!empty($search_date_modification_end)) { $filter['t.tms<='] = $search_date_modification_end; $tmp = dol_getdate($search_date_modification_end); - $param .= '&date_modification_endmonth='.urlencode($tmp['mon']).'&date_modification_endday='.urlencode($tmp['mday']).'&date_modification_endyear='.urlencode($tmp['year']); + $param .= '&search_date_modification_endmonth='.urlencode($tmp['mon']).'&search_date_modification_endday='.urlencode($tmp['mday']).'&search_date_modification_endyear='.urlencode($tmp['year']); } if (!empty($search_date_export_start)) { $filter['t.date_export>='] = $search_date_export_start; $tmp = dol_getdate($search_date_export_start); - $param .= '&date_export_startmonth='.urlencode($tmp['mon']).'&date_export_startday='.urlencode($tmp['mday']).'&date_export_startyear='.urlencode($tmp['year']); + $param .= '&search_date_export_startmonth='.urlencode($tmp['mon']).'&search_date_export_startday='.urlencode($tmp['mday']).'&search_date_export_startyear='.urlencode($tmp['year']); } if (!empty($search_date_export_end)) { $filter['t.date_export<='] = $search_date_export_end; $tmp = dol_getdate($search_date_export_end); - $param .= '&date_export_endmonth='.urlencode($tmp['mon']).'&date_export_endday='.urlencode($tmp['mday']).'&date_export_endyear='.urlencode($tmp['year']); + $param .= '&search_date_export_endmonth='.urlencode($tmp['mon']).'&search_date_export_endday='.urlencode($tmp['mday']).'&search_date_export_endyear='.urlencode($tmp['year']); } if (!empty($search_date_validation_start)) { $filter['t.date_validated>='] = $search_date_validation_start; $tmp = dol_getdate($search_date_validation_start); - $param .= '&date_validation_startmonth='.urlencode($tmp['mon']).'&date_validation_startday='.urlencode($tmp['mday']).'&date_validation_startyear='.urlencode($tmp['year']); + $param .= '&search_date_validation_startmonth='.urlencode($tmp['mon']).'&search_date_validation_startday='.urlencode($tmp['mday']).'&search_date_validation_startyear='.urlencode($tmp['year']); } if (!empty($search_date_validation_end)) { $filter['t.date_validated<='] = $search_date_validation_end; $tmp = dol_getdate($search_date_validation_end); - $param .= '&date_validation_endmonth='.urlencode($tmp['mon']).'&date_validation_endday='.urlencode($tmp['mday']).'&date_validation_endyear='.urlencode($tmp['year']); + $param .= '&search_date_validation_endmonth='.urlencode($tmp['mon']).'&search_date_validation_endday='.urlencode($tmp['mday']).'&search_date_validation_endyear='.urlencode($tmp['year']); } if (!empty($search_debit)) { $filter['t.debit'] = $search_debit; @@ -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 ''; } @@ -904,10 +904,10 @@ print $hookmanager->resPrint; if (!empty($arrayfields['t.date_creation']['checked'])) { print ''; print '
'; - print $form->selectDate($search_date_creation_start, 'date_creation_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + print $form->selectDate($search_date_creation_start, 'search_date_creation_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); print '
'; print '
'; - print $form->selectDate($search_date_creation_end, 'date_creation_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); + print $form->selectDate($search_date_creation_end, 'search_date_creation_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); print '
'; print ''; } @@ -915,10 +915,10 @@ if (!empty($arrayfields['t.date_creation']['checked'])) { if (!empty($arrayfields['t.tms']['checked'])) { print ''; print '
'; - print $form->selectDate($search_date_modification_start, 'date_modification_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + print $form->selectDate($search_date_modification_start, 'search_date_modification_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); print '
'; print '
'; - print $form->selectDate($search_date_modification_end, 'date_modification_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + print $form->selectDate($search_date_modification_end, 'search_date_modification_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); print '
'; print ''; } @@ -926,10 +926,10 @@ if (!empty($arrayfields['t.tms']['checked'])) { if (!empty($arrayfields['t.date_export']['checked'])) { print ''; print '
'; - print $form->selectDate($search_date_export_start, 'date_export_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + print $form->selectDate($search_date_export_start, 'search_date_export_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); print '
'; print '
'; - print $form->selectDate($search_date_export_end, 'date_export_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); + print $form->selectDate($search_date_export_end, 'search_date_export_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); print '
'; print ''; } @@ -937,10 +937,10 @@ if (!empty($arrayfields['t.date_export']['checked'])) { if (!empty($arrayfields['t.date_validated']['checked'])) { print ''; print '
'; - print $form->selectDate($search_date_validation_start, 'date_validation_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + 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, 'date_validation_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); + print $form->selectDate($search_date_validation_end, 'search_date_validation_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); print '
'; print ''; } @@ -1243,7 +1243,7 @@ while ($i < min($num, $limit)) { // Action column print ''; - if (empty($line->date_export) || empty($line->date_validation)) { + if (empty($line->date_export) && empty($line->date_validation)) { if ($user->rights->accounting->mouvements->creer) { print '' . img_edit() . ''; } diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 98c3f14191b..27f23d36a74 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) { @@ -484,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 .= '
'; @@ -564,6 +588,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 +640,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 @@ -632,20 +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 = 7; - - if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING) || empty($arrayfields['t.lettering_code']['checked'])) { - $colnumber--; - } - if (empty($arrayfields['t.date_export']['checked'])) { - $colnumber--; - } - - $colspan = $totalarray['nbfield'] - $colnumber; - $colspanend = $totalarray['nbfield'] - $colnumberend; // Show a subtotal by accounting account if (isset($displayed_account_number)) { print ''; @@ -845,6 +882,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 @@ -852,12 +897,14 @@ while ($i < min($num, $limit)) { // Action column print ''; - if (empty($line->date_export)) { + if (empty($line->date_export) && empty($line->date_validation)) { if ($user->rights->accounting->mouvements->creer) { - print ''.img_edit().''; + print '' . img_edit() . ''; } + } + if (empty($line->date_validation)) { if ($user->rights->accounting->mouvements->supprimer) { - print '   '.img_delete().''; + print ''.img_delete().''; } } print ''; @@ -874,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 ''.$langs->trans("TotalForAccount").' '.$accountg.':'; print ''.price($sous_total_debit).''; diff --git a/htdocs/accountancy/bookkeeping/listbysubaccount.php b/htdocs/accountancy/bookkeeping/listbysubaccount.php index 20899c693c6..5e83c729fb1 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)) { @@ -488,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 .= '
'; @@ -568,6 +590,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 +642,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 @@ -636,21 +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 = 7; - - if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING) || empty($arrayfields['t.lettering_code']['checked'])) { - $colnumber--; - } - if (empty($arrayfields['t.date_export']['checked'])) { - $colnumber--; - } - - $colspan = $totalarray['nbfield'] - $colnumber; - $colspanend = $totalarray['nbfield'] - $colnumberend; - // Show a subtotal by accounting account if (isset($displayed_account_number)) { print ''; @@ -859,6 +893,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 @@ -866,12 +908,14 @@ while ($i < min($num, $limit)) { // Action column print ''; - if (empty($line->date_export)) { + if (empty($line->date_export) && empty($line->date_validation)) { if ($user->rights->accounting->mouvements->creer) { - print ''.img_edit().''; + print '' . img_edit() . ''; } + } + if (empty($line->date_validation)) { if ($user->rights->accounting->mouvements->supprimer) { - print '   '.img_delete().''; + print ''.img_delete().''; } } print ''; @@ -888,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 ''.$langs->trans("TotalForAccount").' '.$accountg.':'; print ''.price($sous_total_debit).''; diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index 0bd60445613..c8aa1407ddb 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 @@ -477,34 +477,43 @@ class AccountancyExport } /** - * Export format : CIEL + * 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..." + * + * 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; + $code_compta = length_accountg($data->numero_compte); if (!empty($data->subledger_account)) { - $code_compta = $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'); + $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'] = 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); - $Tab['montant'] = str_pad(abs($data->debit - $data->credit), 13, ' ', STR_PAD_LEFT); + $Tab['montant'] = str_pad(price2fec(abs($data->debit - $data->credit)), 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/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 6bd39f4e227..aeaa42154d8 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -1506,6 +1506,7 @@ class BookKeeping extends CommonObject $sql = "DELETE"; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element; $sql .= " WHERE piece_num = ".(int) $piecenum; + $sql .= " AND date_validated IS NULL"; // For security, exclusion of validated entries at the time of deletion $sql .= " AND entity IN (".getEntity('accountancy').")"; $resql = $this->db->query($sql); 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 ""; - 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 ""; + print "".$reflabel.""; + print ''.$val["type_payment"].""; + print ''.($mt < 0 ? price(-$mt) : '').""; + print ''.($mt >= 0 ? price($mt) : '').""; + print ""; } } diff --git a/htdocs/accountancy/tpl/export_journal.tpl.php b/htdocs/accountancy/tpl/export_journal.tpl.php index 1700d391f54..ecb0f7a6b09 100644 --- a/htdocs/accountancy/tpl/export_journal.tpl.php +++ b/htdocs/accountancy/tpl/export_journal.tpl.php @@ -16,6 +16,8 @@ * along with this program. If not, see . */ +// $formatexportset ùust be defined + // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { print "Error, template page can't be called as URL"; @@ -56,6 +58,8 @@ if ($accountancyexport->getFormatCode($formatexportset) == $accountancyexport::$ $endaccountingperiod = dol_print_date(dol_get_last_day($tmparray['year'], $tmparray['mon']), 'dayxcard'); $completefilename = $siren."FEC".$endaccountingperiod.".txt"; +} 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/adherents/list.php b/htdocs/adherents/list.php index 1c93b247dfc..68430a71bab 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -176,7 +176,7 @@ if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massa $massaction = ''; } -$parameters = array('socid'=>$socid); +$parameters = array('socid'=>isset($socid) ? $socid : null); $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'); diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php index d3d84cb3624..7146e89648e 100644 --- a/htdocs/adherents/subscription/list.php +++ b/htdocs/adherents/subscription/list.php @@ -115,7 +115,7 @@ if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massa $massaction = ''; } -$parameters = array('socid'=>$socid); +$parameters = array('socid'=>isset($socid) ? $socid : null); $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'); @@ -496,7 +496,7 @@ while ($i < min($num, $limit)) { $adherent->gender = $obj->gender; $adherent->morphy = $obj->morphy; $adherent->email = $obj->email; - $adherent->typeid = $obj->type; + $adherent->typeid = $obj->fk_type; $adherent->datefin = $db->jdate($obj->datef); $typeid = ($obj->fk_type > 0 ? $obj->fk_type : $adherent->typeid); diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index 033592a9afc..10560d38648 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -43,6 +43,8 @@ $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'alpha'); $backtopage = GETPOST('backtopage', 'alpha'); +$sall = GETPOST("sall", "alpha"); +$filter = GETPOST("filter", 'alpha'); $search_lastname = GETPOST('search_lastname', 'alpha'); $search_login = GETPOST('search_login', 'alpha'); $search_email = GETPOST('search_email', 'alpha'); diff --git a/htdocs/adherents/type_translation.php b/htdocs/adherents/type_translation.php index 7435fc440ed..6c8f273ae77 100644 --- a/htdocs/adherents/type_translation.php +++ b/htdocs/adherents/type_translation.php @@ -157,7 +157,7 @@ $form = new Form($db); $formadmin = new FormAdmin($db); $head = member_type_prepare_head($object); -$titre = $langs->trans("MemberType".$object->type); +$titre = $langs->trans("MemberType".$object->id); // Calculate $cnt_trans $cnt_trans = 0; diff --git a/htdocs/admin/clicktodial.php b/htdocs/admin/clicktodial.php index 25ada4d2d89..9fd92f45faa 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', '', 'mobile'); } else { $langs->load("errors"); print '
'.$langs->trans("WarningClickToDialUserSetupNotComplete").'
'; diff --git a/htdocs/admin/paymentbybanktransfer.php b/htdocs/admin/paymentbybanktransfer.php index 7cf522abc33..43ad8c15929 100644 --- a/htdocs/admin/paymentbybanktransfer.php +++ b/htdocs/admin/paymentbybanktransfer.php @@ -150,42 +150,44 @@ print ''; print ''; print ''; -print ''; +print ''; print ''; 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("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/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'); 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/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++; diff --git a/htdocs/admin/system/database-tables.php b/htdocs/admin/system/database-tables.php index 7535500e799..3d31c516858 100644 --- a/htdocs/admin/system/database-tables.php +++ b/htdocs/admin/system/database-tables.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2005 Laurent Destailleur + * Copyright (C) 2004-2021 Laurent Destailleur * Copyright (C) 2004 Sebastien Di Cintio * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2005-2012 Regis Houssin @@ -21,9 +21,13 @@ /** * \file htdocs/admin/system/database-tables.php - * \brief Page with information on database tables + * \brief Page with information on database tables. Add also some maintenance action to convert tables. */ +if (! defined('CSRFCHECK_WITH_TOKEN')) { + define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET +} + require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; @@ -126,14 +130,14 @@ if (!$base) { print ''; print ''.$obj->Engine.''; if (isset($obj->Engine) && $obj->Engine == "MyISAM") { - print ''.$langs->trans("Convert").' InnoDb'; + print ''.$langs->trans("Convert").' InnoDb'; } else { print ' '; } print ''; print $obj->Row_format; if (isset($obj->Row_format) && (in_array($obj->Row_format, array("Compact")))) { - print '
'.$langs->trans("Convert").' Dynamic'; + print '
'.$langs->trans("Convert").' Dynamic'; } print ''; print ''.$obj->Rows.''; @@ -145,7 +149,7 @@ if (!$base) { print ''.$obj->Check_time.''; print ''.$obj->Collation; if (isset($obj->Collation) && (in_array($obj->Collation, array("utf8mb4_general_ci", "utf8mb4_unicode_ci", "latin1_swedish_ci")))) { - print '
'.$langs->trans("Convert").' UTF8'; + print '
'.$langs->trans("Convert").' UTF8'; } print ''; print ''; diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 032a23a68c8..b745ad75818 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(); @@ -88,10 +88,14 @@ if (function_exists('exec')) { } print '
'; -print "PHP safe_mode = ".(ini_get('safe_mode') ? ini_get('safe_mode') : yn(0)).'   '.$langs->trans("Deprecated")." (removed in PHP 5.4)
\n"; +print "PHP session.use_strict_mode = ".(ini_get('session.use_strict_mode') ? ini_get('session.use_strict_mode') : yn(0)).'   ('.$langs->trans("RecommendedValueIs", '1').")
\n"; +print "PHP session.use_only_cookies = ".(ini_get('session.use_only_cookies') ? ini_get('session.use_only_cookies') : yn(0)).'   ('.$langs->trans("RecommendedValueIs", '1').")
\n"; +print "PHP session.cookie_httponly = ".(ini_get('session.cookie_httponly') ? ini_get('session.cookie_httponly') : '').'   ('.$langs->trans("RecommendedValueIs", '1').")
\n"; +print "PHP session.cookie_samesite = ".(ini_get('session.cookie_samesite') ? ini_get('session.cookie_samesite') : 'None').'   ('.$langs->trans("RecommendedValueIs", 'Strict').")
\n"; print "PHP open_basedir = ".(ini_get('open_basedir') ? ini_get('open_basedir') : yn(0).'   ('.$langs->trans("RecommendedValueIs", $langs->transnoentitiesnoconv("ARestrictedPath").', '.$langs->transnoentitiesnoconv("Example").' '.$_SERVER["DOCUMENT_ROOT"]).')')."
\n"; print "PHP allow_url_fopen = ".(ini_get('allow_url_fopen') ? img_picto($langs->trans("YouShouldSetThisToOff"), 'warning').' '.ini_get('allow_url_fopen') : yn(0)).'   ('.$langs->trans("RecommendedValueIs", $langs->transnoentitiesnoconv("No")).")
\n"; print "PHP allow_url_include = ".(ini_get('allow_url_include') ? img_picto($langs->trans("YouShouldSetThisToOff"), 'warning').' '.ini_get('allow_url_include') : yn(0)).'   ('.$langs->trans("RecommendedValueIs", $langs->transnoentitiesnoconv("No")).")
\n"; +print "PHP safe_mode = ".(ini_get('safe_mode') ? ini_get('safe_mode') : yn(0)).'   '.$langs->trans("Deprecated")." (removed in PHP 5.4)
\n"; print "PHP disable_functions = "; $arrayoffunctionsdisabled = explode(',', ini_get('disable_functions')); $arrayoffunctionstodisable = explode(',', 'pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals'); @@ -198,6 +202,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 +224,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/admin/tools/dolibarr_export.php b/htdocs/admin/tools/dolibarr_export.php index 428c80676a2..4f6977ffb41 100644 --- a/htdocs/admin/tools/dolibarr_export.php +++ b/htdocs/admin/tools/dolibarr_export.php @@ -136,7 +136,7 @@ $title = $langs->trans("Backup"); print load_fiche_titre($title, '', 'title_setup'); //print_barre_liste($langs->trans("Backup"), '', '', '', '', '', $langs->trans("BackupDesc",DOL_DATA_ROOT), 0, 0, 'title_setup'); -print '
'; +print '
'; print $langs->trans("BackupDesc", DOL_DATA_ROOT); print '
'; print '
'; @@ -147,8 +147,11 @@ print ''; print ''; print '
1'; +print ''; print $langs->trans("BackupDesc3", $dolibarr_main_db_name).'
'; //print $langs->trans("BackupDescY").'
'; +print '
'; + print '
'; print '
'; @@ -157,7 +160,7 @@ $title = $langs->trans("BackupDumpWizard"); print load_fiche_titre($title); -print ''; +print '
'; print ''; 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++; @@ -906,7 +906,7 @@ if (!empty($conf->propal->enabled) && $user->rights->propal->lire) { print ''; print ''; - print ''; + print ''; print ''; print ''; @@ -1023,7 +1023,7 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire) { print ''; print ''; - print ''; + print ''; print ''; print ''; 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/comm/propal/card.php b/htdocs/comm/propal/card.php index 3c0d8dd9a28..802416f1626 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -2529,7 +2529,7 @@ if ($action == 'create') { } // ReOpen - if (($object->statut == Propal::STATUS_SIGNED || $object->statut == Propal::STATUS_NOTSIGNED || $object->statut == Propal::STATUS_BILLED) && $usercanclose) { + if ( (( ! empty($conf->global->PROPAL_REOPEN_UNSIGNED_ONLY) && $object->statut == Propal::STATUS_NOTSIGNED) || (empty($conf->global->PROPAL_REOPEN_UNSIGNED_ONLY) && ($object->statut == Propal::STATUS_SIGNED || $object->statut == Propal::STATUS_NOTSIGNED || $object->statut == Propal::STATUS_BILLED))) && $usercanclose) { print 'global->MAIN_JUMP_TAG) ? '' : '#reopen').'"'; print '>'.$langs->trans('ReOpen').''; } diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 333d4e2ded6..65b446727e5 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -195,7 +195,7 @@ class Commande extends CommonOrder /** * @var int Date expected for delivery - * @see delivery_date + * @see $delivery_date * @deprecated */ public $date_livraison; 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 ''; if ($conf->prelevement->enabled) { - print ''; + print ''; print ''; print ''; } if ($conf->paymentbybanktransfer->enabled) { - print ''; + print ''; print ''; print ''; } @@ -1053,12 +1053,12 @@ if ($action == 'create') { print ''; if ($conf->prelevement->enabled) { - print ''; + print ''; print ''; } if ($conf->paymentbybanktransfer->enabled) { - print ''; + print ''; 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/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 $langs->trans("DatabaseName").' : '.$dolibarr_main_db_name.'
'; @@ -554,8 +557,10 @@ print ''; print '
2'; +print ''; print $langs->trans("BackupDesc2", DOL_DATA_ROOT).'
'; print $langs->trans("BackupDescX").'

'; +print '
'; print '
'; diff --git a/htdocs/admin/tools/dolibarr_import.php b/htdocs/admin/tools/dolibarr_import.php index 1fc0ca49221..29bfe5c12a4 100644 --- a/htdocs/admin/tools/dolibarr_import.php +++ b/htdocs/admin/tools/dolibarr_import.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2006-2021 Laurent Destailleur * Copyright (C) 2006-2012 Regis Houssin * * This program is free software; you can redistribute it and/or modify @@ -22,6 +22,10 @@ * \brief Page to import database */ +if (! defined('CSRFCHECK_WITH_TOKEN')) { + define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET +} + require '../../main.inc.php'; // Load translation files required by the page @@ -72,7 +76,7 @@ jQuery(document).ready(function() { print load_fiche_titre($langs->trans("Restore"), '', 'title_setup'); -print '
'; +print '
'; print $langs->trans("RestoreDesc", DOL_DATA_ROOT); print '
'; print '
'; @@ -81,7 +85,9 @@ print '
';
1 '; print $langs->trans("RestoreDesc2", DOL_DATA_ROOT).'

'; +print ''; ?>
@@ -90,7 +96,9 @@ print $langs->trans("RestoreDesc2", DOL_DATA_ROOT).'

';
2 '; print $langs->trans("RestoreDesc3", $dolibarr_main_db_name).'

'; +print ''; ?> trans("DatabaseName").' : '.$dolibarr_main_db_name.''; ?>

diff --git a/htdocs/admin/tools/export_files.php b/htdocs/admin/tools/export_files.php index 34685676320..384b08e19cf 100644 --- a/htdocs/admin/tools/export_files.php +++ b/htdocs/admin/tools/export_files.php @@ -22,6 +22,10 @@ * \brief Page to export documents into a compressed file */ +if (! defined('CSRFCHECK_WITH_TOKEN')) { + define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET +} + require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; diff --git a/htdocs/admin/tools/listsessions.php b/htdocs/admin/tools/listsessions.php index 61d2b1cea58..10a38fb59a1 100644 --- a/htdocs/admin/tools/listsessions.php +++ b/htdocs/admin/tools/listsessions.php @@ -22,9 +22,14 @@ * \brief List of PHP sessions */ +if (! defined('CSRFCHECK_WITH_TOKEN')) { + define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET +} + require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; + // Load translation files required by the page $langs->loadLangs(array("companies", "install", "users", "other")); @@ -185,14 +190,14 @@ print '
'; if (empty($conf->global->MAIN_ONLY_LOGIN_ALLOWED)) { - print ''.$langs->trans("LockNewSessions").''; + print ''.$langs->trans("LockNewSessions").''; } else { - print ''.$langs->trans("UnlockNewSessions").''; + print ''.$langs->trans("UnlockNewSessions").''; } if ($savehandler == 'files') { if (count($listofsessions)) { - print ''.$langs->trans("PurgeSessions").''; + print ''.$langs->trans("PurgeSessions").''; } } diff --git a/htdocs/admin/tools/purge.php b/htdocs/admin/tools/purge.php index e20b9c2b13a..09647549c8b 100644 --- a/htdocs/admin/tools/purge.php +++ b/htdocs/admin/tools/purge.php @@ -21,15 +21,15 @@ * \brief Page to purge files (temporary or not) */ +if (! defined('CSRFCHECK_WITH_TOKEN')) { + define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET +} + require '../../main.inc.php'; include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $langs->load("admin"); -if (!$user->admin) { - accessforbidden(); -} - $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); $choice = GETPOST('choice', 'aZ09'); @@ -42,10 +42,15 @@ if (!empty($conf->syslog->enabled)) { $filelog = preg_replace('/DOL_DATA_ROOT/i', DOL_DATA_ROOT, $filelog); } +if (!$user->admin) { + accessforbidden(); +} + /* * Actions */ + if ($action == 'purge' && !preg_match('/^confirm/i', $choice) && ($choice != 'allfiles' || $confirm == 'yes')) { // Increase limit of time. Works only if we are not in safe mode $ExecTimeLimit = 600; diff --git a/htdocs/admin/tools/update.php b/htdocs/admin/tools/update.php index 5a6ff94ce57..821bcd9e3f3 100644 --- a/htdocs/admin/tools/update.php +++ b/htdocs/admin/tools/update.php @@ -22,6 +22,10 @@ * \brief Page to make a Dolibarr online upgrade */ +if (! defined('CSRFCHECK_WITH_TOKEN')) { + define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET +} + require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; @@ -100,7 +104,7 @@ if (function_exists('curl_init')) { print $langs->trans("LastStableVersion").' : '.$langs->trans("UpdateServerOffline").'
'; } } else { - print $langs->trans("LastStableVersion").' : '.$langs->trans("Check").'
'; + print $langs->trans("LastStableVersion").' : '.$langs->trans("Check").'
'; } } @@ -113,14 +117,14 @@ print '
'; print $langs->trans("ThisIsProcessToFollow").'
'; print ''.$langs->trans("StepNb", 1).': '; $fullurl = ''.$urldolibarr.''; -print $langs->trans("DownloadPackageFromWebSite", $fullurl).'
'; +print str_replace('{s}', $fullurl, $langs->trans("DownloadPackageFromWebSite", '{s}')).'
'; print ''.$langs->trans("StepNb", 2).': '; -print $langs->trans("UnpackPackageInDolibarrRoot", $dolibarrroot).'
'; +print str_replace('{s}', $dolibarrroot, $langs->trans("UnpackPackageInDolibarrRoot", '{s}')).'
'; print ''.$langs->trans("StepNb", 3).': '; print $langs->trans("RemoveLock", $dolibarrdataroot.'/install.lock').'
'; print ''.$langs->trans("StepNb", 4).': '; $fullurl = ''.DOL_URL_ROOT.'/install/'; -print $langs->trans("CallUpdatePage", $fullurl).'
'; +print str_replace('{s}', $fullurl, $langs->trans("CallUpdatePage", '{s}')).'
'; print ''.$langs->trans("StepNb", 5).': '; print $langs->trans("RestoreLock", $dolibarrdataroot.'/install.lock').'
'; @@ -133,8 +137,9 @@ print '
'; print $langs->trans("AddExtensionThemeModuleOrOther").'
'; print '
'; - -print $langs->trans("GoModuleSetupArea", DOL_URL_ROOT.'/admin/modules.php?mode=deploy', $langs->transnoentities("Home").' - '.$langs->transnoentities("Setup").' - '.$langs->transnoentities("Modules")); +$texttoshow = $langs->trans("GoModuleSetupArea", DOL_URL_ROOT.'/admin/modules.php?mode=deploy', '{s2}'); +$texttoshow = str_replace('{s2}', img_picto('', 'tools', 'class="pictofixedwidth"').$langs->transnoentities("Home").' - '.$langs->transnoentities("Setup").' - '.$langs->transnoentities("Modules"), $texttoshow); +print $texttoshow; // End of page llxFooter(); diff --git a/htdocs/bom/bom_list.php b/htdocs/bom/bom_list.php index 76f16c838be..2cd7492395d 100644 --- a/htdocs/bom/bom_list.php +++ b/htdocs/bom/bom_list.php @@ -297,7 +297,7 @@ $sql .= $object->getFieldList('t'); // Add fields from extrafields if (!empty($extrafields->attributes[$object->table_element]['label'])) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { - $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key.' as options_'.$key.', ' : ''); + $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key.' as options_'.$key.' ' : ''); } } // Add fields from hooks diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php index eeca990ef28..8ebb9f43b1e 100644 --- a/htdocs/categories/viewcat.php +++ b/htdocs/categories/viewcat.php @@ -142,6 +142,11 @@ if ($id > 0 && $removeelem > 0) { $tmpobject = new User($db); $result = $tmpobject->fetch($removeelem); $elementtype = 'user'; + } elseif ($type == Categorie::TYPE_TICKET && $user->rights->ticket->write) { + require_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php'; + $tmpobject = new Ticket($db); + $result = $tmpobject->fetch($removeelem); + $elementtype = 'ticket'; } $result = $object->del_type($tmpobject, $elementtype); @@ -167,7 +172,8 @@ if ($user->rights->categorie->supprimer && $action == 'confirm_delete' && $confi if ($elemid && $action == 'addintocategory' && (($type == Categorie::TYPE_PRODUCT && ($user->rights->produit->creer || $user->rights->service->creer)) || ($type == Categorie::TYPE_CUSTOMER && $user->rights->societe->creer) || - ($type == Categorie::TYPE_SUPPLIER && $user->rights->societe->creer) + ($type == Categorie::TYPE_SUPPLIER && $user->rights->societe->creer) || + ($type == Categorie::TYPE_TICKET && $user->rights->ticket->write) )) { if ($type == Categorie::TYPE_PRODUCT) { require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; @@ -181,6 +187,10 @@ if ($elemid && $action == 'addintocategory' && require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; $newobject = new Societe($db); $elementtype = 'supplier'; + } elseif ($type == Categorie::TYPE_TICKET) { + require_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php'; + $newobject = new Ticket($db); + $elementtype = 'ticket'; } $result = $newobject->fetch($elemid); @@ -1024,6 +1034,78 @@ if ($type == Categorie::TYPE_WAREHOUSE) { } } +if ($type == Categorie::TYPE_TICKET) { + $permission = ($user->rights->categorie->creer || $user->rights->categorie->creer); + + $tickets = $object->getObjectsInCateg($type, 0, $limit, $offset); + if ($tickets < 0) { + dol_print_error($db, $object->error, $object->errors); + } else { + // Form to add record into a category + $showclassifyform = 1; + if ($showclassifyform) { + print '
'; + print '
'; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print '
'; + print $langs->trans("AddTicketIntoCategory").'  '; + $form->selectTickets('', 'elemid'); + print '
'; + print '
'; + } + + print '
'; + print ''; + print ''; + print ''; + print ''; + print ''; + + print '
'; + $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($tickets); $nbtotalofrecords = ''; $newcardbutton = ''; + print_barre_liste($langs->trans("Ticket"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'ticket', 0, $newcardbutton, '', $limit); + + + print ''."\n"; + print ''."\n"; + + if (count($tickets) > 0) { + $i = 0; + foreach ($tickets as $ticket) { + $i++; + if ($i > $limit) break; + + print "\t".''."\n"; + print '\n"; + print '\n"; + // Link to delete from category + print ''; + print "\n"; + } + } else { + print ''; + } + print "
'.$langs->trans("Ref").'
'; + print $ticket->getNomUrl(1); + print "'.$ticket->label."'; + if ($permission) { + print ""; + print $langs->trans("DeleteFromCat"); + print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); + print ""; + } + print '
'.$langs->trans("ThisCategoryHasNoItems").'
\n"; + + print '
'."\n"; + } +} // End of page llxFooter(); diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 7fd294b89b2..c6c0d277edd 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -2340,7 +2340,7 @@ class ActionComm extends CommonObject $sendContent = make_substitutions($langs->trans($arraymessage->content), $substitutionarray); //Topic - $sendTopic = (!empty($arraymessage->topic)) ? $arraymessage->topic : html_entity_decode($langs->trans('EventReminder')); + $sendTopic = (!empty($arraymessage->topic)) ? $arraymessage->topic : html_entity_decode($langs->transnoentities('EventReminder')); // Recipient $recipient = new User($this->db); diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php index e95cc3366c5..9c587a934e2 100644 --- a/htdocs/comm/action/list.php +++ b/htdocs/comm/action/list.php @@ -47,7 +47,7 @@ $massaction = GETPOST('massaction', 'alpha'); $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'actioncommlist'; // To manage different context of search $resourceid = GETPOST("search_resourceid", "int") ?GETPOST("search_resourceid", "int") : GETPOST("resourceid", "int"); $pid = GETPOST("search_projectid", 'int', 3) ?GETPOST("search_projectid", 'int', 3) : GETPOST("projectid", 'int', 3); -$search_status = (GETPOST("search_status", 'alpha') != '') ?GETPOST("search_status", 'alpha') : GETPOST("status", 'alpha'); +$search_status = (GETPOST("search_status", 'aZ09') != '') ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); $type = GETPOST('search_type', 'alphanohtml') ?GETPOST('search_type', 'alphanohtml') : GETPOST('type', 'alphanohtml'); $optioncss = GETPOST('optioncss', 'alpha'); $year = GETPOST("year", 'int'); diff --git a/htdocs/comm/index.php b/htdocs/comm/index.php index 11accdb3f0a..48e08ce3c0d 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 '
'.$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).'
'; 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/card.php b/htdocs/compta/bank/card.php index ea9f7799849..d1cc0413bfd 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -212,7 +212,7 @@ if (empty($reshook)) { $object->ics = trim(GETPOST("ics", 'alpha')); $object->ics_transfer = trim(GETPOST("ics_transfer", 'alpha')); - $account_number = GETPOST('account_number', 'alpha'); + $account_number = GETPOST('account_number', 'alphanohtml'); if (empty($account_number) || $account_number == '-1') { $object->account_number = ''; } else { @@ -754,13 +754,13 @@ if ($action == 'create') { print '
'.$langs->trans("ICS").'
'.$langs->trans("ICS").' ('.$langs->trans("StandingOrder").')'.$object->ics.'
'.$langs->trans("ICSTransfer").'
'.$langs->trans("ICS").' ('.$langs->trans("BankTransfer").')'.$object->ics_transfer.'
'.$langs->trans("ICS").'
'.$langs->trans("ICS").' ('.$langs->trans("StandingOrder").')
'.$langs->trans("ICSTransfer").'
'.$langs->trans("ICS").' ('.$langs->trans("BankTransfer").')
'; - print '"; + print '"; if ($user->rights->banque->consolidate) { print ''; } else { - print ''; + print ''; } print ''; diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 699a10d3ef5..5c21f2b9539 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -5274,7 +5274,8 @@ if ($action == 'create') { // 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) if ($object->close_code != 'replaced' || (!$objectidnext)) { // Not replaced by another invoice or replaced but the replacement invoice has been deleted 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'; diff --git a/htdocs/compta/prelevement/card.php b/htdocs/compta/prelevement/card.php index a94d068603a..b03ed9d93e0 100644 --- a/htdocs/compta/prelevement/card.php +++ b/htdocs/compta/prelevement/card.php @@ -325,19 +325,19 @@ if ($id > 0 || $ref) { // Actions if ($action != 'settransmitted' && $action != 'setcredited') { - print "\n
\n"; + print "\n".'
'."\n"; if (empty($object->date_trans) && $user->rights->prelevement->bons->send) { - print "id."\">".$langs->trans("SetToStatusSent").""; + print ''.$langs->trans("SetToStatusSent").''; } if (!empty($object->date_trans) && $object->date_credit == 0) { - print "id."\">".$langs->trans("ClassCredited").""; + print ''.$langs->trans("ClassCredited").''; } - print "id."\">".$langs->trans("Delete").""; + print ''.$langs->trans("Delete").''; - print "
"; + print '
'; } @@ -413,7 +413,7 @@ if ($id > 0 || $ref) { print "'; @@ -434,7 +434,7 @@ if ($id > 0 || $ref) { if ($obj->statut == 2) { if ($user->rights->prelevement->bons->credit) { //print ''.$langs->trans("StandingOrderReject").''; - print ''.$langs->trans("StandingOrderReject").''; + print ''.$langs->trans("StandingOrderReject").''; } else { //print ''.$langs->trans("StandingOrderReject").''; } diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php index 6793fb0a893..6f045f3ca74 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 = ''; } @@ -95,7 +96,7 @@ if (empty($reshook)) { $bank = new Account($db); $bank->fetch($conf->global->{$default_account}); if (empty($bank->ics) || empty($bank->ics_transfer)) { - $errormessage = str_replace('{url}', $bank->getNomUrl(1), $langs->trans("ErrorICSmissing", '{url}')); + $errormessage = str_replace('{url}', $bank->getNomUrl(1, '', '', -1, 1), $langs->trans("ErrorICSmissing", '{url}')); setEventMessages($errormessage, null, 'errors'); header("Location: ".DOL_URL_ROOT.'/compta/prelevement/create.php'); exit; @@ -124,9 +125,13 @@ if (empty($reshook)) { } } else { if ($type != 'bank-transfer') { - setEventMessages($langs->trans("DirectDebitOrderCreated", $bprev->getNomUrl(1)), null); + $texttoshow = $langs->trans("DirectDebitOrderCreated", '{s}'); + $texttoshow = str_replace('{s}', $bprev->getNomUrl(1), $texttoshow); + setEventMessages($texttoshow, null); } else { - setEventMessages($langs->trans("CreditTransferOrderCreated", $bprev->getNomUrl(1)), null); + $texttoshow = $langs->trans("CreditTransferOrderCreated", '{s}'); + $texttoshow = str_replace('{s}', $bprev->getNomUrl(1), $texttoshow); + setEventMessages($texttoshow, null); } header("Location: ".DOL_URL_ROOT.'/compta/prelevement/card.php?id='.$bprev->id); @@ -165,7 +170,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'); } @@ -206,7 +215,7 @@ print $nb; print ''; print ''; -print ''; print ''; @@ -225,8 +234,13 @@ print ''; print ''; if ($nb) { if ($pricetowithdraw) { - print $langs->trans('BankToReceiveWithdraw').': '; - $form->select_comptes($conf->global->PRELEVEMENT_ID_BANKACCOUNT, 'id_bankaccount', 0, "courant=1"); + $title = $langs->trans('BankToReceiveWithdraw').': '; + if ($type == 'bank-transfer') { + $title = $langs->trans('BankToPayCreditTransfer').': '; + } + print $title; + print img_picto('', 'bank_account'); + print $form->select_comptes($conf->global->PRELEVEMENT_ID_BANKACCOUNT, 'id_bankaccount', 0, "courant=1", 0, '', 0, '', 1); print ' - '; print $langs->trans('ExecutionDate').' '; @@ -430,7 +444,7 @@ if ($resql) { } print ''; // Amount - print ''; // Date diff --git a/htdocs/compta/prelevement/orders_list.php b/htdocs/compta/prelevement/orders_list.php index 5c6f058bff1..3ca9ce32fbe 100644 --- a/htdocs/compta/prelevement/orders_list.php +++ b/htdocs/compta/prelevement/orders_list.php @@ -29,7 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.p require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; // Load translation files required by the page -$langs->loadLangs(array('banks', 'categories', 'widthdrawals')); +$langs->loadLangs(array('banks', 'categories', 'withdrawals')); $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'directdebitcredittransferlist'; // To manage different context of search diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 32edf9a1558..d5187c6a040 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -1003,7 +1003,7 @@ if ($action == 'create') { $soc->fetch($socid); } - if (GETPOST('origin') && GETPOST('originid')) { + if (GETPOST('origin') && GETPOST('originid', 'int')) { // Parse element/subelement (ex: project_task) $regs = array(); $element = $subelement = GETPOST('origin'); @@ -1013,7 +1013,7 @@ if ($action == 'create') { } if ($element == 'project') { - $projectid = GETPOST('originid'); + $projectid = GETPOST('originid', 'int'); } else { // For compatibility if ($element == 'order' || $element == 'commande') { @@ -1094,7 +1094,8 @@ if ($action == 'create') { print ''; } else { print ''; } @@ -1121,11 +1122,13 @@ if ($action == 'create') { // Commercial suivi print ''; // Commercial signature print ''; @@ -1686,7 +1689,7 @@ if ($action == 'create') { $colspan++; } - // Ligne dates prevues + // Line dates planed print ''; print ''; $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; diff --git a/htdocs/core/modules/product/modules_product.class.php b/htdocs/core/modules/product/modules_product.class.php index e0141348568..fef12717e3b 100644 --- a/htdocs/core/modules/product/modules_product.class.php +++ b/htdocs/core/modules/product/modules_product.class.php @@ -193,7 +193,8 @@ abstract class ModeleProductCode { global $conf; - $langs->load("admin"); + $langs->loadLangs(array("admin", "companies")); + $strikestart = ''; $strikeend = ''; if (!empty($conf->global->MAIN_COMPANY_CODE_ALWAYS_REQUIRED) && !empty($this->code_null)) { 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; } diff --git a/htdocs/core/modules/societe/modules_societe.class.php b/htdocs/core/modules/societe/modules_societe.class.php index 28d0120da72..09f6cb9c29d 100644 --- a/htdocs/core/modules/societe/modules_societe.class.php +++ b/htdocs/core/modules/societe/modules_societe.class.php @@ -198,7 +198,8 @@ abstract class ModeleThirdPartyCode { global $conf; - $langs->load("admin"); + $langs->loadLangs(array("admin", "companies")); + $strikestart = ''; $strikeend = ''; if (!empty($conf->global->MAIN_COMPANY_CODE_ALWAYS_REQUIRED) && !empty($this->code_null)) { diff --git a/htdocs/core/search_page.php b/htdocs/core/search_page.php index 8581776a2d8..2b82501208a 100644 --- a/htdocs/core/search_page.php +++ b/htdocs/core/search_page.php @@ -20,7 +20,7 @@ /** * \file htdocs/core/search_page.php - * \brief File to return a page with search boxes + * \brief File to return a page with the complete search form (all search input fields) */ //if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled cause need to load personalized language @@ -77,7 +77,7 @@ $hookmanager->initHooks(array('searchform')); // Define $searchform $searchform = ''; -if ($conf->use_javascript_ajax && 1 == 2) { // select2 is ko with jmobile +if ($conf->use_javascript_ajax && 1 == 2) { // select2 is not best with smartphone if (!is_object($form)) { $form = new Form($db); } diff --git a/htdocs/core/tpl/card_presend.tpl.php b/htdocs/core/tpl/card_presend.tpl.php index c741fb213c2..143d8d5536c 100644 --- a/htdocs/core/tpl/card_presend.tpl.php +++ b/htdocs/core/tpl/card_presend.tpl.php @@ -137,6 +137,13 @@ if ($action == 'presend') { $formmail->fromname = ''; $formmail->fromtype = 'special'; } + if ($object->element === 'order_supplier' && !empty($conf->global->ORDER_SUPPLIER_EMAIL_SENDER)) { + $formmail->frommail = $conf->global->ORDER_SUPPLIER_EMAIL_SENDER; + $formmail->fromname = ''; + $formmail->fromtype = 'special'; + } + + $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 diff --git a/htdocs/core/tpl/extrafields_edit.tpl.php b/htdocs/core/tpl/extrafields_edit.tpl.php index 5915fb8a633..6d6b6aa8836 100644 --- a/htdocs/core/tpl/extrafields_edit.tpl.php +++ b/htdocs/core/tpl/extrafields_edit.tpl.php @@ -43,7 +43,7 @@ $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, print $hookmanager->resPrint; if (empty($reshook)) { $params = array(); - $params['cols'] = $parameters['colspanvalue']; + $params['cols'] = isset($parameters['colspanvalue']) ? $parameters['colspanvalue'] : null; print $object->showOptionals($extrafields, 'edit', $params); } diff --git a/htdocs/core/tpl/massactions_pre.tpl.php b/htdocs/core/tpl/massactions_pre.tpl.php index c40f896e702..e2e56e1a060 100644 --- a/htdocs/core/tpl/massactions_pre.tpl.php +++ b/htdocs/core/tpl/massactions_pre.tpl.php @@ -205,7 +205,7 @@ if ($massaction == 'predisable') { // Allow Pre-Mass-Action hook (eg for confirmation dialog) $parameters = array( 'toselect' => $toselect, - 'uploaddir' => $uploaddir + 'uploaddir' => isset($uploaddir) ? $uploaddir : null ); $reshook = $hookmanager->executeHooks('doPreMassActions', $parameters, $object, $action); diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php index 8e23c258d88..d441d364f4b 100644 --- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php +++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php @@ -556,6 +556,21 @@ class InterfaceActionsAuto extends DolibarrTriggers $object->actionmsg .= $langs->trans("Reason") . ': '.$object->refuse_note; } + $object->sendtoid = 0; + } elseif ($action == 'ORDER_SUPPLIER_CANCEL') { + // Load translation files required by the page + $langs->loadLangs(array("agenda", "other", "orders", "main")); + + if (empty($object->actionmsg2)) { + $object->actionmsg2 = $langs->transnoentities("OrderCanceledInDolibarr", $object->ref); + } + $object->actionmsg = $langs->transnoentities("OrderCanceledInDolibarr", $object->ref); + + if (!empty($object->cancel_note)) { + $object->actionmsg .= '
'; + $object->actionmsg .= $langs->trans("Reason") . ': '.$object->cancel_note; + } + $object->sendtoid = 0; } elseif ($action == 'ORDER_SUPPLIER_SUBMIT') { // Load translation files required by the page @@ -566,6 +581,11 @@ class InterfaceActionsAuto extends DolibarrTriggers } $object->actionmsg = $langs->transnoentities("SupplierOrderSubmitedInDolibarr", ($object->newref ? $object->newref : $object->ref)); + if (!empty($object->context['comments'])) { + $object->actionmsg .= '
'; + $object->actionmsg .= $langs->trans("Comment") . ': '.$object->context['comments']; + } + $object->sendtoid = 0; } elseif ($action == 'ORDER_SUPPLIER_RECEIVE') { // Load translation files required by the page @@ -936,7 +956,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/core/triggers/interface_50_modNotification_Notification.class.php b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php index 7d315f142a7..e2b359809dd 100644 --- a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php +++ b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php @@ -30,7 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php'; */ class InterfaceNotification extends DolibarrTriggers { - // @todo Defined also into notify.class.php) + // @todo Defined also into notify.class.php public $listofmanagedevents = array( 'BILL_VALIDATE', 'BILL_PAYED', diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 0b45db6a808..16df7774470 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -324,6 +324,9 @@ class EmailCollector extends CommonObject // Clear fields $object->ref = "copy_of_".$object->ref; $object->title = $langs->trans("CopyOf")." ".$object->title; + if (empty($object->host)) { + $object->host = 'imap.example.com'; + } // ... // Clear extrafields that are unique if (is_array($object->array_options) && count($object->array_options) > 0) { @@ -849,11 +852,11 @@ class EmailCollector extends CommonObject $regexstring = ''; //$transformationstring=''; $regforregex = array(); - if (preg_match('/^EXTRACT:([a-zA-Z0-9]+):(.*):([^:])$/', $valueforproperty, $regforregex)) { + if (preg_match('/^EXTRACT:([a-zA-Z0-9_]+):(.*):([^:])$/', $valueforproperty, $regforregex)) { $sourcefield = $regforregex[1]; $regexstring = $regforregex[2]; //$transofrmationstring=$regforregex[3]; - } elseif (preg_match('/^EXTRACT:([a-zA-Z0-9]+):(.*)$/', $valueforproperty, $regforregex)) { + } elseif (preg_match('/^EXTRACT:([a-zA-Z0-9_]+):(.*)$/', $valueforproperty, $regforregex)) { $sourcefield = $regforregex[1]; $regexstring = $regforregex[2]; } @@ -1199,15 +1202,20 @@ class EmailCollector extends CommonObject $iforemailloop = 0; foreach ($arrayofemail as $imapemail) { if ($nbemailprocessed > 1000) { - break; // Do not process more than 1000 email per launch (this is a different protection than maxnbcollectedpercollect + break; // Do not process more than 1000 email per launch (this is a different protection than maxnbcollectedpercollect) } $iforemailloop++; + // GET header and overview datas + $header = imap_fetchheader($connection, $imapemail, 0); + $overview = imap_fetch_overview($connection, $imapemail, 0); + + /* print $header; var_dump($overview); */ + + // Process $header of email $header = preg_replace('/\r\n\s+/m', ' ', $header); // When a header line is on several lines, merge lines - /*print $header; - print $header;*/ $matches = array(); preg_match_all('/([^: ]+): (.+?(?:\r\n\s(?:.+?))*)\r\n/m', $header, $matches); @@ -1297,9 +1305,6 @@ class EmailCollector extends CommonObject $this->db->begin(); - // GET Email meta datas - $overview = imap_fetch_overview($connection, $imapemail, 0); - dol_syslog("msgid=".$overview[0]->message_id." date=".dol_print_date($overview[0]->udate, 'dayrfc', 'gmt')." from=".$overview[0]->from." to=".$overview[0]->to." subject=".$overview[0]->subject); $overview[0]->subject = $this->decodeSMTPSubject($overview[0]->subject); @@ -1309,10 +1314,14 @@ class EmailCollector extends CommonObject // Removed emojis $overview[0]->subject = preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $overview[0]->subject); - // Parse IMAP email structure + // GET IMAP email structure/content + global $htmlmsg, $plainmsg, $charset, $attachments; + $this->getmsg($connection, $imapemail); + //print $plainmsg; var_dump($plainmsg); exit; + //$htmlmsg,$plainmsg,$charset,$attachments $messagetext = $plainmsg ? $plainmsg : dol_string_nohtmltag($htmlmsg, 0); // Removed emojis @@ -1640,13 +1649,15 @@ class EmailCollector extends CommonObject if ($operation['type'] == 'loadthirdparty' || $operation['type'] == 'loadandcreatethirdparty') { if (empty($operation['actionparam'])) { $errorforactions++; - $this->error = "Action loadthirdparty or loadandcreatethirdparty has empty parameter. Must be a rule like 'SET:xxx' or 'EXTRACT:(body|subject):regex' to define how to set or extract data"; + $this->error = "Action loadthirdparty or loadandcreatethirdparty has empty parameter. Must be a rule like 'name=HEADER:^From:(.*);' or 'name=SET:xxx' or 'name=EXTRACT:(body|subject):regex where 'name' can be replaced with 'id' or 'email' to define how to set or extract data. More properties can also be set, for example client=SET:2;"; $this->errors[] = $this->error; } else { $actionparam = $operation['actionparam']; + $idtouseforthirdparty = ''; $nametouseforthirdparty = ''; + $emailtouseforthirdparty = ''; - // $this->actionparam = 'SET:aaa' or 'EXTRACT:BODY:....' + // $actionparam = 'param=SET:aaa' or 'param=EXTRACT:BODY:....' $arrayvaluetouse = dolExplodeIntoArray($actionparam, ';', '='); foreach ($arrayvaluetouse as $propertytooverwrite => $valueforproperty) { $sourcestring = ''; @@ -1654,7 +1665,7 @@ class EmailCollector extends CommonObject $regexstring = ''; $regforregex = array(); - if (preg_match('/^EXTRACT:([a-zA-Z0-9]+):(.*)$/', $valueforproperty, $regforregex)) { + if (preg_match('/^EXTRACT:([a-zA-Z0-9_]+):(.*)$/', $valueforproperty, $regforregex)) { $sourcefield = $regforregex[1]; $regexstring = $regforregex[2]; } @@ -1674,10 +1685,18 @@ class EmailCollector extends CommonObject if (preg_match('/'.$regexstring.'/ms', $sourcestring, $regforval)) { //var_dump($regforval[count($regforval)-1]);exit; // Overwrite param $tmpproperty - $nametouseforthirdparty = isset($regforval[count($regforval) - 1]) ? trim($regforval[count($regforval) - 1]) : null; + if ($propertytooverwrite == 'id') { + $idtouseforthirdparty = isset($regforval[count($regforval) - 1]) ? trim($regforval[count($regforval) - 1]) : null; + } elseif ($propertytooverwrite == 'email') { + $emailtouseforthirdparty = isset($regforval[count($regforval) - 1]) ? trim($regforval[count($regforval) - 1]) : null; + } else { + $nametouseforthirdparty = isset($regforval[count($regforval) - 1]) ? trim($regforval[count($regforval) - 1]) : null; + } } else { // Regex not found + $idtouseforthirdparty = null; $nametouseforthirdparty = null; + $emailtouseforthirdparty = null; } //var_dump($object->$tmpproperty);exit; } else { @@ -1689,7 +1708,13 @@ class EmailCollector extends CommonObject } elseif (preg_match('/^(SET|SETIFEMPTY):(.*)$/', $valueforproperty, $reg)) { //if (preg_match('/^options_/', $tmpproperty)) $object->array_options[preg_replace('/^options_/', '', $tmpproperty)] = $reg[1]; //else $object->$tmpproperty = $reg[1]; - $nametouseforthirdparty = $reg[2]; + if ($propertytooverwrite == 'id') { + $idtouseforthirdparty = $reg[2]; + } elseif ($propertytooverwrite == 'email') { + $emailtouseforthirdparty = $reg[2]; + } else { + $nametouseforthirdparty = $reg[2]; + } } else { $errorforactions++; $this->error = 'Bad syntax for description of action parameters: '.$actionparam; @@ -1698,8 +1723,8 @@ class EmailCollector extends CommonObject } } - if (!$errorforactions && $nametouseforthirdparty) { - $result = $thirdpartystatic->fetch(0, $nametouseforthirdparty); + if (!$errorforactions && ($idtouseforthirdparty || $emailtouseforthirdparty || $nametouseforthirdparty)) { + $result = $thirdpartystatic->fetch($idtouseforthirdparty, $nametouseforthirdparty, '', '', '', '', '', '', '', '', $emailtouseforthirdparty); if ($result < 0) { $errorforactions++; $this->error = 'Error when getting thirdparty with name '.$nametouseforthirdparty.' (may be 2 record exists with same name ?)'; @@ -1707,20 +1732,20 @@ class EmailCollector extends CommonObject break; } elseif ($result == 0) { if ($operation['type'] == 'loadthirdparty') { - dol_syslog("Third party with name ".$nametouseforthirdparty." was not found"); + dol_syslog("Third party with id=".$idtouseforthirdparty." email=".$emailtouseforthirdparty." name=".$nametouseforthirdparty." was not found"); $errorforactions++; $this->error = 'ErrorFailedToLoadThirdParty'; $this->errors[] = 'ErrorFailedToLoadThirdParty'; } elseif ($operation['type'] == 'loadandcreatethirdparty') { - dol_syslog("Third party with name ".$nametouseforthirdparty." was not found. We try to create it."); + dol_syslog("Third party with id=".$idtouseforthirdparty." email=".$emailtouseforthirdparty." name=".$nametouseforthirdparty." was not found. We try to create it."); // Create thirdparty $thirdpartystatic->name = $nametouseforthirdparty; if ($fromtext != $nametouseforthirdparty) { $thirdpartystatic->name_alias = $fromtext; } - $thirdpartystatic->email = $from; + $thirdpartystatic->email = ($emailtouseforthirdparty ? $emailtouseforthirdparty : $from); // Overwrite values with values extracted from source email $errorforthisaction = $this->overwritePropertiesOfObject($thirdpartystatic, $operation['actionparam'], $messagetext, $subject, $header); 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 '"; print '
'.$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.'
"; print $ligne->LibStatut($obj->statut, 2); print " "; - print ''; + print ''; print sprintf("%06s", $obj->rowid); print '
'.$langs->trans("AmountTotal").''; +print ''; print price($pricetowithdraw); print '
'; + print ''; print price($obj->amount, 0, $langs, 0, 0, -1, $conf->currency); print ''; - print $form->select_company('', 'socid', '', 'SelectThirdParty', 1, 0, null, 0, 'minwidth300'); + print img_picto('', 'company', 'class="pictofixedwidth"'); + print $form->select_company('', 'socid', '', 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 widthcentpercentminusxx maxwidth500'); print ' '; print '
'.$langs->trans("TypeContact_contrat_internal_SALESREPFOLL").''; + print img_picto('', 'user', 'class="pictofixedwidth"'); print $form->select_dolusers(GETPOST("commercial_suivi_id") ?GETPOST("commercial_suivi_id") : $user->id, 'commercial_suivi_id', 1, ''); print '
'.$langs->trans("TypeContact_contrat_internal_SALESREPSIGN").''; + print img_picto('', 'user', 'class="pictofixedwidth"'); print $form->select_dolusers(GETPOST("commercial_signature_id") ?GETPOST("commercial_signature_id") : $user->id, 'commercial_signature_id', 1, ''); print '
'; print $langs->trans("DateStartPlanned").' '; @@ -1786,7 +1789,7 @@ if ($action == 'create') { print ''; print ''; - print ''; + print ''; print ''; - if ( ! empty($conf->global->MAIN_VIEW_LINE_NUMBER) ) { + if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER) && $action == 'view') { $out .= ''; } $out .= ''; } + + // User assigned + print ''; + print ''; } if (!empty($conf->projet->enabled) && !$this->ispublic) { diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index 6b32799bc89..2e0a71460ba 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -65,7 +65,7 @@ class Notify // Les codes actions sont definis dans la table llx_notify_def // codes actions supported are - // @todo defined also into interface_50_modNotificiation_Notificiation.class.php + // @todo defined also into interface_50_modNotification_Notification.class.php public $arrayofnotifsupported = array( 'BILL_VALIDATE', 'BILL_PAYED', @@ -80,8 +80,8 @@ class Notify 'SHIPPING_VALIDATE', 'EXPENSE_REPORT_VALIDATE', 'EXPENSE_REPORT_APPROVE', - 'HOLIDAY_VALIDATE', - 'HOLIDAY_APPROVE', + 'HOLIDAY_VALIDATE', + 'HOLIDAY_APPROVE', 'ACTION_CREATE' ); @@ -546,7 +546,7 @@ class Notify $object_type = 'holiday'; $labeltouse = $conf->global->HOLIDAY_APPROVE_TEMPLATE; $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayApproved", $link); - break; + break; case 'ACTION_CREATE': $link = ''.$newref.''; $dir_output = $conf->agenda->dir_output; @@ -567,10 +567,10 @@ class Notify $subject = make_substitutions($arraydefaultmessage->topic, $substitutionarray, $outputlangs); $message = make_substitutions($arraydefaultmessage->content, $substitutionarray, $outputlangs); } else { - $message = $outputlangs->transnoentities("YouReceiveMailBecauseOfNotification", $application, $mysoc->name)."\n"; - $message .= $outputlangs->transnoentities("YouReceiveMailBecauseOfNotification2", $application, $mysoc->name)."\n"; - $message .= "\n"; - $message .= $mesg; + $message = $outputlangs->transnoentities("YouReceiveMailBecauseOfNotification", $application, $mysoc->name)."\n"; + $message .= $outputlangs->transnoentities("YouReceiveMailBecauseOfNotification2", $application, $mysoc->name)."\n"; + $message .= "\n"; + $message .= $mesg; } $ref = dol_sanitizeFileName($newref); @@ -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; @@ -782,7 +782,7 @@ class Notify $dir_output = $conf->holiday->dir_output; $object_type = 'holiday'; $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayApproved", $link); - break; + break; case 'ACTION_CREATE': $link = ''.$newref.''; $dir_output = $conf->agenda->dir_output; diff --git a/htdocs/core/db/Database.interface.php b/htdocs/core/db/Database.interface.php index 898421978db..9996d09f036 100644 --- a/htdocs/core/db/Database.interface.php +++ b/htdocs/core/db/Database.interface.php @@ -122,7 +122,7 @@ interface Database * List tables into a database * * @param string $database Name of database - * @param string $table Nmae of table filter ('xxx%') + * @param string $table Name of table filter ('xxx%') * @return array List of tables in an array */ public function DDLListTables($database, $table = ''); @@ -189,7 +189,7 @@ interface Database /** * Get last ID after an insert INSERT * - * @param string $tab Table name concerned by insert. Ne sert pas sous MySql mais requis pour compatibilite avec Postgresql + * @param string $tab Table name concerned by insert. Not used under MySql but required for compatibility with Postgresql * @param string $fieldid Field name * @return int Id of row */ diff --git a/htdocs/core/js/lib_notification.js.php b/htdocs/core/js/lib_notification.js.php index 616463b944d..ee41555119a 100644 --- a/htdocs/core/js/lib_notification.js.php +++ b/htdocs/core/js/lib_notification.js.php @@ -131,8 +131,8 @@ function check_events() { if (value.type == 'agenda') { - url = '' + value.id_agenda; - title = 'trans('EventReminder')) ?>'; + url = '' + value.id_agenda; + title = 'transnoentities('EventReminder')) ?>'; } var extra = { icon: '', 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(); } } diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php index ae96f59d407..9796c49cf59 100644 --- a/htdocs/core/lib/agenda.lib.php +++ b/htdocs/core/lib/agenda.lib.php @@ -61,13 +61,13 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh // Filters //print '
'; print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; if ($massaction != 'predelete' && $massaction != 'preaffecttag') { // When $massaction == 'predelete', action may be already output to 'delete' by the mass action system. print ''; } - print ''; + print ''; if ($canedit) { print '
'; diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index cb710c19875..7d261f2d5ab 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -1948,7 +1948,9 @@ function show_subsidiaries($conf, $langs, $db, $object) $socstatic = new Societe($db); print load_fiche_titre($langs->trans("Subsidiaries"), '', ''); - print "\n".'
'.$langs->trans("ServiceStatus").': '.$object->lines[$cursorline - 1]->getLibStatut(4).''.$langs->trans("ServiceStatus").': '.$object->lines[$cursorline - 1]->getLibStatut(4).''; if ($user->socid == 0) { if ($object->statut > 0 && $action != 'activateline' && $action != 'unactivateline') { diff --git a/htdocs/core/actions_dellink.inc.php b/htdocs/core/actions_dellink.inc.php index a7ac035506f..fbecacce515 100644 --- a/htdocs/core/actions_dellink.inc.php +++ b/htdocs/core/actions_dellink.inc.php @@ -27,17 +27,42 @@ // $permissiondellink must be defined $dellinkid = GETPOST('dellinkid', 'int'); +$addlink = GETPOST('addlink', 'alpha'); $addlinkid = GETPOST('idtolinkto', 'int'); +$addlinkref = GETPOST('reftolinkto', 'alpha'); +$cancellink = GETPOST('cancel', 'alpha'); // Link invoice to order -if ($action == 'addlink' && !empty($permissiondellink) && !GETPOST('cancel', 'alpha') && $id > 0 && $addlinkid > 0) { +if ($action == 'addlink' && !empty($permissiondellink) && !$cancellink && $id > 0 && $addlinkid > 0) { $object->fetch($id); $object->fetch_thirdparty(); - $result = $object->add_object_linked(GETPOST('addlink', 'alpha'), $addlinkid); + $result = $object->add_object_linked($addlink, $addlinkid); +} + +// Link by reference +if ($action == 'addlinkbyref' && ! empty($permissiondellink) && !$cancellink && $id > 0 && !empty($addlinkref) && !empty($conf->global->MAIN_LINK_BY_REF_IN_LINKTO)) { + $element_prop = getElementProperties($addlink); + if (is_array($element_prop)) { + dol_include_once('/' . $element_prop['classpath'] . '/' . $element_prop['classfile'] . '.class.php'); + + $objecttmp = new $element_prop['classname']($db); + $ret = $objecttmp->fetch(0, $addlinkref); + if ($ret > 0) { + $object->fetch($id); + $object->fetch_thirdparty(); + $result = $object->add_object_linked($addlink, $objecttmp->id); + if (isset($_POST['reftolinkto'])) unset($_POST['reftolinkto']); + } elseif ($ret < 0) { + setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); + } else { + $langs->load('errors'); + setEventMessage($langs->trans('ErrorRecordNotFound'), 'errors'); + } + } } // Delete link -if ($action == 'dellink' && !empty($permissiondellink) && !GETPOST('cancel', 'alpha') && $dellinkid > 0) { +if ($action == 'dellink' && !empty($permissiondellink) && !$cancellink && $dellinkid > 0) { $result = $object->deleteObjectLinked(0, '', 0, '', $dellinkid); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index e5d4de26278..8d70f7c3042 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -1547,7 +1547,7 @@ if (!$error && ($massaction == 'disable' || ($action == 'disable' && $confirm == $parameters['toselect'] = $toselect; $parameters['uploaddir'] = $uploaddir; $parameters['massaction'] = $massaction; -$parameters['diroutputmassaction'] = $diroutputmassaction; +$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) { diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index 83a823edeb2..e5c75a2e7c3 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -182,10 +182,15 @@ 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 into free hidden text field + $tmparray[] = trim($_POST['tomail']); + } + if (count($receiver) > 0) { // Recipient was provided from combo list foreach ($receiver as $key => $val) { diff --git a/htdocs/core/ajax/selectsearchbox.php b/htdocs/core/ajax/selectsearchbox.php index 509d10e7858..1814b476d06 100644 --- a/htdocs/core/ajax/selectsearchbox.php +++ b/htdocs/core/ajax/selectsearchbox.php @@ -110,13 +110,13 @@ if (!empty($conf->facture->enabled) && empty($conf->global->MAIN_SEARCHFORM_CUST } if (!empty($conf->supplier_proposal->enabled) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_PROPAL_DISABLED) && $user->rights->supplier_proposal->lire) { - $arrayresult['searchintosupplierpropal'] = array('position'=>100, 'img'=>'object_propal', 'label'=>$langs->trans("SearchIntoSupplierProposals", $search_boxvalue), 'text'=>img_picto('', 'object_supplier_proposal').' '.$langs->trans("SearchIntoSupplierProposals", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/supplier_proposal/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); + $arrayresult['searchintosupplierpropal'] = array('position'=>100, 'img'=>'object_supplier_proposal', 'label'=>$langs->trans("SearchIntoSupplierProposals", $search_boxvalue), 'text'=>img_picto('', 'object_supplier_proposal').' '.$langs->trans("SearchIntoSupplierProposals", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/supplier_proposal/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->commande->lire) || (!empty($conf->supplier_order->enabled) && $user->rights->supplier_order->lire)) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_ORDER_DISABLED)) { - $arrayresult['searchintosupplierorder'] = array('position'=>110, 'img'=>'object_order', 'label'=>$langs->trans("SearchIntoSupplierOrders", $search_boxvalue), 'text'=>img_picto('', 'object_supplier_order').' '.$langs->trans("SearchIntoSupplierOrders", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/fourn/commande/list.php'.($search_boxvalue ? '?search_all='.urlencode($search_boxvalue) : '')); + $arrayresult['searchintosupplierorder'] = array('position'=>110, 'img'=>'object_supplier_order', 'label'=>$langs->trans("SearchIntoSupplierOrders", $search_boxvalue), 'text'=>img_picto('', 'object_supplier_order').' '.$langs->trans("SearchIntoSupplierOrders", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/fourn/commande/list.php'.($search_boxvalue ? '?search_all='.urlencode($search_boxvalue) : '')); } if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire) || (!empty($conf->supplier_invoice->enabled) && $user->rights->supplier_invoice->lire)) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_INVOICE_DISABLED)) { - $arrayresult['searchintosupplierinvoice'] = array('position'=>120, 'img'=>'object_bill', 'label'=>$langs->trans("SearchIntoSupplierInvoices", $search_boxvalue), 'text'=>img_picto('', 'object_supplier_invoice').' '.$langs->trans("SearchIntoSupplierInvoices", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/fourn/facture/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); + $arrayresult['searchintosupplierinvoice'] = array('position'=>120, 'img'=>'object_supplier_invoice', 'label'=>$langs->trans("SearchIntoSupplierInvoices", $search_boxvalue), 'text'=>img_picto('', 'object_supplier_invoice').' '.$langs->trans("SearchIntoSupplierInvoices", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/fourn/facture/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } // Customer payments 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; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index b3ae722a5d3..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 @@ -6521,11 +6525,11 @@ abstract class CommonObject } elseif (in_array($type, array('int', 'integer'))) { $tmp = explode(',', $size); $newsize = $tmp[0]; - $out = ''; + $out = ' 0 ? ' maxlength="'.$newsize.'"' : '').' value="'.dol_escape_htmltag($value).'"'.($moreparam ? $moreparam : '').($autofocusoncreate ? ' autofocus' : '').'>'; } elseif (in_array($type, array('real'))) { $out = ''; } elseif (preg_match('/varchar/', $type)) { - $out = ''; + $out = ' 0 ? ' maxlength="'.$size.'"' : '').' value="'.dol_escape_htmltag($value).'"'.($moreparam ? $moreparam : '').($autofocusoncreate ? ' autofocus' : '').'>'; } elseif (in_array($type, array('mail', 'phone', 'url'))) { $out = ''; } elseif (preg_match('/^text/', $type)) { @@ -7492,7 +7496,7 @@ abstract class CommonObject if ($display_type == 'card') { $out .= '
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'); diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php index 5e24ee03fa4..45643e26e4c 100644 --- a/htdocs/core/class/hookmanager.class.php +++ b/htdocs/core/class/hookmanager.class.php @@ -193,6 +193,7 @@ class HookManager 'getFormatedSupplierRef', 'getIdProfUrl', 'getInputIdProf', + 'menuLeftMenuItems', 'moveUploadedFile', 'moreHtmlStatus', 'pdf_build_address', diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 178404da973..9bcbf08f71a 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1267,16 +1267,17 @@ class Form // mode 1 $urloption = 'htmlname='.urlencode($htmlname).'&outjson=1&filter='.urlencode($filter).(empty($excludeids) ? '' : '&excludeids='.join(',', $excludeids)).($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").'"'; + $placeholder = $langs->trans("RefOrLabel"); if ($hidelabel == 2) { $out .= img_picto($langs->trans("Search"), 'search'); } } - $out .= 'global->THIRDPARTY_SEARCH_AUTOFOCUS) ? 'autofocus' : '').' />'; + $out .= 'global->THIRDPARTY_SEARCH_AUTOFOCUS) ? 'autofocus' : '').' />'; if ($hidelabel == 3) { $out .= img_picto($langs->trans("Search"), 'search'); } @@ -1332,7 +1333,7 @@ class Form } // We search companies - $sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.client, s.fournisseur, s.code_client, s.code_fournisseur"; + $sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.tva_intra, s.client, s.fournisseur, s.code_client, s.code_fournisseur"; if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST)) { $sql .= ", s.address, s.zip, s.town"; $sql .= ", dictp.code as country_code"; @@ -1384,6 +1385,7 @@ class Form $sql .= " OR s.barcode LIKE '".$this->db->escape($prefix.$filterkey)."%'"; } $sql .= " OR s.code_client LIKE '".$this->db->escape($prefix.$filterkey)."%' OR s.code_fournisseur LIKE '".$this->db->escape($prefix.$filterkey)."%'"; + $sql .= " OR s.name_alias LIKE '".$this->db->escape($prefix.$filterkey)."%' OR s.tva_intra LIKE '".$this->db->escape($prefix.$filterkey)."%'"; $sql .= ")"; } $sql .= $this->db->order("nom", "ASC"); @@ -1951,15 +1953,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); } @@ -6867,11 +6872,8 @@ 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 .= ''; - if ($placeholder) { - $placeholder = ' placeholder="'.$placeholder.'"'; - } - $out .= ''; + $out .= ''; + $out .= ''; } else { // Immediate load of table record. Note: filter is inside $objecttmp->filter $out .= $this->selectForFormsList($objecttmp, $htmlname, $preselectedvalue, $showempty, $searchkey, $placeholder, $morecss, $moreparams, $forcecombo, 0, $disabled); @@ -6974,13 +6976,15 @@ class Form // Search data $sql = "SELECT t.rowid, ".$fieldstoshow." FROM ".MAIN_DB_PREFIX.$objecttmp->table_element." as t"; - if (isset($objecttmp->ismultientitymanaged) && !is_numeric($objecttmp->ismultientitymanaged)) { - $tmparray = explode('@', $objecttmp->ismultientitymanaged); - $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.$tmparray[1].' as parenttable ON parenttable.rowid = t.'.$tmparray[0]; - } - if ($objecttmp->ismultientitymanaged == 'fk_soc@societe') { - if (!$user->rights->societe->client->voir && !$user->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + if (isset($objecttmp->ismultientitymanaged)) { + if (!is_numeric($objecttmp->ismultientitymanaged)) { + $tmparray = explode('@', $objecttmp->ismultientitymanaged); + $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.$tmparray[1].' as parenttable ON parenttable.rowid = t.'.$tmparray[0]; + } + if ($objecttmp->ismultientitymanaged == 'fk_soc@societe') { + if (!$user->rights->societe->client->voir && !$user->socid) { + $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + } } } @@ -6991,27 +6995,29 @@ class Form $sql .= $hookmanager->resPrint; } else { $sql .= " WHERE 1=1"; - if (isset($objecttmp->ismultientitymanaged) && $objecttmp->ismultientitymanaged == 1) { - $sql .= " AND t.entity IN (".getEntity($objecttmp->table_element).")"; - } - if (isset($objecttmp->ismultientitymanaged) && !is_numeric($objecttmp->ismultientitymanaged)) { - $sql .= ' AND parenttable.entity = t.'.$tmparray[0]; - } - if ($objecttmp->ismultientitymanaged == 1 && !empty($user->socid)) { - if ($objecttmp->element == 'societe') { - $sql .= " AND t.rowid = ".$user->socid; - } else { - $sql .= " AND t.fk_soc = ".$user->socid; + if (isset($objecttmp->ismultientitymanaged)) { + if ($objecttmp->ismultientitymanaged == 1) { + $sql .= " AND t.entity IN (".getEntity($objecttmp->table_element).")"; + } + if (!is_numeric($objecttmp->ismultientitymanaged)) { + $sql .= ' AND parenttable.entity = t.'.$tmparray[0]; + } + if ($objecttmp->ismultientitymanaged == 1 && !empty($user->socid)) { + if ($objecttmp->element == 'societe') { + $sql .= " AND t.rowid = ".$user->socid; + } else { + $sql .= " AND t.fk_soc = ".$user->socid; + } + } + if ($objecttmp->ismultientitymanaged == 'fk_soc@societe') { + if (!$user->rights->societe->client->voir && !$user->socid) { + $sql .= " AND t.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; + } } } if ($searchkey != '') { $sql .= natural_search(explode(',', $fieldstoshow), $searchkey); } - if ($objecttmp->ismultientitymanaged == 'fk_soc@societe') { - if (!$user->rights->societe->client->voir && !$user->socid) { - $sql .= " AND t.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; - } - } if ($objecttmp->filter) { // Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" /*if (! DolibarrApi::_checkFilters($objecttmp->filter)) { @@ -7848,6 +7854,10 @@ class Form $tplpath = 'expensereport'; } elseif ($objecttype == 'subscription') { $tplpath = 'adherents'; + } elseif ($objecttype == 'conferenceorbooth') { + $tplpath = 'eventorganization'; + } elseif ($objecttype == 'conferenceorboothattendee') { + $tplpath = 'eventorganization'; } global $linkedObjectBlock; @@ -7970,6 +7980,21 @@ class Form if (!empty($possiblelink['perms']) && (empty($restrictlinksto) || in_array($key, $restrictlinksto)) && (empty($excludelinksto) || !in_array($key, $excludelinksto))) { print '
use_javascript_ajax) ? '' : ' style="display:none"').'>'; + + if (!empty($conf->global->MAIN_LINK_BY_REF_IN_LINKTO)) { + print '
'; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print '
' . $langs->trans("Ref") . '  
'; + print '
'; + } + $sql = $possiblelink['sql']; $resqllist = $this->db->query($sql); @@ -8027,7 +8052,7 @@ class Form print '
'; //$linktoelem.=($linktoelem?'   ':''); - if ($num > 0) { + if ($num > 0 || !empty($conf->global->MAIN_LINK_BY_REF_IN_LINKTO)) { $linktoelemlist .= '
  • '.$langs->trans($possiblelink['label']).' ('.$num.')
  • '; // } else $linktoelem.=$langs->trans($possiblelink['label']); } else { diff --git a/htdocs/core/class/html.formactions.class.php b/htdocs/core/class/html.formactions.class.php index 992efb79bbf..09c94485d11 100644 --- a/htdocs/core/class/html.formactions.class.php +++ b/htdocs/core/class/html.formactions.class.php @@ -97,7 +97,7 @@ class FormActions function select_status() { var defaultvalue = $('#select' + htmlname).val(); var percentage = $('input[name=percentage]'); - var selected = '".(isset($selected) ? $selected : '')."'; + var selected = '".(isset($selected) ? dol_escape_js($selected) : '')."'; var value = (selected>0?selected:(defaultvalue>=0?defaultvalue:'')); percentage.val(value); diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 110d80b45d1..2b8a2d15aff 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -1182,7 +1182,7 @@ class FormFile ); $reshook = $hookmanager->executeHooks('showFilesList', $parameters, $object); - if (isset($reshook) && $reshook != '') { // null or '' for bypass + if (!empty($reshook)) { // null or '' for bypass return $reshook; } else { if (!is_object($form)) { 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/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 991e3cb37cc..5f00ed6877b 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -63,7 +63,7 @@ class FormOther * @param string $jstoexecuteonadd Name of javascript function to call * @return string HTML component */ - public function getHTMLScannerForm($jstoexecuteonadd = 'barcodscannerjs') + public function getHTMLScannerForm($jstoexecuteonadd = 'barcodescannerjs') { global $langs; @@ -73,9 +73,9 @@ class FormOther $out .= '
    '; $out .= '
    Barcode scanner tool...

    '; - $out .= ' Autodetect if we scan a product barcode or a lot/serial barcode
    '; - $out .= ' Scan a product barcode
    '; - $out .= ' Scan a product lot or serial number
    '; + $out .= ' Autodetect if we scan a product barcode or a lot/serial barcode
    '; + $out .= ' Scan a product barcode
    '; + $out .= ' Scan a product lot or serial number
    '; $out .= $langs->trans("QtyToAddAfterBarcodeScan").'
    '; $out .= ''; @@ -88,13 +88,16 @@ class FormOther */ $out .= '
    '; $out .= '
    '; - $out .= ''; + $out .= ''; $out .= ''; $out .= '
    '; - $out .= ''.$langs->trans("FeatureNotYetAvailable").''; - - // TODO Add call of javascript $jstoexecuteonadd so each scan will add qty into the inventory page + an ajax save. + $out .= ''; $out .= '
    '; $out .= '
    '; diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php index 53ba83015b3..259e5a3a19a 100644 --- a/htdocs/core/class/html.formticket.class.php +++ b/htdocs/core/class/html.formticket.class.php @@ -436,6 +436,14 @@ class FormTicket print 'withnotifytiersatcreate ? ' checked="checked"' : '').'>'; print '
    '; + print $langs->trans("AssignedTo"); + print ''; + print $form->select_dolusers(GETPOST('fk_user_assign', 'int'), 'fk_user_assign', 1); + print '
    '."\n"; + + print "\n".'
    '."\n"; + print '
    '."\n"; print ''; print ''; @@ -1976,17 +1978,17 @@ function show_subsidiaries($conf, $langs, $db, $object) print ''; - print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; print ''; @@ -1994,6 +1996,7 @@ function show_subsidiaries($conf, $langs, $db, $object) $i++; } print "\n
    '.$langs->trans("Company").''.$langs->trans("Address").''.$langs->trans("Zip").'
    '; + print ''; print $socstatic->getNomUrl(1); print ''.$obj->address.''.$obj->zip.''.$obj->town.''.$obj->code_client.''.dol_escape_htmltag($obj->address).''.$obj->zip.''.$obj->town.''.$obj->code_client.''; - print ''; + print ''; print img_edit(); print '
    \n"; + print ''."\n"; } print "
    \n"; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 26da9ee3d21..62f4006c1de 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2831,7 +2831,7 @@ function dol_print_socialnetworks($value, $cid, $socid, $type, $dictsocialnetwor * @param int $socid Id of third party if known * @param string $addlink ''=no link to create action, 'AC_TEL'=add link to clicktodial (if module enabled) and add link to create event (if conf->global->AGENDA_ADDACTIONFORPHONE set) * @param string $separ Separation between numbers for a better visibility example : xx.xx.xx.xx.xx - * @param string $withpicto Show picto + * @param string $withpicto Show picto ('fax', 'phone', 'mobile') * @param string $titlealt Text to show on alt * @param int $adddivfloat Add div float around phone. * @return string Formated phone number @@ -6828,6 +6828,8 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, $substitutionarray = array_merge($substitutionarray, array( '__MYCOMPANY_NAME__' => $mysoc->name, '__MYCOMPANY_EMAIL__' => $mysoc->email, + '__MYCOMPANY_PHONE__' => $mysoc->phone, + '__MYCOMPANY_FAX__' => $mysoc->fax, '__MYCOMPANY_PROFID1__' => $mysoc->idprof1, '__MYCOMPANY_PROFID2__' => $mysoc->idprof2, '__MYCOMPANY_PROFID3__' => $mysoc->idprof3, @@ -10202,7 +10204,7 @@ function newToken() */ function currentToken() { - return $_SESSION['token']; + return isset($_SESSION['token']) ? $_SESSION['token'] : ''; } /** diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index 6f5d2ccb891..0035688c66f 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -2700,7 +2700,7 @@ function convertBackOfficeMediasLinksToPublicLinks($notetoshow) * Function to format a value into a defined format for French administration (no thousand separator & decimal separator force to ',' with two decimals) * Function used into accountancy FEC export * - * @param float $amount Amount to format + * @param float $amount Amount to format * @return string Chain with formatted upright * @see price2num() Format a numeric into a price for FEC files */ 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') { diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index c192d5e6ac6..89f4c37f459 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -690,7 +690,8 @@ function print_end_menu_array() */ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabMenu, &$menu, $noout = 0, $forcemainmenu = '', $forceleftmenu = '', $moredata = null, $type_user = 0) { - global $user, $conf, $langs, $dolibarr_main_db_name, $mysoc; + + global $user, $conf, $langs, $dolibarr_main_db_name, $mysoc, $hookmanager; //var_dump($tabMenu); @@ -1344,15 +1345,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); @@ -1732,11 +1733,11 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM $titleboth = $langs->trans("LeadsOrProjects"); $titlenew = $langs->trans("NewLeadOrProject"); // Leads and opportunities by default - if ($conf->global->PROJECT_USE_OPPORTUNITIES == 0) { + if (isset($conf->global->PROJECT_USE_OPPORTUNITIES) && $conf->global->PROJECT_USE_OPPORTUNITIES == 0) { $titleboth = $langs->trans("Projects"); $titlenew = $langs->trans("NewProject"); } - if ($conf->global->PROJECT_USE_OPPORTUNITIES == 2) { // 2 = leads only + if (isset($conf->global->PROJECT_USE_OPPORTUNITIES) && $conf->global->PROJECT_USE_OPPORTUNITIES == 2) { // 2 = leads only $titleboth = $langs->trans("Leads"); $titlenew = $langs->trans("NewLead"); } @@ -1745,13 +1746,13 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM $newmenu->add("/projet/index.php?leftmenu=projects".($search_project_user ? '&search_project_user='.$search_project_user : ''), $titleboth, 0, $user->rights->projet->lire, '', $mainmenu, 'projects', 0, '', '', '', img_picto('', 'project', 'class="pictofixedwidth"')); $newmenu->add("/projet/card.php?leftmenu=projects&action=create".($search_project_user ? '&search_project_user='.$search_project_user : ''), $titlenew, 1, $user->rights->projet->creer); - if ($conf->global->PROJECT_USE_OPPORTUNITIES == 0) { + if (isset($conf->global->PROJECT_USE_OPPORTUNITIES) && $conf->global->PROJECT_USE_OPPORTUNITIES == 0) { $newmenu->add("/projet/list.php?leftmenu=projets".($search_project_user ? '&search_project_user='.$search_project_user : '').'&search_status=99', $langs->trans("List"), 1, $showmode, '', 'project', 'list'); - } elseif ($conf->global->PROJECT_USE_OPPORTUNITIES == 1) { + } elseif (isset($conf->global->PROJECT_USE_OPPORTUNITIES) && $conf->global->PROJECT_USE_OPPORTUNITIES == 1) { $newmenu->add("/projet/list.php?leftmenu=projets".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("List"), 1, $showmode, '', 'project', 'list'); $newmenu->add('/projet/list.php?mainmenu=project&leftmenu=list&search_usage_opportunity=1&search_status=99&search_opp_status=openedopp&contextpage=lead', $langs->trans("ListOpenLeads"), 2, $showmode); $newmenu->add('/projet/list.php?mainmenu=project&leftmenu=list&search_opp_status=notopenedopp&search_status=99&contextpage=project', $langs->trans("ListOpenProjects"), 2, $showmode); - } elseif ($conf->global->PROJECT_USE_OPPORTUNITIES == 2) { // 2 = leads only + } elseif (isset($conf->global->PROJECT_USE_OPPORTUNITIES) && $conf->global->PROJECT_USE_OPPORTUNITIES == 2) { // 2 = leads only $newmenu->add('/projet/list.php?mainmenu=project&leftmenu=list&search_usage_opportunity=1&search_status=99', $langs->trans("List"), 2, $showmode); } @@ -1958,6 +1959,28 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM return 0; } + // Allow the $menu_array of the menu to be manipulated by modules + $parameters = array( + 'mainmenu' => $mainmenu, + ); + $hook_items = $menu_array; + $reshook = $hookmanager->executeHooks('menuLeftMenuItems', $parameters, $hook_items); // Note that $action and $object may have been modified by some hooks + + if (is_numeric($reshook)) { + if ($reshook == 0 && !empty($hookmanager->results)) { + $menu_array[] = $hookmanager->results; // add + } elseif ($reshook == 1) { + $menu_array = $hookmanager->results; // replace + } + + // @todo Sort menu items by 'position' value + // $position = array(); + // foreach ($menu_array as $key => $row) { + // $position[$key] = $row['position']; + // } + // array_multisort($position, SORT_ASC, $menu_array); + } + // TODO Use the position property in menu_array to reorder the $menu_array //var_dump($menu_array); /*$new_menu_array = array(); diff --git a/htdocs/core/modules/barcode/modules_barcode.class.php b/htdocs/core/modules/barcode/modules_barcode.class.php index 99fc8ed366d..01a00405452 100644 --- a/htdocs/core/modules/barcode/modules_barcode.class.php +++ b/htdocs/core/modules/barcode/modules_barcode.class.php @@ -138,7 +138,7 @@ abstract class ModeleNumRefBarCode { global $conf; - $langs->load("admin"); + $langs->loadLangs(array("admin", "companies")); $s = ''; $s .= $langs->trans("Name").': '.$this->name.'
    '; diff --git a/htdocs/core/modules/mailings/contacts1.modules.php b/htdocs/core/modules/mailings/contacts1.modules.php index 4bd03593e09..0ca62392c82 100644 --- a/htdocs/core/modules/mailings/contacts1.modules.php +++ b/htdocs/core/modules/mailings/contacts1.modules.php @@ -140,16 +140,20 @@ 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); $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); @@ -159,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,"; @@ -175,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); @@ -197,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"; @@ -234,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,"; @@ -250,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); @@ -272,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,"; @@ -288,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 .= ''; diff --git a/htdocs/core/modules/modBarcode.class.php b/htdocs/core/modules/modBarcode.class.php index fab12a0ae59..877dca880f7 100644 --- a/htdocs/core/modules/modBarcode.class.php +++ b/htdocs/core/modules/modBarcode.class.php @@ -93,6 +93,7 @@ class modBarcode extends DolibarrModules // Main menu entries $r = 0; + $this->menu[$r] = array( 'fk_menu'=>'fk_mainmenu=tools', // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'mainmenu'=>'tools', @@ -106,7 +107,7 @@ class modBarcode extends DolibarrModules 'enabled'=>'$conf->barcode->enabled', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. 'perms'=>'($conf->global->MAIN_USE_ADVANCED_PERMS && $user->rights->barcode->lire_advance) || (! $conf->global->MAIN_USE_ADVANCED_PERMS)', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules 'target'=>'', - 'user'=>2, // 0=Menu for internal users, 1=external users, 2=both + 'user'=>0, // 0=Menu for internal users, 1=external users, 2=both ); $r++; diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php index 475c8fc5996..bb044900acd 100644 --- a/htdocs/core/modules/modFacture.class.php +++ b/htdocs/core/modules/modFacture.class.php @@ -273,7 +273,7 @@ class modFacture extends DolibarrModules $this->export_TypeFields_array[$r] = array( 's.rowid'=>'Numeric', 's.nom'=>'Text', 'ps.nom'=>'Text', 's.code_client'=>'Text', 's.address'=>'Text', 's.zip'=>'Text', 's.town'=>'Text', 'c.code'=>'Text', 'cd.nom'=>'Text', 's.phone'=>'Text', 's.siren'=>'Text', 's.siret'=>'Text', 's.ape'=>'Text', 's.idprof4'=>'Text', 's.code_compta'=>'Text', 's.code_compta_fournisseur'=>'Text', 's.tva_intra'=>'Text', - 'f.rowid'=>'Numeric', 'f.ref'=>"Text", 'f.ref_client'=>'Text', 'f.type'=>"Numeric", 'f.datec'=>"Date", 'f.datef'=>"Date", 'f.date_lim_reglement'=>"Date", + 'f.rowid'=>'Numeric', 'f.ref'=>"Text", 'f.ref_client'=>'Text', 'f.type'=>"Numeric", 'f.datec'=>"Date", 'f.datef'=>"Date", 'f.date_lim_reglement'=>"Date", 'f.fk_mode_reglement'=>'Numeric', 'f.total_ht'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.total_tva'=>"Numeric", 'f.localtax1'=>'Numeric', 'f.localtax2'=>'Numeric', 'f.paye'=>"Boolean", 'f.fk_statut'=>'Numeric', 'f.close_code'=>'Text', 'f.close_note'=>'Text', 'none.rest'=>"NumericCompute", 'f.note_private'=>"Text", 'f.note_public'=>"Text", 'f.fk_user_author'=>'Numeric', 'uc.login'=>'Text', 'f.fk_user_valid'=>'Numeric', 'uv.login'=>'Text', diff --git a/htdocs/core/modules/modHoliday.class.php b/htdocs/core/modules/modHoliday.class.php index 2d34cee5626..be0b39ecc7e 100644 --- a/htdocs/core/modules/modHoliday.class.php +++ b/htdocs/core/modules/modHoliday.class.php @@ -135,6 +135,28 @@ class modHoliday extends DolibarrModules //$r++; + // Cronjobs + $arraydate = dol_getdate(dol_now()); + $datestart = dol_mktime(4, 0, 0, $arraydate['mon'], $arraydate['mday'], $arraydate['year']); + $this->cronjobs = array( + 0 => array( + 'label' => 'HolidayBalanceMonthlyUpdate', + 'jobtype' => 'method', + 'class' => 'holiday/class/holiday.class.php', + 'objectname' => 'Holiday', + 'method' => 'updateBalance', + 'parameters' => '', + 'comment' => 'Update holiday balance every month', + 'frequency' => 1, + 'unitfrequency' => 3600 * 24, + 'priority' => 50, + 'status' => 1, + 'test' => '$conf->holiday->enabled', + 'datestart' => $datestart + ) + ); + + // Permissions $this->rights = array(); // Permission array used by this module $r = 0; diff --git a/htdocs/core/modules/modStock.class.php b/htdocs/core/modules/modStock.class.php index c9379fb25d6..3494cb684dc 100644 --- a/htdocs/core/modules/modStock.class.php +++ b/htdocs/core/modules/modStock.class.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2008 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2012 Juanjo Menent + * Copyright (C) 2021 Ferran Marcet * * 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 @@ -148,19 +149,19 @@ class modStock extends DolibarrModules $this->rights[4][4] = 'mouvement'; $this->rights[4][5] = 'creer'; + $this->rights[5][0] = 1011; + $this->rights[5][1] = 'inventoryReadPermission'; // Permission label + $this->rights[5][3] = 0; // Permission by default for new user (0/1) + $this->rights[5][4] = 'inventory_advance'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) + $this->rights[5][5] = 'read'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) + + $this->rights[6][0] = 1012; + $this->rights[6][1] = 'inventoryCreatePermission'; // Permission label + $this->rights[6][3] = 0; // Permission by default for new user (0/1) + $this->rights[6][4] = 'inventory_advance'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) + $this->rights[6][5] = 'write'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) + if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { - $this->rights[5][0] = 1011; - $this->rights[5][1] = 'inventoryReadPermission'; // Permission label - $this->rights[5][3] = 0; // Permission by default for new user (0/1) - $this->rights[5][4] = 'inventory_advance'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) - $this->rights[5][5] = 'read'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) - - $this->rights[6][0] = 1012; - $this->rights[6][1] = 'inventoryCreatePermission'; // Permission label - $this->rights[6][3] = 0; // Permission by default for new user (0/1) - $this->rights[6][4] = 'inventory_advance'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) - $this->rights[6][5] = 'write'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) - $this->rights[8][0] = 1014; $this->rights[8][1] = 'inventoryValidatePermission'; // Permission label $this->rights[8][3] = 0; // Permission by default for new user (0/1) diff --git a/htdocs/core/modules/modTicket.class.php b/htdocs/core/modules/modTicket.class.php index 705c89be80f..78bcb9901af 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,fk_parent", "code,label,pos,use_default"), 'tabfieldinsert' => array("code,label,pos,use_default", "code,label,pos,use_default", "code,label,pos,use_default,public,fk_parent", "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/core/modules/product/mod_codeproduct_elephant.php b/htdocs/core/modules/product/mod_codeproduct_elephant.php index 5936476e079..0b03bd9b6a4 100644 --- a/htdocs/core/modules/product/mod_codeproduct_elephant.php +++ b/htdocs/core/modules/product/mod_codeproduct_elephant.php @@ -118,7 +118,7 @@ class mod_codeproduct_elephant extends ModeleProductCode $texte .= '
    '.$langs->trans("Mask").' ('.$langs->trans("ProductCodeModel").'):'.$form->textwithpicto('', $tooltip, 1, 1).'   
    '.$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 "
    '; @@ -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_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 0b1221006a8..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'; } @@ -421,8 +425,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 ""; @@ -583,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); @@ -612,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_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/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/linkedobjectblock.tpl.php b/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php new file mode 100644 index 00000000000..f2bb6f0c3ae --- /dev/null +++ b/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php @@ -0,0 +1,61 @@ + + * 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 ''; + 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 ''; +} + +echo "\n"; 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/expedition/class/api_shipments.class.php b/htdocs/expedition/class/api_shipments.class.php index 2a4b6765b4e..eaf66e59125 100644 --- a/htdocs/expedition/class/api_shipments.class.php +++ b/htdocs/expedition/class/api_shipments.class.php @@ -530,14 +530,9 @@ class Shipments extends DolibarrApi if ($result < 0) { throw new RestException(500, 'Error when validating Shipment: '.$this->shipment->error); } - $result = $this->shipment->fetch($id); - if (!$result) { - throw new RestException(404, 'Shipment not found'); - } - if (!DolibarrApi::_checkAccessToResource('expedition', $this->shipment->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } + // Reload shipment + $result = $this->shipment->fetch($id); $this->shipment->fetchObjectLinked(); return $this->_cleanObjectDatas($this->shipment); @@ -626,6 +621,47 @@ class Shipments extends DolibarrApi } */ + /** + * Close a shipment (Classify it as "Delivered") + * + * @param int $id Expedition ID + * @param int $notrigger Disabled triggers + * + * @url POST {id}/close + * + * @return int + */ + public function close($id, $notrigger = 0) + { + if (!DolibarrApiAccess::$user->rights->expedition->creer) { + throw new RestException(401); + } + + $result = $this->shipment->fetch($id); + if (!$result) { + throw new RestException(404, 'Shipment not found'); + } + + if (!DolibarrApi::_checkAccessToResource('expedition', $this->commande->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->shipment->setClosed(); + if ($result == 0) { + throw new RestException(304, 'Error nothing done. May be object is already closed'); + } + if ($result < 0) { + throw new RestException(500, 'Error when closing Order: '.$this->commande->error); + } + + // Reload shipment + $result = $this->shipment->fetch($id); + + $this->shipment->fetchObjectLinked(); + + return $this->_cleanObjectDatas($this->shipment); + } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore /** * Clean sensible object datas diff --git a/htdocs/expensereport/class/paymentexpensereport.class.php b/htdocs/expensereport/class/paymentexpensereport.class.php index a453b810e6a..6e3e8d34137 100644 --- a/htdocs/expensereport/class/paymentexpensereport.class.php +++ b/htdocs/expensereport/class/paymentexpensereport.class.php @@ -169,7 +169,7 @@ class PaymentExpenseReport extends CommonObject $sql .= " VALUES ($this->fk_expensereport, '".$this->db->idate($now)."',"; $sql .= " '".$this->db->idate($this->datepaid)."',"; $sql .= " ".price2num($totalamount).","; - $sql .= " ".$this->fk_typepayment.", '".$this->db->escape($this->num_payment)."', '".$this->db->escape($this->note_public)."', ".$user->id.","; + $sql .= " ".((int) $this->fk_typepayment).", '".$this->db->escape($this->num_payment)."', '".$this->db->escape($this->note_public)."', ".((int) $user->id).","; $sql .= " 0)"; dol_syslog(get_class($this)."::create", LOG_DEBUG); diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index f315661b90c..e938b729f80 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -11,6 +11,7 @@ * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2018-2020 Frédéric France * Copyright (C) 2018 Ferran Marcet + * 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 @@ -460,7 +461,7 @@ class CommandeFournisseur extends CommonOrder $sql .= " l.vat_src_code, l.tva_tx, l.remise_percent, l.subprice,"; $sql .= " l.localtax1_tx, l. localtax2_tx, l.localtax1_type, l. localtax2_type, l.total_localtax1, l.total_localtax2,"; $sql .= " l.total_ht, l.total_tva, l.total_ttc, l.special_code, l.fk_parent_line, l.rang,"; - $sql .= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.description as product_desc,"; + $sql .= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.description as product_desc, p.tobatch as product_tobatch, p.barcode as product_barcode,"; $sql .= " l.fk_unit,"; $sql .= " l.date_start, l.date_end,"; $sql .= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc'; @@ -516,6 +517,8 @@ class CommandeFournisseur extends CommonOrder $line->libelle = $objp->product_label; // deprecated $line->product_label = $objp->product_label; $line->product_desc = $objp->product_desc; + $line->product_tobatch = $objp->product_tobatch; + $line->product_barcode = $objp->product_barcode; $line->ref = $objp->product_ref; // Ref of product $line->product_ref = $objp->product_ref; // Ref of product diff --git a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php index 5457a9ee376..cd1ff267fb7 100644 --- a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php +++ b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php @@ -220,13 +220,12 @@ class CommandeFournisseurDispatch extends CommonObject $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element); if (!$notrigger) { - // Uncomment this and change MYOBJECT to your own tag if you - // want this action calls a trigger. - - //// Call triggers - //$result=$this->call_trigger('MYOBJECT_CREATE',$user); - //if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail} - //// End call triggers + // Call triggers + $result=$this->call_trigger('LINERECEPTION_CREATE', $user); + if ($result < 0) { + $error++; + } + // End call triggers } } diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index cc0f67e4b4e..0affc7dcce4 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -983,7 +983,9 @@ if (empty($reshook)) { if ($action == 'commande') { $methodecommande = GETPOST('methodecommande', 'int'); - if ($methodecommande <= 0) { + if ($cancel) { + $action = ''; + } elseif ($methodecommande <= 0) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("OrderMode")), null, 'errors'); $action = 'makeorder'; } @@ -1059,36 +1061,43 @@ if (empty($reshook)) { // Set status of reception (complete, partial, ...) if ($action == 'livraison' && $usercanreceived) { - $db->begin(); + if ($cancel) { + $action = ''; + } else { + $db->begin(); - if (GETPOST("type") != '') { - $date_liv = dol_mktime(GETPOST('rehour'), GETPOST('remin'), GETPOST('resec'), GETPOST("remonth"), GETPOST("reday"), GETPOST("reyear")); + if (GETPOST("type") != '') { + $date_liv = dol_mktime(GETPOST('rehour'), GETPOST('remin'), GETPOST('resec'), GETPOST("remonth"), GETPOST("reday"), GETPOST("reyear")); - $result = $object->Livraison($user, $date_liv, GETPOST("type"), GETPOST("comment")); // GETPOST("type") is 'tot', 'par', 'nev', 'can' - if ($result > 0) { - $langs->load("deliveries"); - setEventMessages($langs->trans("DeliveryStateSaved"), null); - $action = ''; - } elseif ($result == -3) { - $error++; - setEventMessages($object->error, $object->errors, 'errors'); + $result = $object->Livraison($user, $date_liv, GETPOST("type"), GETPOST("comment")); // GETPOST("type") is 'tot', 'par', 'nev', 'can' + if ($result > 0) { + $langs->load("deliveries"); + setEventMessages($langs->trans("DeliveryStateSaved"), null); + $action = ''; + } elseif ($result == -3) { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + } else { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + } } else { $error++; - setEventMessages($object->error, $object->errors, 'errors'); + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Delivery")), null, 'errors'); } - } else { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Delivery")), null, 'errors'); - } - if (!$error) { - $db->commit(); - } else { - $db->rollback(); + if (!$error) { + $db->commit(); + } else { + $db->rollback(); + } } } if ($action == 'confirm_cancel' && $confirm == 'yes' && $usercanorder) { + if (GETPOST('cancel_note')) { + $object->cancel_note = GETPOST('cancel_note'); + } $result = $object->cancel($user); if ($result > 0) { header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object->id); @@ -1889,13 +1898,13 @@ if ($action == 'create') { $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("ApproveThisOrder"), $text, "confirm_".$action, $formquestion, 1, 1, 240); } - // Confirmation de la desapprobation + // Confirmation of disapproval if ($action == 'refuse') { $formquestion = array( array( 'type' => 'text', 'name' => 'refuse_note', - 'label' => $langs->trans("MotifCP"), + 'label' => $langs->trans("Reason"), 'value' => '', 'morecss' => 'minwidth300' ) @@ -1903,9 +1912,18 @@ if ($action == 'create') { $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id", $langs->trans("DenyingThisOrder"), $langs->trans("ConfirmDenyingThisOrder", $object->ref), "confirm_refuse", $formquestion, 0, 1); } - // Confirmation de l'annulation + // Confirmation of cancellation if ($action == 'cancel') { - $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id", $langs->trans("Cancel"), $langs->trans("ConfirmCancelThisOrder", $object->ref), "confirm_cancel", '', 0, 1); + $formquestion = array( + array( + 'type' => 'text', + 'name' => 'cancel_note', + 'label' => $langs->trans("Reason"), + 'value' => '', + 'morecss' => 'minwidth300' + ) + ); + $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id", $langs->trans("Cancel"), $langs->trans("ConfirmCancelThisOrder", $object->ref), "confirm_cancel", $formquestion, 0, 1); } // Confirmation de l'envoi de la commande @@ -2640,7 +2658,11 @@ if ($action == 'create') { print ''; print ''.$langs->trans("Comment").''; - print ''; + print ''; + print ''; + print '     '; + print ''; + print ''; print "\n"; print "\n"; print "
    "; diff --git a/htdocs/fourn/js/lib_dispatch.js.php b/htdocs/fourn/js/lib_dispatch.js.php index fd15894b4ec..01af2ee5d91 100644 --- a/htdocs/fourn/js/lib_dispatch.js.php +++ b/htdocs/fourn/js/lib_dispatch.js.php @@ -70,7 +70,9 @@ function addDispatchLine(index, type, mode) mode = mode || 'qtymissing' console.log("fourn/js/lib_dispatch.js.php Split line type="+type+" index="+index+" mode="+mode); - var $row = $("tr[name='"+type+'_0_'+index+"']").clone(true); // clone first batch line to jQuery object + var $row0 = $("tr[name='"+type+'_0_'+index+"']"); + var $dpopt = $row0.find('.hasDatepicker').first().datepicker('option', 'all'); // get current datepicker options to apply the same to the cloned datepickers + var $row = $row0.clone(true); // clone first batch line to jQuery object var nbrTrs = $("tr[name^='"+type+"_'][name$='_"+index+"']").length; // position of line for batch var qtyOrdered = parseFloat($("#qty_ordered_0_"+index).val()); // Qty ordered is same for all rows var qty = parseFloat($("#qty_"+(nbrTrs - 1)+"_"+index).val()); @@ -96,6 +98,18 @@ function addDispatchLine(index, type, mode) } else if (qtyDispatched < qtyOrdered) { //replace tr suffix nbr $row.html($row.html().replace(/_0_/g,"_"+nbrTrs+"_")); + + // jquery's deep clone is incompatible with date pickers (the clone shares data with the original) + // so we destroy and rebuild the new date pickers + setTimeout(() => { + $row.find('.hasDatepicker').each((i, dp) => { + $(dp).removeData() + .removeClass('hasDatepicker'); + $(dp).next('img.ui-datepicker-trigger').remove(); + $(dp).datepicker($dpopt); + }); + }, 0); + //create new select2 to avoid duplicate id of cloned one $row.find("select[name='"+'entrepot_'+nbrTrs+'_'+index+"']").select2(); // TODO find solution to copy selected option to new select diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index 82229198185..b272d7b45fb 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -227,7 +227,7 @@ class Holiday extends CommonObject if ($result >= 0) { $this->db->commit(); - return 1; + return 0; // for cronjob use (0 is OK, any other value is an error code) } else { $this->db->rollback(); return -1; @@ -1296,11 +1296,11 @@ class Holiday extends CommonObject * * @param int $selected Id of preselected status * @param string $htmlname Name of HTML select field + * @param string $morecss More CSS on select component * @return string Show select of status */ - public function selectStatutCP($selected = '', $htmlname = 'select_statut') + public function selectStatutCP($selected = '', $htmlname = 'select_statut', $morecss = 'minwidth125') { - global $langs; // Liste des statuts @@ -1308,7 +1308,7 @@ class Holiday extends CommonObject $nb = count($name) + 1; // Select HTML - $out = ''."\n"; $out .= ''."\n"; // Boucle des statuts diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index ab57a497e8e..e7a09abea6e 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -636,7 +636,7 @@ if ($resql) { // Create date if (!empty($arrayfields['cp.date_create']['checked'])) { - print ''; + print ''; print ''; $formother->select_year($search_year_create, 'search_year_create', 1, $min_year, 0); print ''; @@ -644,7 +644,7 @@ if ($resql) { // Create date if (!empty($arrayfields['cp.tms']['checked'])) { - print ''; + print ''; print ''; $formother->select_year($search_year_update, 'search_year_update', 1, $min_year, 0); print ''; @@ -652,8 +652,8 @@ if ($resql) { // Status if (!empty($arrayfields['cp.statut']['checked'])) { - print ''; - $object->selectStatutCP($search_status, 'search_status'); + print ''; + $object->selectStatutCP($search_status, 'search_status', 'minwidth125'); print ''; } @@ -781,7 +781,7 @@ if ($resql) { } } if (!empty($arrayfields['cp.fk_type']['checked'])) { - print ''; + print ''; $labeltypeleavetoshow = ($langs->trans($typeleaves[$obj->fk_type]['code']) != $typeleaves[$obj->fk_type]['code'] ? $langs->trans($typeleaves[$obj->fk_type]['code']) : $typeleaves[$obj->fk_type]['label']); print empty($typeleaves[$obj->fk_type]['label']) ? $langs->trans("TypeWasDisabledOrRemoved", $obj->fk_type) : $labeltypeleavetoshow; print ''; 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); diff --git a/htdocs/install/check.php b/htdocs/install/check.php index 35efe1f36b2..a509768f4b5 100644 --- a/htdocs/install/check.php +++ b/htdocs/install/check.php @@ -100,7 +100,7 @@ print "
    \n"; // Check PHP support for $_GET and $_POST if (!isset($_GET["testget"]) && !isset($_POST["testpost"])) { // We must keep $_GET and $_POST here print 'Warning '.$langs->trans("PHPSupportPOSTGETKo"); - print ' ('.$langs->trans("Recheck").')'; + print ' ('.$langs->trans("Recheck").')'; print "
    \n"; $checksok = 0; } else { @@ -411,26 +411,28 @@ if (!file_exists($conffile)) { if (GETPOST('allowupgrade')) { $allowupgrade = true; } - $migrationscript = array(array('from'=>'3.0.0', 'to'=>'3.1.0'), - array('from'=>'3.1.0', 'to'=>'3.2.0'), - array('from'=>'3.2.0', 'to'=>'3.3.0'), - array('from'=>'3.3.0', 'to'=>'3.4.0'), - array('from'=>'3.4.0', 'to'=>'3.5.0'), - array('from'=>'3.5.0', 'to'=>'3.6.0'), - array('from'=>'3.6.0', 'to'=>'3.7.0'), - array('from'=>'3.7.0', 'to'=>'3.8.0'), - array('from'=>'3.8.0', 'to'=>'3.9.0'), - array('from'=>'3.9.0', 'to'=>'4.0.0'), - array('from'=>'4.0.0', 'to'=>'5.0.0'), - array('from'=>'5.0.0', 'to'=>'6.0.0'), - array('from'=>'6.0.0', 'to'=>'7.0.0'), - array('from'=>'7.0.0', 'to'=>'8.0.0'), - array('from'=>'8.0.0', 'to'=>'9.0.0'), - array('from'=>'9.0.0', 'to'=>'10.0.0'), - array('from'=>'10.0.0', 'to'=>'11.0.0'), - array('from'=>'11.0.0', 'to'=>'12.0.0'), - array('from'=>'12.0.0', 'to'=>'13.0.0'), - array('from'=>'13.0.0', 'to'=>'14.0.0') + $migrationscript = array( + array('from'=>'3.0.0', 'to'=>'3.1.0'), + array('from'=>'3.1.0', 'to'=>'3.2.0'), + array('from'=>'3.2.0', 'to'=>'3.3.0'), + array('from'=>'3.3.0', 'to'=>'3.4.0'), + array('from'=>'3.4.0', 'to'=>'3.5.0'), + array('from'=>'3.5.0', 'to'=>'3.6.0'), + array('from'=>'3.6.0', 'to'=>'3.7.0'), + array('from'=>'3.7.0', 'to'=>'3.8.0'), + array('from'=>'3.8.0', 'to'=>'3.9.0'), + array('from'=>'3.9.0', 'to'=>'4.0.0'), + array('from'=>'4.0.0', 'to'=>'5.0.0'), + array('from'=>'5.0.0', 'to'=>'6.0.0'), + array('from'=>'6.0.0', 'to'=>'7.0.0'), + array('from'=>'7.0.0', 'to'=>'8.0.0'), + array('from'=>'8.0.0', 'to'=>'9.0.0'), + array('from'=>'9.0.0', 'to'=>'10.0.0'), + array('from'=>'10.0.0', 'to'=>'11.0.0'), + array('from'=>'11.0.0', 'to'=>'12.0.0'), + array('from'=>'12.0.0', 'to'=>'13.0.0'), + array('from'=>'13.0.0', 'to'=>'14.0.0'), + array('from'=>'14.0.0', 'to'=>'15.0.0'), ); $count = 0; diff --git a/htdocs/install/default.css b/htdocs/install/default.css index 731ac4131b4..85a2f4703c2 100644 --- a/htdocs/install/default.css +++ b/htdocs/install/default.css @@ -415,3 +415,6 @@ a.button:hover { vertical-align: text-bottom; } +.text-security { + -webkit-text-security: disc; +} diff --git a/htdocs/install/fileconf.php b/htdocs/install/fileconf.php index 42c8d3459fe..42ea5e423af 100644 --- a/htdocs/install/fileconf.php +++ b/htdocs/install/fileconf.php @@ -476,13 +476,13 @@ if (!empty($force_install_noedit)) { - 0 && !empty($force_install_databaserootlogin)) { print ' disabled'; } ?> @@ -556,10 +556,10 @@ if (!empty($force_install_noedit)) { autocomplete="off" id="db_pass_root" name="db_pass_root" - class="needroot" + class="needroot text-security" value=" -- Copyright (C) 2005-2011 Regis Houssin -- Copyright (C) 2007 Patrick Raguin +-- Copyright (C) 2021 Udo Tamm +-- -- -- 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 @@ -21,6 +23,9 @@ -- -- +-- +-- Do not put a comment at the end of the line, this file is parsed during the +-- install and all '--' symbols are removed. -- -- Ne pas placer de commentaire en fin de ligne, ce fichier est parsé lors -- de l'install et tous les sigles '--' sont supprimés. @@ -31,25 +36,29 @@ -- delete from llx_c_actioncomm where id in (1,2,3,4,5,6,8,9,10,11,30,31,40,50); --- Code used from 3.3+ when type of event is used -insert into llx_c_actioncomm (id, code, type, libelle, module, active, position) values ( 1,'AC_TEL','system','Phone call',NULL, 1, 2); -insert into llx_c_actioncomm (id, code, type, libelle, module, active, position) values ( 2,'AC_FAX','system','Send Fax',NULL, 1, 3); -insert into llx_c_actioncomm (id, code, type, libelle, module, active, position) values ( 4,'AC_EMAIL','system','Send Email',NULL, 1, 4); -insert into llx_c_actioncomm (id, code, type, libelle, module, active, position) values ( 5,'AC_RDV','system','Rendez-vous',NULL, 1, 1); -insert into llx_c_actioncomm (id, code, type, libelle, module, active, position) values ( 6,'AC_EMAIL_IN','system','reception Email',NULL, 1, 4); -insert into llx_c_actioncomm (id, code, type, libelle, module, active, position) values (11,'AC_INT','system','Intervention on site',NULL, 1, 4); --- Code kept for backward compatibility < 3.3 ---insert into llx_c_actioncomm (id, code, type, libelle, module, active, position) values ( 3,'AC_PROP','systemauto', 'Send commercial proposal by email','propal',0,10); ---insert into llx_c_actioncomm (id, code, type, libelle, module, active, position) values ( 8,'AC_COM','systemauto','Send customer order by email','order', 0,8); ---insert into llx_c_actioncomm (id, code, type, libelle, module, active, position) values ( 9,'AC_FAC','systemauto', 'Send customer invoice by email','invoice',0,6); ---insert into llx_c_actioncomm (id, code, type, libelle, module, active, position) values ( 10,'AC_SHIP','systemauto', 'Send shipping by email','shipping',0,11); ---insert into llx_c_actioncomm (id, code, type, libelle, module, active, position) values ( 30,'AC_SUP_ORD','systemauto','Send supplier order by email','order_supplier',0,9); ---insert into llx_c_actioncomm (id, code, type, libelle, module, active, position) values ( 31,'AC_SUP_INV','systemauto','Send supplier invoice by email','invoice_supplier',0,7); --- Code used from 3.3+ when type of event is not used -insert into llx_c_actioncomm (id, code, type, libelle, module, active, position) values ( 40,'AC_OTH_AUTO','systemauto','Other (automatically inserted events)',NULL, 1, 20); -insert into llx_c_actioncomm (id, code, type, libelle, module, active, position) values ( 50,'AC_OTH','system','Other (manually inserted events)',NULL, 1, 5); -INSERT INTO llx_c_actioncomm (id, code, type, libelle, module, active, position) VALUES ( 60,'AC_EO_ONLINECONF','module','Online/Virtual conference','conference@eventorganization', 1, 60); -INSERT INTO llx_c_actioncomm (id, code, type, libelle, module, active, position) VALUES ( 61,'AC_EO_INDOORCONF','module','Indoor conference','conference@eventorganization', 1, 61); -INSERT INTO llx_c_actioncomm (id, code, type, libelle, module, active, position) VALUES ( 62,'AC_EO_ONLINEBOOTH','module','Online/Virtual booth','booth@eventorganization', 1, 62); -INSERT INTO llx_c_actioncomm (id, code, type, libelle, module, active, position) VALUES ( 63,'AC_EO_INDOORBOOTH','module','Indoor booth','booth@eventorganization', 1, 63); +-- Code used from 3.3+ when type of event is used +insert into llx_c_actioncomm (id, code, libelle, type, module, active, position) values ( 1, 'AC_TEL', 'Phone call', 'system', NULL, 1, 2); +insert into llx_c_actioncomm (id, code, libelle, type, module, active, position) values ( 2, 'AC_FAX', 'Send Fax', 'system', NULL, 1, 3); +insert into llx_c_actioncomm (id, code, libelle, type, module, active, position) values ( 4, 'AC_EMAIL', 'Send Email', 'system', NULL, 1, 4); +insert into llx_c_actioncomm (id, code, libelle, type, module, active, position) values ( 5, 'AC_RDV', 'Rendez-vous', 'system', NULL, 1, 1); +insert into llx_c_actioncomm (id, code, libelle, type, module, active, position) values ( 6, 'AC_EMAIL_IN', 'reception Email', 'system', NULL, 1, 4); +insert into llx_c_actioncomm (id, code, libelle, type, module, active, position) values ( 11, 'AC_INT', 'Intervention on site', 'system', NULL, 1, 4); + +-- Code kept for backward compatibility < 3.3 +--insert into llx_c_actioncomm (id, code, libelle, type, module, active, position) values ( 3, 'AC_PROP', 'Send commercial proposal by email', 'systemauto', 'propal', 0, 10); +--insert into llx_c_actioncomm (id, code, libelle, type, module, active, position) values ( 8, 'AC_COM', 'Send customer order by email', 'systemauto', 'order', 0, 8); +--insert into llx_c_actioncomm (id, code, libelle, type, module, active, position) values ( 9, 'AC_FAC', 'Send customer invoice by email', 'systemauto', 'invoice', 0, 6); +--insert into llx_c_actioncomm (id, code, libelle, type, module, active, position) values ( 10, 'AC_SHIP', 'Send shipping by email', 'systemauto', 'shipping', 0, 11); +--insert into llx_c_actioncomm (id, code, libelle, type, module, active, position) values ( 30, 'AC_SUP_ORD', 'Send supplier order by email', 'systemauto', 'order_supplier', 0, 9); +--insert into llx_c_actioncomm (id, code, libelle, type, module, active, position) values ( 31, 'AC_SUP_INV', 'Send supplier invoice by email', 'systemauto', 'invoice_supplier', 0, 7); + +-- Code used from 3.3+ when type of event is not used + +insert into llx_c_actioncomm (id, code, libelle, type, module, active, position) values ( 40, 'AC_OTH_AUTO', 'Other (automatically inserted events)', 'systemauto', NULL, 1, 20); +insert into llx_c_actioncomm (id, code, libelle, type, module, active, position) values ( 50, 'AC_OTH', 'Other (manually inserted events)', 'systemauto', NULL, 1, 5); + +INSERT INTO llx_c_actioncomm (id, code, libelle, type, module, active, position) VALUES ( 60, 'AC_EO_ONLINECONF', 'Online/Virtual conference', 'module', 'conference@eventorganization', 1, 60); +INSERT INTO llx_c_actioncomm (id, code, libelle, type, module, active, position) VALUES ( 61, 'AC_EO_INDOORCONF', 'Indoor conference', 'module', 'conference@eventorganization', 1, 61); +INSERT INTO llx_c_actioncomm (id, code, libelle, type, module, active, position) VALUES ( 62, 'AC_EO_ONLINEBOOTH', 'Online/Virtual booth', 'module', 'booth@eventorganization', 1, 62); +INSERT INTO llx_c_actioncomm (id, code, libelle, type, module, active, position) VALUES ( 63, 'AC_EO_INDOORBOOTH', 'Indoor booth', 'module', 'booth@eventorganization', 1, 63); 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/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index 95de2ab7ba6..89546dd9bb6 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -26,14 +26,34 @@ -- To set a field as NOT NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET NOT NULL; -- To set a field as default NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET DEFAULT NULL; -- Note: fields with type BLOB/TEXT can't have default value. --- To rebuild sequence for postgresql after insert by forcing id autoincrement fields: +-- To rebuild sequence for postgresql after insert by forcing id autoincrement fields: -- -- VPGSQL8.2 SELECT dol_util_rebuild_sequences(); -- Missing in v14 or lower - - -- v15 +ALTER TABLE llx_emailcollector_emailcollectoraction MODIFY COLUMN actionparam TEXT; + +ALTER TABLE llx_knowledgemanagement_knowledgerecord ADD lang varchar(6); + +CREATE TABLE llx_categorie_ticket +( + fk_categorie integer NOT NULL, + fk_ticket integer NOT NULL, + import_key varchar(14) +) ENGINE=innodb; + +ALTER TABLE llx_categorie_ticket ADD PRIMARY KEY pk_categorie_ticket (fk_categorie, fk_ticket); +ALTER TABLE llx_categorie_ticket ADD INDEX idx_categorie_ticket_fk_categorie (fk_categorie); +ALTER TABLE llx_categorie_ticket ADD INDEX idx_categorie_ticket_fk_ticket (fk_ticket); + +ALTER TABLE llx_categorie_ticket ADD CONSTRAINT fk_categorie_ticket_categorie_rowid FOREIGN KEY (fk_categorie) REFERENCES llx_categorie (rowid); +ALTER TABLE llx_categorie_ticket ADD CONSTRAINT fk_categorie_ticket_ticket_rowid FOREIGN KEY (fk_ticket) REFERENCES llx_ticket (rowid); +ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN ref_fourn varchar(128); +ALTER TABLE llx_product_customer_price MODIFY COLUMN ref_customer varchar(128); + +-- -- add action trigger +INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) VALUES ('ORDER_SUPPLIER_CANCEL','Supplier order request canceled','Executed when a supplier order is canceled','order_supplier',13); diff --git a/htdocs/install/mysql/tables/llx_adherent.sql b/htdocs/install/mysql/tables/llx_adherent.sql index 787a2b15bd7..1d3a784dd74 100644 --- a/htdocs/install/mysql/tables/llx_adherent.sql +++ b/htdocs/install/mysql/tables/llx_adherent.sql @@ -48,6 +48,7 @@ create table llx_adherent state_id integer, country integer, email varchar(255), + url varchar(255) NULL, socialnetworks text DEFAULT NULL, -- json with socialnetworks skype varchar(255), -- deprecated diff --git a/htdocs/install/mysql/tables/llx_emailcollector_emailcollectoraction.sql b/htdocs/install/mysql/tables/llx_emailcollector_emailcollectoraction.sql index c45a3dcd1c4..deda90cbdcd 100644 --- a/htdocs/install/mysql/tables/llx_emailcollector_emailcollectoraction.sql +++ b/htdocs/install/mysql/tables/llx_emailcollector_emailcollectoraction.sql @@ -19,7 +19,7 @@ CREATE TABLE llx_emailcollector_emailcollectoraction( rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, fk_emailcollector INTEGER NOT NULL, type varchar(128) NOT NULL, - actionparam varchar(255) NULL, + actionparam text NULL, date_creation datetime NOT NULL, tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, fk_user_creat integer NOT NULL, diff --git a/htdocs/install/mysql/tables/llx_object_lang.sql b/htdocs/install/mysql/tables/llx_object_lang.sql index cc4352f3acc..01b70b208ff 100644 --- a/htdocs/install/mysql/tables/llx_object_lang.sql +++ b/htdocs/install/mysql/tables/llx_object_lang.sql @@ -25,7 +25,7 @@ create table llx_object_lang fk_object integer DEFAULT 0 NOT NULL, type_object varchar(32) NOT NULL, -- value found into $object->element: 'thirdparty', 'contact', '...' property varchar(32) NOT NULL, -- name of property - lang varchar(5) DEFAULT 0 NOT NULL, + lang varchar(5) DEFAULT '' NOT NULL, value text, import_key varchar(14) DEFAULT NULL )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_product_customer_price.sql b/htdocs/install/mysql/tables/llx_product_customer_price.sql index f0d5edf9c2f..361a42a5b54 100644 --- a/htdocs/install/mysql/tables/llx_product_customer_price.sql +++ b/htdocs/install/mysql/tables/llx_product_customer_price.sql @@ -28,7 +28,7 @@ create table llx_product_customer_price tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, fk_product integer NOT NULL, fk_soc integer NOT NULL, - ref_customer varchar(30), + ref_customer varchar(128), price double(24,8) DEFAULT 0, price_ttc double(24,8) DEFAULT 0, price_min double(24,8) DEFAULT 0, diff --git a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql index 4e1d75dd1dd..2a01df30e4b 100644 --- a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql +++ b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql @@ -27,7 +27,7 @@ create table llx_product_fournisseur_price tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, fk_product integer, fk_soc integer, - ref_fourn varchar(30), + ref_fourn varchar(128), desc_fourn text, fk_availability integer, price double(24,8) DEFAULT 0, -- price without tax for quantity diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 27a6b3337a4..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 @@ -339,7 +339,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 diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 3f8077ba9f3..ade0f89ff1c 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2092,7 +2092,7 @@ LargerThan=Larger than IfTrackingIDFoundEventWillBeLinked=Note that If a tracking ID of an object is found into email, or if the email is an answer of an email aready collected and linked to an object, the created event will be automatically linked to the known related object. WithGMailYouCanCreateADedicatedPassword=With a GMail account, if you enabled the 2 steps validation, it is recommanded to create a dedicated second password for the application instead of using your own account passsword from https://myaccount.google.com/. EmailCollectorTargetDir=It may be a desired behaviour to move the email into another tag/directory when it was processed successfully. Just set name of directory here to use this feature (Do NOT use special characters in name). Note that you must also use a read/write login account. -EmailCollectorLoadThirdPartyHelp=You can use this action to use the email content to find and load an existing thirdparty in your database. The found (or created) thirdparty will be used for following actions that need it. In the parameter field you can use for example 'EXTRACT:BODY:Name:\s([^\s]*)' if you want to extract the name of the thirdparty from a string 'Name: name to find' found into the body. +EmailCollectorLoadThirdPartyHelp=You can use this action to use the email content to find and load an existing thirdparty in your database. The found (or created) thirdparty will be used for following actions that need it.
    For example, if you want to create a thirdparty with a name extracted a string 'Name: name to find' found into the body, use sender email as email, you can set the parameter field like this:
    'email=HEADER:^From:(.*);name=EXTRACT:BODY:Name:\s([^\s]*);client=SET:2;'
    EndPointFor=End point for %s : %s DeleteEmailCollector=Delete email collector ConfirmDeleteEmailCollector=Are you sure you want to delete this email collector? @@ -2150,4 +2150,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 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/langs/en_US/holiday.lang b/htdocs/langs/en_US/holiday.lang index 2393a02ee50..0e6b1d69b36 100644 --- a/htdocs/langs/en_US/holiday.lang +++ b/htdocs/langs/en_US/holiday.lang @@ -132,3 +132,4 @@ FreeLegalTextOnHolidays=Free text on PDF WatermarkOnDraftHolidayCards=Watermarks on draft leave requests HolidaysToApprove=Holidays to approve NobodyHasPermissionToValidateHolidays=Nobody has permission to validate holidays +HolidayBalanceMonthlyUpdate=Monthly update of holiday balance 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) diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 7dfafe73edb..6c1ef6aa659 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -1148,3 +1148,4 @@ RecordsDisabled=%s record(s) disabled RecordEnabled=Record enabled RecordDisabled=Record disabled Forthcoming=Forthcoming +Currently=Currently diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index efa5257498c..4396139f1f9 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -255,4 +255,9 @@ MakeMovementsAndClose=Generate movements and close AutofillWithExpected=Fill real quantity with expected quantity ShowAllBatchByDefault=By default, show batch details on product "stock" tab CollapseBatchDetailHelp=You can set batch detail default display in stocks module configuration -FieldCannotBeNegative=Field "%s" cannot be negative \ No newline at end of file +FieldCannotBeNegative=Field "%s" cannot be negative +ErrorWrongBarcodemode=Unknown Barcode mode +ProductDoesNotExist=Product does not exist +ErrorSameBatchNumber=Same batch number found in inventory list +ProductBatchDoesNotExist=Product with batch/serial does not exist +ProductBarcodeDoesNotExist=Product with barcode does not exist 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/langs/en_US/withdrawals.lang b/htdocs/langs/en_US/withdrawals.lang index 7d5b57f7da9..a3773a427a1 100644 --- a/htdocs/langs/en_US/withdrawals.lang +++ b/htdocs/langs/en_US/withdrawals.lang @@ -133,8 +133,7 @@ SEPARCUR=SEPA CUR SEPAFRST=SEPA FRST ExecutionDate=Execution date CreateForSepa=Create direct debit file -ICS=Creditor Identifier CI for direct debit -ICSTransfer=Creditor Identifier CI for bank transfer +ICS=Creditor Identifier - ICS END_TO_END="EndToEndId" SEPA XML tag - Unique id assigned per transaction USTRD="Unstructured" SEPA XML tag ADDDAYS=Add days to Execution Date diff --git a/htdocs/langs/fr_FR/categories.lang b/htdocs/langs/fr_FR/categories.lang index 4b806e1edbd..20bfb122c75 100644 --- a/htdocs/langs/fr_FR/categories.lang +++ b/htdocs/langs/fr_FR/categories.lang @@ -17,6 +17,7 @@ ContactsCategoriesArea=Espace tags/catégories de contacts AccountsCategoriesArea=Espace des tags/categories de comptes bancaires ProjectsCategoriesArea=Espace des tags/catégories des projets UsersCategoriesArea=Espace des tags/catégories des utilisateurs +TicketsCategoriesArea=Espace tags/catégories des tickets SubCats=Sous-catégories CatList=Liste des tags/catégories CatListAll=Liste de toutes les catégories (de tous types) @@ -90,6 +91,7 @@ CategorieRecursivHelp=Si l'option est activé, quand un produit est ajouté dans AddProductServiceIntoCategory=Ajouter le produit/service suivant AddCustomerIntoCategory=Assigner cette catégorie au client AddSupplierIntoCategory=Assigner cette catégorie au fournisseur +AddTicketIntoCategory=Assigner cette catégorie au ticket ShowCategory=Afficher tag/catégorie ByDefaultInList=Par défaut dans la liste ChooseCategory=Choisissez une catégorie 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 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=您必須已投票並使用與投票時相同的用戶名來發表評論 diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 99cfe360f9f..49797b1e6e8 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -80,7 +80,7 @@ function realCharForNumericEntities($matches) * Warning: Such a protection can't be enough. It is not reliable as it will always be possible to bypass this. Good protection can * only be guaranted by escaping data during output. * - * @param string $val Value brut found int $_GET, $_POST or PHP_SELF + * @param string $val Brut value found into $_GET, $_POST or PHP_SELF * @param string $type 0=POST, 1=GET, 2=PHP_SELF, 3=GET without sql reserved keywords (the less tolerant test) * @return int >0 if there is an injection, 0 if none */ @@ -265,7 +265,7 @@ if (!empty($_POST["DOL_AUTOSET_COOKIE"])) { $cookiename = $tmpautoset[0]; $cookievalue = json_encode($cookiearrayvalue); //var_dump('setcookie cookiename='.$cookiename.' cookievalue='.$cookievalue); - setcookie($cookiename, empty($cookievalue) ? '' : $cookievalue, empty($cookievalue) ? 0 : (time() + (86400 * 354)), '/', null, false, true); // keep cookie 1 year and add tag httponly + setcookie($cookiename, empty($cookievalue) ? '' : $cookievalue, empty($cookievalue) ? 0 : (time() + (86400 * 354)), '/', null, (empty($dolibarr_main_force_https) ? false : true), true); // keep cookie 1 year and add tag httponly if (empty($cookievalue)) { unset($_COOKIE[$cookiename]); } @@ -460,11 +460,15 @@ if (!defined('NOTOKENRENEWAL')) { if ((!defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && !empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN)) || defined('CSRFCHECK_WITH_TOKEN')) { // Array of action code where CSRFCHECK with token will be forced (so token must be provided on url request) $arrayofactiontoforcetokencheck = array( - 'activate', 'add', 'addtimespent', 'update', 'install', - 'confirm_create_user', 'confirm_create_thirdparty', 'confirm_purge', 'confirm_reject_check', - 'delete', 'deletefilter', 'deleteoperation', 'deleteprof', 'deletepayment', 'disable', + 'activate', 'add', 'addrights', 'addtimespent', + 'confirm_create_user', 'confirm_create_thirdparty', 'confirm_delete', 'confirm_deletedir', 'confirm_deletefile', 'confirm_purge', 'confirm_reject_check', + 'delete', 'deletefilter', 'deleteoperation', 'deleteprof', 'deletepayment', 'delrights', + 'disable', 'doprev', 'donext', 'dvprev', 'dvnext', - 'enable', 'setpricelevel' + 'enable', + 'install', + 'setpricelevel', + 'update' ); $sensitiveget = false; if (in_array(GETPOST('action', 'aZ09'), $arrayofactiontoforcetokencheck)) { diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 4633a69e6dd..1e319e18ec2 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -327,22 +327,21 @@ $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $objec $sql .= $hookmanager->resPrint; /* If a group by is required -$sql.= " GROUP BY "; -foreach($object->fields as $key => $val) -{ - $sql.='t.'.$key.', '; +$sql .= " GROUP BY "; +foreach($object->fields as $key => $val) { + $sql .= 't.'.$key.', '; } // Add fields from extrafields -if (! empty($extrafields->attributes[$object->table_element]['label'])) { +if (!empty($extrafields->attributes[$object->table_element]['label'])) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : ''); } } // Add where from hooks -$parameters=array(); -$reshook=$hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook -$sql.=$hookmanager->resPrint; -$sql=preg_replace('/,\s*$/','', $sql); +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; +$sql = preg_replace('/,\s*$/', '', $sql); */ $sql .= $db->order($sortfield, $sortorder); diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 5a83c685e0f..fa75a20277f 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -295,13 +295,14 @@ $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); print load_fiche_titre($langs->trans("ProductCodeChecker"), '', ''); +print '
    '; print ''."\n"; print ''."\n"; print ' '; print ' '; print ' '; print ' '; -print ' '; +print ' '; print "\n"; foreach ($dirproduct as $dirroot) { @@ -333,7 +334,7 @@ foreach ($dirproduct as $dirroot) { print ''."\n"; print ''."\n"; print ''."\n"; - print ''."\n"; + print ''."\n"; if (!empty($conf->global->PRODUCT_CODEPRODUCT_ADDON) && $conf->global->PRODUCT_CODEPRODUCT_ADDON == $file) { print '
    '.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Example").''.$langs->trans("Status").''.$langs->trans("ShortInfo").'
    '.$modCodeProduct->name.''.$modCodeProduct->info($langs).''.$modCodeProduct->getExample($langs).''.$modCodeProduct->getExample($langs).''."\n"; @@ -366,6 +367,7 @@ foreach ($dirproduct as $dirroot) { } } print '
    '; +print '
    '; // Module to build doc $def = array(); @@ -390,13 +392,14 @@ print '
    '; print load_fiche_titre($langs->trans("ProductDocumentTemplates"), '', ''); +print '
    '; print ''; print ''; print ''; print ''; print '\n"; print '\n"; -print ''; +print ''; print ''; print "\n"; @@ -499,6 +502,8 @@ foreach ($dirmodels as $reldir) { } print '
    '.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."'.$langs->trans("Default")."'.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
    '; +print '
    '; + print "
    "; /* @@ -517,6 +522,7 @@ print ''; print load_fiche_titre($langs->trans("ProductOtherConf"), '', ''); +print '
    '; print ''; print ''; print ''."\n"; @@ -611,6 +617,7 @@ if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SU } print '
    '.$langs->trans("Parameters").'
    '; +print '
    '; print '
    '; print ''; @@ -620,6 +627,7 @@ print '
    '; print load_fiche_titre($langs->trans("UserInterface"), '', ''); +print '
    '; print ''; print ''; print ''."\n"; @@ -671,7 +679,7 @@ print $form->selectarray( 0, 0, '', - 'maxwidth400', + 'minwidth100imp maxwidth400', 1 ); print ''; @@ -772,6 +780,7 @@ if (!empty($conf->global->PRODUCT_CANVAS_ABILITY)) { } print '
    '.$langs->trans("Parameters").'
    '; +print '
    '; print '
    '; print ''; 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; diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php index e1250f10cb3..e2539dae31c 100644 --- a/htdocs/product/composition/card.php +++ b/htdocs/product/composition/card.php @@ -51,6 +51,9 @@ if (!empty($user->socid)) { $fieldvalue = (!empty($id) ? $id : (!empty($ref) ? $ref : '')); $fieldtype = (!empty($ref) ? 'ref' : 'rowid'); +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('productcompositioncard', 'globalcard')); + $object = new Product($db); $objectid = 0; if ($id > 0 || !empty($ref)) { diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 85cd0932f46..01968855836 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -449,7 +449,7 @@ if ($object->id > 0) { print dol_get_fiche_end(); - print '
    '; + print ''; print ''; print ''; print ''; @@ -537,11 +537,116 @@ if ($object->id > 0) { // Popup for mass barcode scanning if ($action == 'updatebyscaning') { + if ($permissiontoadd) { + print ''; + } include DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; $formother = new FormOther($db); print $formother->getHTMLScannerForm(); } + //Call method to undo changes in real qty + print ''; print '
    '; //print '
    '; @@ -639,15 +744,15 @@ if ($object->id > 0) { } print ''; - print ''; + print ''; print $warehouse_static->getNomUrl(1); print ''; - print ''; + print ''; print $product_static->getNomUrl(1); print ''; if ($conf->productbatch->enabled) { - print ''; + print ''; print $obj->batch; print ''; } @@ -665,8 +770,11 @@ if ($object->id > 0) { print ''; print ''; print ''; + print '  '; print ''.img_delete().''; print ''; + $qty_tmp = price2num(GETPOST("id_".$obj->rowid."_input_tmp", 'MS')) >= 0 ? GETPOST("id_".$obj->rowid."_input_tmp") : $qty_view; + print ''; } else { print $obj->qty_view; $totalfound += $obj->qty_view; @@ -685,7 +793,7 @@ if ($object->id > 0) { print '
    '; if ($object->status == $object::STATUS_VALIDATED) { - print '
    '; + print '
    '; } print '
    '; diff --git a/htdocs/product/price.php b/htdocs/product/price.php index aad0311502d..bb46839e588 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -1108,34 +1108,41 @@ print dol_get_fiche_end(); /* * Action bar */ + + if (!$action || $action == 'delete' || $action == 'showlog_customer_price' || $action == 'showlog_default_price' || $action == 'add_customer_price' || $action == 'activate_price_by_qty' || $action == 'disable_price_by_qty') { print "\n".'
    '."\n"; - if ($object->isVariant()) { - if ($user->rights->produit->creer || $user->rights->service->creer) { - print ''; - } - } else { - if (empty($conf->global->PRODUIT_MULTIPRICES) && empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { - if ($user->rights->produit->creer || $user->rights->service->creer) { - print ''; - } - } - if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been + if (empty($reshook)) { + if ($object->isVariant()) { if ($user->rights->produit->creer || $user->rights->service->creer) { - print ''; + print ''; } - } - - if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { - if ($user->rights->produit->creer || $user->rights->service->creer) { - print ''; + } else { + if (empty($conf->global->PRODUIT_MULTIPRICES) && empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { + if ($user->rights->produit->creer || $user->rights->service->creer) { + print ''; + } } - if ($user->rights->produit->creer || $user->rights->service->creer) { - print ''; + if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { + if ($user->rights->produit->creer || $user->rights->service->creer) { + print ''; + } + } + + if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { + if ($user->rights->produit->creer || $user->rights->service->creer) { + print ''; + } + + if ($user->rights->produit->creer || $user->rights->service->creer) { + print ''; + } } } } diff --git a/htdocs/product/stats/card.php b/htdocs/product/stats/card.php index 6929c70a5ff..3e7d9045dc8 100644 --- a/htdocs/product/stats/card.php +++ b/htdocs/product/stats/card.php @@ -59,6 +59,9 @@ if (!empty($user->socid)) { $fieldvalue = (!empty($id) ? $id : $ref); $fieldtype = (!empty($ref) ? 'ref' : 'rowid'); +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('productstatscard', 'globalcard')); + $tmp = dol_getdate(dol_now()); $currentyear = $tmp['year']; if (empty($search_year)) { diff --git a/htdocs/product/stock/class/productlot.class.php b/htdocs/product/stock/class/productlot.class.php index 52322cf4697..360978ac736 100644 --- a/htdocs/product/stock/class/productlot.class.php +++ b/htdocs/product/stock/class/productlot.class.php @@ -402,7 +402,7 @@ class Productlot extends CommonObject $sql .= ' sellby = '.(!isset($this->sellby) || dol_strlen($this->sellby) != 0 ? "'".$this->db->idate($this->sellby)."'" : 'null').','; $sql .= ' eol_date = '.(!isset($this->eol_date) || dol_strlen($this->eol_date) != 0 ? "'".$this->db->idate($this->eol_date)."'" : 'null').','; $sql .= ' manufacturing_date = '.(!isset($this->manufacturing_date) || dol_strlen($this->manufacturing_date) != 0 ? "'".$this->db->idate($this->manufacturing_date)."'" : 'null').','; - $sql .= ' scrapping_date = '.(!isset($this->destruction_date) || dol_strlen($this->destruction_date) != 0 ? "'".$this->db->idate($this->destruction_date)."'" : 'null').','; + $sql .= ' scrapping_date = '.(!isset($this->scrapping_date) || dol_strlen($this->scrapping_date) != 0 ? "'".$this->db->idate($this->scrapping_date)."'" : 'null').','; //$sql .= ' commissionning_date = '.(!isset($this->first_use_date) || dol_strlen($this->first_use_date) != 0 ? "'".$this->db->idate($this->first_use_date)."'" : 'null').','; //$sql .= ' qc_frequency = '.(!isset($this->qc_frequency) || dol_strlen($this->qc_frequency) != 0 ? "'".$this->db->escape($this->qc_frequency)."'" : 'null').','; $sql .= ' datec = '.(!isset($this->datec) || dol_strlen($this->datec) != 0 ? "'".$this->db->idate($this->datec)."'" : 'null').','; 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 { diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php index 58e5bd055f1..78a18ca960b 100644 --- a/htdocs/product/stock/productlot_list.php +++ b/htdocs/product/stock/productlot_list.php @@ -1,6 +1,6 @@ - * Copyright (C) 2018 Ferran Marcet + * Copyright (C) 2018-2021 Ferran Marcet * Copyright (C) 2019 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -299,7 +299,7 @@ if (is_numeric($nbtotalofrecords) && ($limit > $nbtotalofrecords || empty($limit if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) { $obj = $db->fetch_object($resql); $id = $obj->rowid; - header("Location: ".dol_buildpath('/mymodule/myobject_card.php', 1).'?id='.$id); + header("Location: ".DOL_URL_ROOT.'/product/stock/productlot_card.php?id='.$id); exit; } 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 '
    '; diff --git a/htdocs/projet/ajax/projects.php b/htdocs/projet/ajax/projects.php index 5264fa02596..d933e6f55a0 100644 --- a/htdocs/projet/ajax/projects.php +++ b/htdocs/projet/ajax/projects.php @@ -82,7 +82,7 @@ if (empty($mode) || $mode != 'gettasks') { // Mode to get list of tasks if ($mode == '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; } diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 3c2d5b02829..b14fcfc73fd 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -89,6 +89,8 @@ $socid = GETPOST('socid', 'int'); //if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignement. restrictedArea($user, 'projet', $object->id, 'projet&project'); +$permissiondellink = $user->rights->projet->creer; // Used by the include of actions_dellink.inc.php + /* * Actions @@ -121,6 +123,8 @@ if (empty($reshook)) { $action = ''; } + include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once + if ($action == 'add' && $user->rights->projet->creer) { $error = 0; if (!GETPOST('ref')) { @@ -132,9 +136,11 @@ if (empty($reshook)) { $error++; } - if (GETPOST('opp_amount') != '' && !(GETPOST('opp_status') > 0)) { - $error++; - setEventMessages($langs->trans("ErrorOppStatusRequiredIfAmount"), null, 'errors'); + if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { + if (GETPOST('opp_amount') != '' && !(GETPOST('opp_status') > 0)) { + $error++; + setEventMessages($langs->trans("ErrorOppStatusRequiredIfAmount"), null, 'errors'); + } } // Create with status validated immediatly @@ -270,9 +276,11 @@ if (empty($reshook)) { } } - if ($object->opp_amount && ($object->opp_status <= 0)) { - $error++; - setEventMessages($langs->trans("ErrorOppStatusRequiredIfAmount"), null, 'errors'); + if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { + if ($object->opp_amount && ($object->opp_status <= 0)) { + $error++; + setEventMessages($langs->trans("ErrorOppStatusRequiredIfAmount"), null, 'errors'); + } } if (!$error) { @@ -511,7 +519,7 @@ if ($action == 'create' && $user->rights->projet->creer) { // Ref $suggestedref = (GETPOST("ref") ? GETPOST("ref") : $defaultref); - print ''.$langs->trans("Ref").''; + print ''.$langs->trans("Ref").''; print ' '.$form->textwithpicto('', $langs->trans("YouCanCompleteRef", $suggestedref)); print ''; @@ -796,7 +804,7 @@ if ($action == 'create' && $user->rights->projet->creer) { // Ref $suggestedref = $object->ref; print ''.$langs->trans("Ref").''; - print ''; + print ''; print ' '.$form->textwithpicto('', $langs->trans("YouCanCompleteRef", $suggestedref)); print ''; diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index a570e8ed7bb..4f52dd48057 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -744,7 +744,8 @@ class Project extends CommonObject 'datefieldname' => $datefieldname, 'dates' => $dates, 'datee' => $datee, - 'fk_projet' => $projectkey + 'fk_projet' => $projectkey, + 'ids' => $ids, ); $reshook = $hookmanager->executeHooks('getElementList', $parameters, $object, $action); if ($reshook > 0) { diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 0e7377f8751..0947ae5da1d 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -1535,7 +1535,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0) { $totalarray['nbfield']++; } } - } else { + } elseif ($action !== 'createtime') { print ''; } diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index ab8e925d4f5..5a7340bbe34 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -1136,6 +1136,8 @@ if ($ispaymentok) { if ($resultattendee < 0) { setEventMessages(null, $attendeetovalidate->errors, "errors"); } else { + $attendeetovalidate->amount=$FinalPaymentAmt; + $attendeetovalidate->update($user); $attendeetovalidate->validate($user); // Sending mail @@ -1156,8 +1158,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) { @@ -1171,7 +1174,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"]; @@ -1338,7 +1341,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"; diff --git a/htdocs/public/ticket/create_ticket.php b/htdocs/public/ticket/create_ticket.php index 1d0339f83f8..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').'

    '; @@ -390,7 +389,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); 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/recruitment/class/recruitmentjobposition.class.php b/htdocs/recruitment/class/recruitmentjobposition.class.php index 2f180bcc8ec..892ba4121e9 100644 --- a/htdocs/recruitment/class/recruitmentjobposition.class.php +++ b/htdocs/recruitment/class/recruitmentjobposition.class.php @@ -101,13 +101,13 @@ class RecruitmentJobPosition extends CommonObject public $fields = array( 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"), 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'position'=>5, 'notnull'=>1, 'default'=>'1', 'index'=>1), - 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>4, 'noteditable'=>'1', 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object"), + 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>4, 'noteditable'=>'1', 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object", 'css'=>'nowraponall'), 'label' => array('type'=>'varchar(255)', 'label'=>'JobLabel', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth500', 'csslist'=>'tdoverflowmax300', 'showoncombobox'=>'2', 'autofocusoncreate'=>1), 'qty' => array('type'=>'integer', 'label'=>'NbOfEmployeesExpected', 'enabled'=>'1', 'position'=>45, 'notnull'=>1, 'visible'=>1, 'default'=>'1', 'isameasure'=>'1', 'css'=>'maxwidth75imp'), 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'enabled'=>'1', 'position'=>52, 'notnull'=>-1, 'visible'=>-1, 'index'=>1, 'css'=>'maxwidth500', 'picto'=>'project'), - 'fk_user_recruiter' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ResponsibleOfRecruitement', 'enabled'=>'1', 'position'=>54, 'notnull'=>1, 'visible'=>1, 'foreignkey'=>'user.rowid', 'csslist'=>'tdoverflowmax150'), + 'fk_user_recruiter' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ResponsibleOfRecruitement', 'enabled'=>'1', 'position'=>54, 'notnull'=>1, 'visible'=>1, 'foreignkey'=>'user.rowid', 'css'=>'maxwidth500', 'csslist'=>'tdoverflowmax150', 'picto'=>'user'), 'email_recruiter' => array('type'=>'varchar(255)', 'label'=>'EmailRecruiter', 'enabled'=>'1', 'position'=>54, 'notnull'=>0, 'visible'=>-1, 'help'=>'ToUseAGenericEmail', 'picto'=>'email'), - 'fk_user_supervisor' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'FutureManager', 'enabled'=>'1', 'position'=>55, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'user.rowid',), + 'fk_user_supervisor' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'FutureManager', 'enabled'=>'1', 'position'=>55, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'user.rowid', 'css'=>'maxwidth500', 'csslist'=>'tdoverflowmax150', 'picto'=>'user'), 'fk_establishment' => array('type'=>'integer:Establishment:hrm/class/establishment.class.php', 'label'=>'Establishment', 'enabled'=>'$conf->hrm->enabled', 'position'=>56, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'establishment.rowid',), 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'WorkPlace', 'enabled'=>'1', 'position'=>57, 'notnull'=>-1, 'visible'=>-1, 'css'=>'maxwidth500', 'index'=>1, 'help'=>"IfJobIsLocatedAtAPartner", 'picto'=>'company'), 'date_planned' => array('type'=>'date', 'label'=>'DateExpected', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>1,), diff --git a/htdocs/recruitment/recruitmentjobposition_list.php b/htdocs/recruitment/recruitmentjobposition_list.php index 7ccad1de16a..3398a47dca3 100644 --- a/htdocs/recruitment/recruitmentjobposition_list.php +++ b/htdocs/recruitment/recruitmentjobposition_list.php @@ -103,8 +103,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; @@ -123,6 +124,7 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen // Default sort order (if not yet defined by previous GETPOST) if (!$sortfield) { + reset($object->fields); // Reset is required to avoid key() to return null. $sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition. } if (!$sortorder) { @@ -146,17 +148,18 @@ foreach ($object->fields as $key => $val) { } } -// 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'])) { - $visible = dol_eval($val['visible'], 1); + $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'] + 'position'=>$val['position'], + 'help'=> isset($val['help']) ? $val['help'] : '' ); } } @@ -164,7 +167,7 @@ foreach ($object->fields as $key => $val) { include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; $object->fields = dol_sort_array($object->fields, 'position'); -$arrayfields['nbapplications'] = array('label'=>'Applications', 'checked'=>1, 'enabled'=>1, 'position'=>90); +$arrayfields['nbapplications'] = array('type'=>'integer', 'label'=>'Applications', 'checked'=>1, 'enabled'=>1, 'position'=>90, 'csslist'=>'right'); $arrayfields = dol_sort_array($arrayfields, 'position'); $permissiontoread = $user->rights->recruitment->recruitmentjobposition->read; @@ -184,7 +187,8 @@ $result = restrictedArea($user, 'recruitment', 0, 'recruitment_recruitmentjobpos */ if (GETPOST('cancel', 'alpha')) { - $action = 'list'; $massaction = ''; + $action = 'list'; + $massaction = ''; } if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction = ''; @@ -238,13 +242,11 @@ $title = $langs->trans('ListOfPositionsToBeFilled'); // Build and execute select // -------------------------------------------------------------------- $sql = 'SELECT '; -foreach ($object->fields as $key => $val) { - $sql .= 't.'.$key.', '; -} +$sql .= $object->getFieldList('t'); // Add fields from extrafields if (!empty($extrafields->attributes[$object->table_element]['label'])) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { - $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.' as options_'.$key.', ' : ''); + $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key.' as options_'.$key.', ' : ''); } } // Add fields from hooks @@ -258,24 +260,42 @@ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."recruitment_recruitmentcandidature as rc O if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; } +// Add table from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; if ($object->ismultientitymanaged == 1) { $sql .= " WHERE t.entity IN (".getEntity($object->element).")"; } else { $sql .= " WHERE 1 = 1"; } foreach ($search as $key => $val) { - if ($key == 'status' && $search[$key] == -1) { - continue; - } - $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); - if (strpos($object->fields[$key]['type'], 'integer:') === 0) { - if ($search[$key] == '-1') { - $search[$key] = ''; + if (array_key_exists($key, $object->fields)) { + if ($key == 'status' && $search[$key] == -1) { + continue; + } + $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); + if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) { + if ($search[$key] == '-1' || $search[$key] === '0') { + $search[$key] = ''; + } + $mode_search = 2; + } + if ($search[$key] != '') { + $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); + } + } else { + if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') { + $columnName=preg_replace('/(_dtstart|_dtend)$/', '', $key); + if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) { + if (preg_match('/_dtstart$/', $key)) { + $sql .= " AND t." . $columnName . " >= '" . $db->idate($search[$key]) . "'"; + } + if (preg_match('/_dtend$/', $key)) { + $sql .= " AND t." . $columnName . " <= '" . $db->idate($search[$key]) . "'"; + } + } } - $mode_search = 2; - } - if ($search[$key] != '') { - $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); } } if ($search_all) { @@ -372,6 +392,10 @@ if ($optioncss != '') { } // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; +// Add $param from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook +$param .= $hookmanager->resPrint; // List of mass actions available $arrayofmassactions = array( @@ -449,30 +473,38 @@ print ''; foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['css']) ? '' : $val['css']); + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); if ($key == 'status') { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') { + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } if (!empty($arrayfields['t.'.$key]['checked'])) { print ''; } } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; + // Fields from hook $parameters = array('arrayfields'=>$arrayfields); $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook @@ -492,14 +524,14 @@ print ''."\n"; // -------------------------------------------------------------------- print ''; foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['css']) ? '' : $val['css']); + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); if ($key == 'status') { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') { + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } if (!empty($arrayfields['t.'.$key]['checked'])) { @@ -513,7 +545,7 @@ $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$ $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; if (!empty($arrayfields['nbapplications']['checked'])) { - print ''; + print ''; } // Action column print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; @@ -561,7 +593,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; } - if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $key != 'status') { + if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100'; @@ -570,6 +602,8 @@ while ($i < ($limit ? min($num, $limit) : $num)) { print ''; if ($key == 'status') { print $object->getLibStatut(5); + } elseif ($key == 'rowid') { + print $object->showOutputField($val, $key, $object->id, ''); } else { print $object->showOutputField($val, $key, $object->$key, ''); } @@ -602,7 +636,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { } // Action column print ''; $thirdpartycateggraph .= '
    '; if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); - } elseif (strpos($val['type'], 'integer:') === 0) { - print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', 'maxwidth150', 1); - } elseif (!preg_match('/^(date|timestamp)/', $val['type'])) { + } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) { + print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', 'maxwidth125', 1); + } elseif (!preg_match('/^(date|timestamp|datetime)/', $val['type'])) { print ''; + } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + print '
    '; + print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
    '; + print '
    '; + print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + print '
    '; } print '
    '.$langs->trans("Applications").''.$langs->trans("Applications").''; - if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined $selected = 0; if (in_array($object->id, $arrayofselected)) { $selected = 1; 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; 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/class/societe.class.php b/htdocs/societe/class/societe.class.php index eff2ba39c21..dc074c817f8 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2019 Laurent Destailleur + * Copyright (C) 2004-2021 Laurent Destailleur * Copyright (C) 2004 Eric Seigne * Copyright (C) 2003 Brian Fraval * Copyright (C) 2006 Andre Cianfarani @@ -1280,7 +1280,8 @@ class Societe extends CommonObject $this->get_codefournisseur($this, 1); } - $this->code_compta = trim($this->code_compta); + $this->code_compta_client = trim(empty($this->code_compta) ? $this->code_compta_client : $this->code_compta); + $this->code_compta = $this->code_compta_client; // for backward compatbility $this->code_compta_fournisseur = trim($this->code_compta_fournisseur); // Check parameters. More tests are done later in the ->verify() @@ -1292,8 +1293,8 @@ class Societe extends CommonObject $customer = false; if (!empty($allowmodcodeclient) && !empty($this->client)) { - // Attention get_codecompta peut modifier le code suivant le module utilise - if (empty($this->code_compta)) { + // If $allowmodcodeclient is set and value is not set, we generate it + if (empty($this->code_compta_client)) { $ret = $this->get_codecompta('customer'); if ($ret < 0) { return -1; @@ -1305,8 +1306,8 @@ class Societe extends CommonObject $supplier = false; if (!empty($allowmodcodefournisseur) && !empty($this->fournisseur)) { - // Attention get_codecompta peut modifier le code suivant le module utilise - if ($this->code_compta_fournisseur == "") { + // If $allowmodcodefournisseur is set and value is not set, we generate it + if (empty($this->code_compta_fournisseur)) { $ret = $this->get_codecompta('supplier'); if ($ret < 0) { return -1; @@ -1460,7 +1461,7 @@ class Societe extends CommonObject if ($customer) { $sql .= ", code_client = ".(!empty($this->code_client) ? "'".$this->db->escape($this->code_client)."'" : "null"); - $sql .= ", code_compta = ".(!empty($this->code_compta) ? "'".$this->db->escape($this->code_compta)."'" : "null"); + $sql .= ", code_compta = ".(!empty($this->code_compta_client) ? "'".$this->db->escape($this->code_compta_client)."'" : "null"); } if ($supplier) { @@ -3311,7 +3312,8 @@ class Societe extends CommonObject $result = $mod->get_code($this->db, $this, $type); if ($type == 'customer') { - $this->code_compta = $mod->code; + $this->code_compta_client = $mod->code; + $this->code_compta = $this->code_compta_client; // For backward compatibility } elseif ($type == 'supplier') { $this->code_compta_fournisseur = $mod->code; } @@ -3323,6 +3325,7 @@ class Societe extends CommonObject } } else { if ($type == 'customer') { + $this->code_compta_client = ''; $this->code_compta = ''; } elseif ($type == 'supplier') { $this->code_compta_fournisseur = ''; @@ -4262,21 +4265,6 @@ class Societe extends CommonObject return $lib; } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Set prospect level - * - * @param User $user User who sets the discount - * @return int <0 if KO, >0 if OK - * @deprecated Use update function instead - */ - public function set_prospect_level(User $user) - { - // phpcs:enable - return $this->update($this->id, $user); - } - /** * Return status of prospect * @@ -4356,20 +4344,6 @@ class Societe extends CommonObject return "Error, mode/status not found"; } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Set outstanding value - * - * @param User $user User making change - * @return int <0 if KO, >0 if OK - * @deprecated Use update function instead - */ - public function set_OutstandingBill(User $user) - { - // phpcs:enable - return $this->update($this->id, $user); - } - /** * Return amount of order not paid and total * diff --git a/htdocs/societe/index.php b/htdocs/societe/index.php index 14901dc8a9c..30d49e55c2b 100644 --- a/htdocs/societe/index.php +++ b/htdocs/societe/index.php @@ -251,6 +251,8 @@ if (!empty($conf->categorie->enabled) && !empty($conf->global->CATEGORY_GRAPHSTA $thirdpartycateggraph .= '
    '; $thirdpartycateggraph .= '
    '; +} else { + $thirdpartycateggraph = ''; } diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 6835794e916..cdbacd5ffca 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -94,7 +94,7 @@ $search_categ_cus = trim(GETPOST("search_categ_cus", 'int')); $search_categ_sup = trim(GETPOST("search_categ_sup", 'int')); $search_country = GETPOST("search_country", 'intcomma'); $search_type_thirdparty = GETPOST("search_type_thirdparty", 'int'); -$search_price_level = GETPOST('search_prive_level', 'int'); +$search_price_level = GETPOST('search_price_level', 'int'); $search_staff = GETPOST("search_staff", 'int'); $search_status = GETPOST("search_status", 'int'); $search_type = GETPOST('search_type', 'alpha'); @@ -356,7 +356,7 @@ if (empty($reshook)) { $search_idprof6 = ''; $search_vat = ''; $search_type = ''; - $search_prive_level = ''; + $search_price_level = ''; $search_type_thirdparty = ''; $search_staff = ''; $search_status = -1; @@ -639,8 +639,8 @@ if ($search_status != '' && $search_status >= 0) { if (!empty($conf->barcode->enabled) && $search_barcode) { $sql .= natural_search("s.barcode", $search_barcode); } -if ($search_prive_level && $search_prive_level != '-1') { - $sql .= natural_search("s.price_level", $search_prive_level, 2); +if ($search_price_level && $search_price_level != '-1') { + $sql .= natural_search("s.price_level", $search_price_level, 2); } if ($search_type_thirdparty && $search_type_thirdparty > 0) { $sql .= natural_search("s.fk_typent", $search_type_thirdparty, 2); @@ -654,8 +654,8 @@ if ($search_level) { 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') { // -2 is not filter + $sql .= natural_search("s.fk_stcomm", $search_stcomm, 1); } if ($search_import_key) { $sql .= natural_search("s.import_key", $search_import_key); @@ -813,8 +813,8 @@ if ($search_idprof6 != '') { if ($search_vat != '') { $param .= '&search_vat='.urlencode($search_vat); } -if ($search_prive_level != '') { - $param .= '&search_prive_level='.urlencode($search_prive_level); +if ($search_price_level != '') { + $param .= '&search_price_level='.urlencode($search_price_level); } if ($search_type_thirdparty != '' && $search_type_thirdparty > 0) { $param .= '&search_type_thirdparty='.urlencode($search_type_thirdparty); @@ -830,7 +830,7 @@ if (is_array($search_level) && count($search_level)) { if ($search_status != '') { $param .= '&search_status='.urlencode($search_status); } -if ($search_stcomm != '') { +if ($search_stcomm != '' && $search_stcomm != '-2') { // -2 is no filter $param .= '&search_stcomm='.urlencode($search_stcomm); } if ($search_parent_name != '') { @@ -1100,7 +1100,7 @@ if (!empty($arrayfields['typent.code']['checked'])) { // Multiprice level if (!empty($arrayfields['s.price_level']['checked'])) { print ''; - print ''; + print ''; print ''; } // Staff 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 ''.$langs->trans("RUM").''; print ''; + $date_rum = dol_mktime(0, 0, 0, GETPOST('date_rummonth'), GETPOST('date_rumday'), GETPOST('date_rumyear')); + print ''.$langs->trans("DateRUM").''; - print ''.$form->selectDate(GETPOST('date_rum') ?GETPOST('date_rum') : $companybankaccount->date_rum, 'date_rum', 0, 0, 1, 'date_rum').''; + print ''.$form->selectDate($date_rum ? $date_rum : $companybankaccount->date_rum, 'date_rum', 0, 0, 1, 'date_rum', 1, 1).''; print ''.$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").''; print '
    '.$langs->trans("RUMWillBeGenerated").'
    '; + $date_rum = dol_mktime(0, 0, 0, GETPOST('date_rummonth'), GETPOST('date_rumday'), GETPOST('date_rumyear')); + print ''.$langs->trans("DateRUM").''; - print ''.$form->selectDate(GETPOST('date_rum'), 'date_rum', 0, 0, 1, 'date_rum').''; + print ''.$form->selectDate($date_rum, 'date_rum', 0, 0, 1, 'date_rum', 1, 1).''; print ''.$langs->trans("WithdrawMode").''; $tblArraychoice = array("FRST" => $langs->trans("FRST"), "RECUR" => $langs->trans("RECUR")); diff --git a/htdocs/societe/project.php b/htdocs/societe/project.php index 038ed7350d5..c6256324257 100644 --- a/htdocs/societe/project.php +++ b/htdocs/societe/project.php @@ -136,7 +136,7 @@ if ($socid) { $params = ''; $backtopage = $_SERVER['PHP_SELF'].'?socid='.$object->id; - $newcardbutton = dolGetButtonTitle($langs->trans("NewProject"), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/projet/card.php?action=create&socid='.$object->id.'&backtopage='.urlencode($backtopage), '', 1, $params); + $newcardbutton = dolGetButtonTitle($langs->trans("NewProject"), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/projet/card.php?action=create&socid='.$object->id.'&backtopageforcancel='.urlencode($backtopage), '', 1, $params); print '
    '; diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index 1ddab39dcbe..e7b8b8af438 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -67,7 +67,7 @@ if ($_SESSION["takeposterminal"] == "") { if ($setterminal > 0) { $_SESSION["takeposterminal"] = $setterminal; - setcookie("takeposterminal", $setterminal, (time() + (86400 * 354)), '/', null, false, true); // Permanent takeposterminal var in a cookie + setcookie("takeposterminal", $setterminal, (time() + (86400 * 354)), '/', null, (empty($dolibarr_main_force_https) ? false : true), true); // Permanent takeposterminal var in a cookie } if ($setcurrency != "") { diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php index 5faa7b201b7..8a11ac23e23 100644 --- a/htdocs/ticket/card.php +++ b/htdocs/ticket/card.php @@ -31,6 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; if (!empty($conf->projet->enabled)) { include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; include_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; @@ -187,6 +188,11 @@ if (empty($reshook)) { $object->email_from = $user->email; $notifyTiers = GETPOST("notify_tiers_at_create", 'alpha'); $object->notify_tiers_at_create = empty($notifyTiers) ? 0 : 1; + $fk_user_assign = GETPOST("fk_user_assign", 'int'); + if ($fk_user_assign > 0) { + $object->fk_user_assign = $fk_user_assign; + $object->fk_statut = $object::STATUS_ASSIGNED; + } $object->fk_project = $projectid; @@ -202,6 +208,10 @@ if (empty($reshook)) { $contactid = GETPOST('contactid', 'int'); $type_contact = GETPOST("type", 'alpha'); + // Category association + $categories = GETPOST('categories', 'array'); + $object->setCategories($categories); + if ($contactid > 0 && $type_contact) { $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type')); $result = $object->add_contact($contactid, $typeid, 'external'); @@ -312,7 +322,11 @@ if (empty($reshook)) { $object->severity_code = GETPOST('severity_code', 'alpha'); $ret = $object->update($user); - if ($ret <= 0) { + if ($ret > 0) { + // Category association + $categories = GETPOST('categories', 'array'); + $object->setCategories($categories); + } else { $error++; } @@ -426,10 +440,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'); @@ -473,7 +487,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'); @@ -749,7 +763,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 +778,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); @@ -1054,6 +1075,13 @@ if ($action == 'create' || $action == 'presend') { print ''; } + // Categories + if ($conf->categorie->enabled) { + print ''.$langs->trans("Categories").''; + print $form->showCategories($object->id, Categorie::TYPE_TICKET, 1); + print ""; + } + // Other attributes include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; @@ -1119,15 +1147,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 @@ -1296,8 +1330,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/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 ''; diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 5bd8ec05864..e8a1b53ed82 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'=>'$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), ); // END MODULEBUILDER PROPERTIES @@ -286,6 +286,8 @@ class Ticket extends CommonObject */ public function __construct($db) { + global $conf; + $this->db = $db; $this->statuts_short = array( @@ -295,7 +297,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 +307,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' ); } @@ -459,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)."'").","; @@ -1749,21 +1751,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; diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index 84ea65fef71..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 @@ -798,7 +808,7 @@ foreach ($object->fields as $key => $val) { if (!empty($search[$key])) { $selectedarray = array_values($search[$key]); } - print Form::multiselectarray('search_fk_statut', $arrayofstatus, $selectedarray, 0, 0, 'minwidth100 maxwidth150', 1, 0, '', '', ''); + print Form::multiselectarray('search_fk_statut', $arrayofstatus, $selectedarray, 0, 0, 'minwidth100imp maxwidth150', 1, 0, '', '', ''); print ''; } elseif ($key == "fk_soc") { print ''; diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 152c39f79ac..cb7aa69949c 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -314,8 +314,8 @@ if (empty($reshook)) { $id = $object->create($user); if ($id > 0) { - if (GETPOST('password')) { - $object->setPassword($user, GETPOST('password')); + if (GETPOST('password', 'none')) { + $object->setPassword($user, GETPOST('password', 'none')); } if (!empty($conf->categorie->enabled)) { // Categories association @@ -1437,7 +1437,7 @@ if ($action == 'create' || $action == 'adduserldap') { } // Employee - print ''.$langs->trans("Employee").''; + print ''.$langs->trans("Employee").''; print 'employee ? ' checked="checked"' : '').'>'; //print yn($object->employee); print ''."\n"; @@ -1803,7 +1803,7 @@ if ($action == 'create' || $action == 'adduserldap') { print dol_print_date($object->datepreviouslogin, "dayhour").' ('.$langs->trans("Previous").'), '; } if ($object->datelastlogin) { - print dol_print_date($object->datelastlogin, "dayhour").' ('.$langs->trans("Current").')'; + print dol_print_date($object->datelastlogin, "dayhour").' ('.$langs->trans("Currently").')'; } print ''; print "\n"; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 74137537e74..816d3dc3e27 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1280,6 +1280,10 @@ class User extends CommonObject $langs->load("errors"); $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Login")); return -1; + } elseif (preg_match('/[,@<>"\']/', $this->login)) { + $langs->load("errors"); + $this->error = $langs->trans("ErrorBadCharIntoLoginName"); + return -1; } $this->datec = dol_now(); @@ -1669,6 +1673,10 @@ class User extends CommonObject $langs->load("errors"); $this->error = $langs->trans("ErrorFieldRequired", 'Login'); return -1; + } elseif (preg_match('/[,@<>"\']/', $this->login)) { + $langs->load("errors"); + $this->error = $langs->trans("ErrorBadCharIntoLoginName"); + return -1; } $this->db->begin(); diff --git a/htdocs/user/group/perms.php b/htdocs/user/group/perms.php index 618d705bfcf..9fc4426ecac 100644 --- a/htdocs/user/group/perms.php +++ b/htdocs/user/group/perms.php @@ -235,9 +235,9 @@ if ($object->id > 0) { print ''.$langs->trans("Module").''; if ($caneditperms) { print ''; - print ''.$langs->trans("All").""; + print ''.$langs->trans("All").""; print '/'; - print ''.$langs->trans("None").""; + print ''.$langs->trans("None").""; print ''; } print ' '; @@ -286,9 +286,9 @@ if ($object->id > 0) { print ''; if ($caneditperms) { print ''; - print 'module.'">'.$langs->trans("All").""; + print 'module.'&token='.newToken().'">'.$langs->trans("All").""; print '/'; - print 'module.'">'.$langs->trans("None").""; + print 'module.'&token='.newToken().'">'.$langs->trans("None").""; print ''; } else { print ' '; @@ -326,7 +326,7 @@ if ($object->id > 0) { } else { // Do not own permission if ($caneditperms) { - print 'id.'">'; + print 'id.'&token='.newToken().'">'; //print img_edit_add($langs->trans("Add")); print img_picto($langs->trans("Add"), 'switch_off'); print ''; @@ -336,7 +336,7 @@ if ($object->id > 0) { } else { // Do not own permission if ($caneditperms) { - print 'id.'">'; + print 'id.'&token='.newToken().'">'; //print img_edit_add($langs->trans("Add")); print img_picto($langs->trans("Add"), 'switch_off'); print ''; 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); 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'; diff --git a/test/phpunit/HolidayTest.php b/test/phpunit/HolidayTest.php index 418b81f8b41..4fbd57c212b 100644 --- a/test/phpunit/HolidayTest.php +++ b/test/phpunit/HolidayTest.php @@ -366,6 +366,6 @@ class HolidayTest extends PHPUnit\Framework\TestCase $localobjecta->updateConfCP('lastUpdate', '20100101120000'); $result = $localobjecta->updateBalance(); - $this->assertEquals($result, 1); + $this->assertEquals($result, 0); } }