diff --git a/ChangeLog b/ChangeLog index 555258f3901..1a0a95aab9e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,6 +27,8 @@ NEW: A lot of addition of hooks. Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: +* There is a new specific permission to be allowed to enter timesheets. If you use timesheet, don't forget to give the new permission (disable and + enable the module project if it is not visible). * The default value for MAIN_SECURITY_CSRF_WITH_TOKEN has been set to 2. It means any POST and any GET request that contains the "action" or "massaction" with a value of a sensitive action must also a valid token parameter (With previous value 1, only POST was concerned). Note: With value 3, any URL with parameter "action" or "massaction" need the token, whatever is the value of the action. diff --git a/README.md b/README.md index 4e120a4cb91..5559613eaa2 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) - Customers/Prospects + Contacts management - Opportunities or Leads management -- Commercial proposals management +- Commercial proposals management (online signing) - Customer Orders management - Contracts/Subscription management - Interventions management @@ -129,11 +129,11 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) - Supplier Invoices/credit notes and payment management - INCOTERMS - Finance / Accounting + Finance/Accounting -- Invoices / Payments +- Invoices/Payments - Bank accounts management -- Direct debit orders management (European SEPA) +- Direct debit and Credit transfer management (European SEPA) - Accounting management - Donations management - Loan management @@ -142,14 +142,14 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) Collaboration -- Shared calendar/agenda (with ical and vcal export for third party tools integration) +- Shared calendar/agenda (with ical and vcal import/export for third party tools integration) - Projects & Tasks management - Ticket System - Surveys HR -- Employee's leave requests management +- Employee's leaves management - Expense reports - Recruitment management - Timesheets @@ -157,16 +157,14 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) ### Other application/modules - Electronic Document Management (EDM) -- Bookmarks management +- Bookmarks - Reporting - Data export/import - Barcodes -- Margin calculations - LDAP connectivity - ClickToDial integration - Mass emailing - RSS integration -- Skype integration - Social platforms linking - Payment platforms integration (PayPal, Stripe, Paybox...) - Email-Collector @@ -175,13 +173,12 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) ### Other general features -- Localization in most major languages -- Multi-Language Support +- Multi-Language Support (Localization in most major languages) - Multi-Users and groups with finely grained rights - Multi-Currency - Multi-Company (by adding of an external module) - Very user friendly and easy to use -- customizable Dashboard +- Customizable dashboards - Highly customizable: enable only the modules you need, add user personalized fields, choose your skin, several menu managers (can be used by internal users as a back-office with a particular menu, or by external users as a front-office with another one) - APIs (REST, SOAP) - Code that is easy to understand, maintain and develop (PHP with no heavy framework; trigger and hook architecture) @@ -191,8 +188,9 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) - Canadian double taxes (federal/province) and other countries using cumulative VAT - Tunisian tax stamp - Argentina invoice numbering using A,B,C... + - ZATCA e-invoicing QR-Code - Compatible with [European directives](https://europa.eu/legislation_summaries/taxation/l31057_en.htm) (2006/112/CE ... 2010/45/UE) - - Compatible with European GDPR rules + - Compatible with data privacy rules (europe GDPR, ...) - ... - Flexible PDF & ODT generation for invoices, proposals, orders... - ... @@ -244,6 +242,7 @@ Follow Dolibarr project on: - [Facebook](https://www.facebook.com/dolibarr) - [Twitter](https://www.twitter.com/dolibarr) - [LinkedIn](https://www.linkedin.com/company/association-dolibarr) +- [Reddit](https://www.reddit.com/r/Dolibarr_ERP_CRM/) - [YouTube](https://www.youtube.com/user/DolibarrERPCRM) - [GitHub](https://github.com/Dolibarr/dolibarr) diff --git a/htdocs/accountancy/admin/card.php b/htdocs/accountancy/admin/card.php index 91d8257ea7f..f2137d84af9 100644 --- a/htdocs/accountancy/admin/card.php +++ b/htdocs/accountancy/admin/card.php @@ -300,7 +300,7 @@ if ($action == 'create') { // Edit mode if ($action == 'update') { - print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), 0, 'billr'); + print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), 0, 'accounting_account'); print '
'."\n"; print ''; @@ -368,7 +368,7 @@ if ($action == 'create') { // View mode $linkback = ''.$langs->trans("BackToList").''; - print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), -1, 'billr'); + print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), -1, 'accounting_account'); dol_banner_tab($object, 'ref', $linkback, 1, 'account_number', 'ref'); diff --git a/htdocs/accountancy/admin/productaccount.php b/htdocs/accountancy/admin/productaccount.php index 8a8ca0ecf46..1a682636077 100644 --- a/htdocs/accountancy/admin/productaccount.php +++ b/htdocs/accountancy/admin/productaccount.php @@ -384,6 +384,7 @@ if ($search_onpurchase != '' && $search_onpurchase != '-1') { $sql .= " GROUP BY p.rowid, p.ref, p.label, p.description, p.tosell, p.tobuy, p.tva_tx,"; $sql .= " p.fk_product_type,"; $sql .= ' p.tms,'; +$sql .= ' aa.rowid,'; if (empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) { $sql .= " p.accountancy_code_sell, p.accountancy_code_sell_intra, p.accountancy_code_sell_export, p.accountancy_code_buy, p.accountancy_code_buy_intra, p.accountancy_code_buy_export"; } else { diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index bc7ea7c7072..ce0714d5651 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -304,7 +304,7 @@ if (empty($reshook)) { $search_lettering_code = ''; $search_not_reconciled = ''; $search_import_key = ''; - $toselect = ''; + $toselect = array(); } // Must be after the remove filter action, before the export. diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index cb8a2ee0517..80b2efe7050 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -259,7 +259,7 @@ if (empty($reshook)) { $search_lettering_code = ''; $search_not_reconciled = ''; $search_import_key = ''; - $toselect = ''; + $toselect = array(); } // Must be after the remove filter action, before the export. diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 9fa02f1c01b..c2ef4583bdc 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -215,7 +215,7 @@ if (empty($reshook)) { $search_status = ""; $catid = ""; $sall = ""; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php index aed531d86b4..d96adbc3b82 100644 --- a/htdocs/adherents/subscription/list.php +++ b/htdocs/adherents/subscription/list.php @@ -135,7 +135,7 @@ if (empty($reshook)) { $search_note = ""; $search_amount = ""; $search_account = ""; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } } diff --git a/htdocs/admin/defaultvalues.php b/htdocs/admin/defaultvalues.php index 58a72250d64..088c84de3f0 100644 --- a/htdocs/admin/defaultvalues.php +++ b/htdocs/admin/defaultvalues.php @@ -101,7 +101,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $defaulturl = ''; $defaultkey = ''; $defaultvalue = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index cd8ab4c1836..70768b1cf3f 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -209,7 +209,7 @@ $tabsql[8] = "SELECT t.id as rowid, t.code as code, t.libelle, t.fk_country as $tabsql[9] = "SELECT c.code_iso as code, c.label, c.unicode, c.active FROM ".MAIN_DB_PREFIX."c_currencies AS c"; $tabsql[10] = "SELECT t.rowid, t.code, t.taux, t.localtax1_type, t.localtax1, t.localtax2_type, t.localtax2, c.label as country, c.code as country_code, t.fk_pays as country_id, t.recuperableonly, t.note, t.active, t.accountancy_code_sell, t.accountancy_code_buy FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c WHERE t.fk_pays=c.rowid"; $tabsql[11] = "SELECT t.rowid as rowid, t.element, t.source, t.code, t.libelle, t.position, t.active FROM ".MAIN_DB_PREFIX."c_type_contact AS t"; -$tabsql[12] = "SELECT c.rowid as rowid, c.code, c.libelle, c.libelle_facture, c.nbjour, c.type_cdr, c.decalage, c.active, c.sortorder, c.entity FROM ".MAIN_DB_PREFIX."c_payment_term AS c WHERE c.entity = ".getEntity($tabname[12]); +$tabsql[12] = "SELECT c.rowid as rowid, c.code, c.libelle, c.libelle_facture, c.deposit_percent, c.nbjour, c.type_cdr, c.decalage, c.active, c.sortorder, c.entity FROM ".MAIN_DB_PREFIX."c_payment_term AS c WHERE c.entity = ".getEntity($tabname[12]); $tabsql[13] = "SELECT c.id as rowid, c.code, c.libelle, c.type, c.active, c.entity FROM ".MAIN_DB_PREFIX."c_paiement AS c WHERE c.entity = ".getEntity($tabname[13]); $tabsql[14] = "SELECT e.rowid as rowid, e.code as code, e.label, e.price, e.organization, e.fk_pays as country_id, c.code as country_code, c.label as country, e.active FROM ".MAIN_DB_PREFIX."c_ecotaxe AS e, ".MAIN_DB_PREFIX."c_country as c WHERE e.fk_pays=c.rowid and c.active=1"; $tabsql[15] = "SELECT rowid as rowid, code, label as libelle, width, height, unit, active FROM ".MAIN_DB_PREFIX."c_paper_format"; @@ -303,7 +303,7 @@ $tabfield[8] = "code,libelle,country_id,country".(!empty($conf->global->SOCIETE_ $tabfield[9] = "code,label,unicode"; $tabfield[10] = "country_id,country,code,taux,localtax1_type,localtax1,localtax2_type,localtax2,recuperableonly,accountancy_code_sell,accountancy_code_buy,note"; $tabfield[11] = "element,source,code,libelle,position"; -$tabfield[12] = "code,libelle,libelle_facture,nbjour,type_cdr,decalage,sortorder,entity"; +$tabfield[12] = "code,libelle,libelle_facture,deposit_percent,nbjour,type_cdr,decalage,sortorder,entity"; $tabfield[13] = "code,libelle,type,entity"; $tabfield[14] = "code,label,price,organization,country"; $tabfield[15] = "code,libelle,width,height,unit"; @@ -350,7 +350,7 @@ $tabfieldvalue[8] = "code,libelle,country".(!empty($conf->global->SOCIETE_SORT_O $tabfieldvalue[9] = "code,label,unicode"; $tabfieldvalue[10] = "country,code,taux,localtax1_type,localtax1,localtax2_type,localtax2,recuperableonly,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldvalue[11] = "element,source,code,libelle,position"; -$tabfieldvalue[12] = "code,libelle,libelle_facture,nbjour,type_cdr,decalage,sortorder"; +$tabfieldvalue[12] = "code,libelle,libelle_facture,deposit_percent,nbjour,type_cdr,decalage,sortorder"; $tabfieldvalue[13] = "code,libelle,type"; $tabfieldvalue[14] = "code,label,price,organization,country"; $tabfieldvalue[15] = "code,libelle,width,height,unit"; @@ -397,7 +397,7 @@ $tabfieldinsert[8] = "code,libelle,fk_country".(!empty($conf->global->SOCIETE_SO $tabfieldinsert[9] = "code_iso,label,unicode"; $tabfieldinsert[10] = "fk_pays,code,taux,localtax1_type,localtax1,localtax2_type,localtax2,recuperableonly,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldinsert[11] = "element,source,code,libelle,position"; -$tabfieldinsert[12] = "code,libelle,libelle_facture,nbjour,type_cdr,decalage,sortorder,entity"; +$tabfieldinsert[12] = "code,libelle,libelle_facture,deposit_percent,nbjour,type_cdr,decalage,sortorder,entity"; $tabfieldinsert[13] = "code,libelle,type,entity"; $tabfieldinsert[14] = "code,label,price,organization,fk_pays"; $tabfieldinsert[15] = "code,label,width,height,unit"; @@ -761,7 +761,7 @@ if (empty($reshook)) { continue; // For a column name 'sortorder', we use the field name 'position' } if ((!GETPOSTISSET($value) || GETPOST($value) == '') - && (!in_array($value, array('decalage', 'module', 'accountancy_code', 'accountancy_code_sell', 'accountancy_code_buy', 'tracking', 'picto')) // Fields that are not mandatory + && (!in_array($value, array('decalage', 'module', 'accountancy_code', 'accountancy_code_sell', 'accountancy_code_buy', 'tracking', 'picto', 'deposit_percent')) // Fields that are not mandatory && ($id != 10 || ($value != 'code' && $value != 'note')) // Field code and note is not mandatory for dictionary table 10 ) ) { @@ -774,6 +774,9 @@ if (empty($reshook)) { if ($fieldnamekey == 'libelle_facture') { $fieldnamekey = 'LabelOnDocuments'; } + if ($fieldnamekey == 'deposit_percent') { + $fieldnamekey = 'DepositPercent'; + } if ($fieldnamekey == 'nbjour') { $fieldnamekey = 'NbOfDays'; } @@ -1356,6 +1359,10 @@ if ($id) { if ($value == 'libelle_facture') { $valuetoshow = $form->textwithtooltip($langs->trans("LabelOnDocuments"), $langs->trans("LabelUsedByDefault"), 2, 1, img_help(1, '')); } + if ($value == 'deposit_percent') { + $valuetoshow = $langs->trans('DepositPercent'); + $class = 'right'; + } if ($value == 'country') { if (in_array('region_id', $fieldlist)) { print ' '; continue; @@ -1717,6 +1724,10 @@ if ($id) { if ($value == 'libelle_facture') { $valuetoshow = $langs->trans("LabelOnDocuments"); } + if ($value == 'deposit_percent') { + $valuetoshow = $langs->trans('DepositPercent'); + $cssprefix = 'right '; + } if ($value == 'country') { $valuetoshow = $langs->trans("Country"); } @@ -2097,7 +2108,7 @@ if ($id) { if ($value == 'tracking') { $class .= ' tdoverflowauto'; } - if (in_array($value, array('pos', 'position'))) { + if (in_array($value, array('pos', 'position', 'deposit_percent'))) { $class .= ' right'; } if (in_array($value, array('localtax1_type', 'localtax2_type'))) { @@ -2499,7 +2510,7 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') if ($fieldlist[$field] == 'code') { $class = 'maxwidth100'; } - if (in_array($fieldlist[$field], array('pos', 'position'))) { + if (in_array($fieldlist[$field], array('pos', 'position', 'deposit_percent'))) { $classtd = 'right'; $class = 'maxwidth50 right'; } if (in_array($fieldlist[$field], array('dayrule', 'day', 'month', 'year', 'use_default', 'affect', 'delay', 'public', 'sortorder', 'sens', 'category_type', 'fk_parent'))) { diff --git a/htdocs/admin/dolistore/class/PSWebServiceLibrary.class.php b/htdocs/admin/dolistore/class/PSWebServiceLibrary.class.php index 5a23133923e..521a24f490d 100644 --- a/htdocs/admin/dolistore/class/PSWebServiceLibrary.class.php +++ b/htdocs/admin/dolistore/class/PSWebServiceLibrary.class.php @@ -232,6 +232,9 @@ class PrestaShopWebservice if ($response != '') { libxml_clear_errors(); libxml_use_internal_errors(true); + if (!function_exists('simplexml_load_string')) { + throw new PrestaShopWebserviceException('Method simplexml_load_string not available. Your PHP does not support xml.'); + } $xml = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA|LIBXML_NONET); if (libxml_get_errors()) { $msg = var_export(libxml_get_errors(), true); diff --git a/htdocs/admin/eventorganization.php b/htdocs/admin/eventorganization.php index f5b1fd0a4db..ee6c2ae6b52 100644 --- a/htdocs/admin/eventorganization.php +++ b/htdocs/admin/eventorganization.php @@ -457,7 +457,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print ''; $constforvar = 'EVENTORGANIZATION_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $file) { + if (getDolGlobalString($constforvar) == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { print ''; @@ -597,7 +597,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Default print ''; $constforvar = 'EVENTORGANIZATION_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $name) { + if (getDolGlobalString($constforvar) == $name) { //print img_picto($langs->trans("Default"), 'on'); // Even if choice is the default value, we allow to disable it. Replace this with previous line if you need to disable unset print 'scandir.'&label='.urlencode($module->name).'&type='.urlencode($type).'" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').''; diff --git a/htdocs/admin/hrm.php b/htdocs/admin/hrm.php index aea86069f4d..f5bbb5c648f 100644 --- a/htdocs/admin/hrm.php +++ b/htdocs/admin/hrm.php @@ -279,7 +279,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print ''; $constforvar = 'HRMTEST_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $file) { + if (getDolGlobalString($constforvar) == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { print ''; @@ -421,7 +421,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Default print ''; $constforvar = 'HRMTEST_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $name) { + if (getDolGlobalString($constforvar) == $name) { //print img_picto($langs->trans("Default"), 'on'); // Even if choice is the default value, we allow to disable it. Replace this with previous line if you need to disable unset print 'scandir.'&label='.urlencode($module->name).'&type='.urlencode($type).'" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').''; diff --git a/htdocs/admin/knowledgemanagement.php b/htdocs/admin/knowledgemanagement.php index c2440bbb885..041216014b0 100644 --- a/htdocs/admin/knowledgemanagement.php +++ b/htdocs/admin/knowledgemanagement.php @@ -403,7 +403,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print ''; $constforvar = 'KNOWLEDGEMANAGEMENT_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $file) { + if (getDolGlobalString($constforvar) == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { print ''; @@ -545,7 +545,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Default print ''; $constforvar = 'KNOWLEDGEMANAGEMENT_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $name) { + if (getDolGlobalString($constforvar) == $name) { //print img_picto($langs->trans("Default"), 'on'); // Even if choice is the default value, we allow to disable it. Replace this with previous line if you need to disable unset print 'scandir.'&label='.urlencode($module->name).'&type='.urlencode($type).'" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').''; diff --git a/htdocs/admin/mails_senderprofile_list.php b/htdocs/admin/mails_senderprofile_list.php index d3441cf2e21..8e31d0e6d62 100644 --- a/htdocs/admin/mails_senderprofile_list.php +++ b/htdocs/admin/mails_senderprofile_list.php @@ -169,7 +169,7 @@ if (empty($reshook)) { foreach ($object->fields as $key => $val) { $search[$key] = ''; } - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index e308d27b2b2..d96e0706223 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -66,10 +66,6 @@ $search_lang = GETPOST('search_lang', 'alpha'); $search_fk_user = GETPOST('search_fk_user', 'intcomma'); $search_topic = GETPOST('search_topic', 'alpha'); -if (!empty($user->socid)) { - accessforbidden(); -} - $acts = array(); $actl = array(); $acts[0] = "activate"; @@ -100,6 +96,7 @@ if (empty($sortorder)) { // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('emailtemplates')); + // Name of SQL tables of dictionaries $tabname = array(); $tabname[25] = MAIN_DB_PREFIX."c_email_templates"; @@ -246,6 +243,12 @@ if ($reshook == 0) { } } + + +if (!empty($user->socid)) { + accessforbidden(); +} + $permissiontoadd = 1; //asort($elementList); @@ -273,6 +276,9 @@ if ($reshook < 0) { } if (empty($reshook)) { + // Selection of new fields + include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + // Purge search criteria if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers @@ -281,7 +287,7 @@ if (empty($reshook)) { $search_lang = ''; $search_fk_user = ''; $search_topic = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } @@ -395,7 +401,7 @@ if (empty($reshook)) { } } elseif ($keycode == 'content') { $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; - } elseif (in_array($keycode, array('joinfiles', 'private', 'position'))) { + } elseif (in_array($keycode, array('joinfiles', 'private', 'position', 'entity'))) { $sql .= (int) GETPOST($keycode, 'int'); } else { $sql .= "'".$db->escape(GETPOST($keycode, 'nohtml'))."'"; @@ -502,9 +508,9 @@ if (empty($reshook)) { if ($action == 'confirm_delete' && $confirm == 'yes') { // delete $rowidcol = "rowid"; - $sql = "DELETE from ".$tabname[$id]." WHERE ".$rowidcol."=".((int) $rowid); + $sql = "DELETE from ".$tabname[$id]." WHERE ".$rowidcol." = ".((int) $rowid); if (!$user->admin) { // A non admin user can only edit its own template - $sql .= " AND fk_user = ".((int) $user->id); + $sql .= " AND fk_user = ".((int) $user->id); } dol_syslog("delete", LOG_DEBUG); $result = $db->query($sql); @@ -548,47 +554,20 @@ if (empty($reshook)) { */ $form = new Form($db); + +$now = dol_now(); + $formadmin = new FormAdmin($db); +//$help_url = "EN:Module_MyObject|FR:Module_MyObject_FR|ES:Módulo_MyObject"; $help_url = ''; if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) { $title = $langs->trans("EMailsSetup"); } else { - $title = $langs->trans("EMailsTemplates"); + $title = $langs->trans("EMailTemplates"); } - -llxHeader('', $title, $help_url); - -$linkback = ''; -$titlepicto = 'title_setup'; - - -$url = DOL_URL_ROOT.'/admin/mails_templates.php?action=add'; -$newcardbutton = dolGetButtonTitle($langs->trans('NewEMailTemplate'), '', 'fa fa-plus-circle', $url, '', $permissiontoadd); - - -if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) { - print load_fiche_titre($title, '', $titlepicto); -} else { - print load_fiche_titre($title, $newcardbutton, $titlepicto); -} - -if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) { - $head = email_admin_prepare_head(); - - print dol_get_fiche_head($head, 'templates', '', -1); - - if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) { - print load_fiche_titre('', $newcardbutton, ''); - } -} - - -// Confirmation de la suppression de la ligne -if ($action == 'delete') { - print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.$rowid.'&code='.$code.'&id='.$id, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete', '', 0, 1); -} - +$morejs = array(); +$morecss = array(); $sql = "SELECT rowid as rowid, module, label, type_template, lang, fk_user, private, position, topic, joinfiles, content_lines, content, enabled, active"; $sql .= " FROM ".MAIN_DB_PREFIX."c_email_templates"; @@ -623,6 +602,78 @@ $sql .= $db->order($sortfield, $sortorder); $sql .= $db->plimit($listlimit + 1, $offset); //print $sql; +// Output page +// -------------------------------------------------------------------- + +llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', ''); + +$arrayofselected = is_array($toselect) ? $toselect : array(); + +$param = ''; +if (!empty($mode)) { + $param .= '&mode='.urlencode($mode); +} +if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { + $param .= '&contextpage='.urlencode($contextpage); +} +if ($limit > 0 && $limit != $conf->liste_limit) { + $param .= '&limit='.urlencode($limit); +} +foreach ($search as $key => $val) { + if (is_array($search[$key]) && count($search[$key])) { + foreach ($search[$key] as $skey) { + if ($skey != '') { + $param .= '&search_'.$key.'[]='.urlencode($skey); + } + } + } elseif ($search[$key] != '') { + $param .= '&search_'.$key.'='.urlencode($search[$key]); + } +} +if ($optioncss != '') { + $param .= '&optioncss='.urlencode($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; + + +$linkback = ''; +$titlepicto = 'title_setup'; + + +$url = DOL_URL_ROOT.'/admin/mails_templates.php?action=add&token='.newToken(); +$newcardbutton = dolGetButtonTitle($langs->trans('NewEMailTemplate'), '', 'fa fa-plus-circle', $url, '', $permissiontoadd); + + +if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) { + print load_fiche_titre($title, '', $titlepicto); +} else { + print load_fiche_titre($title, $newcardbutton, $titlepicto); +} + +if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) { + $head = email_admin_prepare_head(); + + print dol_get_fiche_head($head, 'templates', '', -1); + + if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) { + print load_fiche_titre('', $newcardbutton, ''); + } +} + + +// Confirmation de la suppression de la ligne +if ($action == 'delete') { + print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.$rowid.'&code='.$code.'&id='.$id, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete', '', 0, 1); +} + + + + $fieldlist = explode(',', $tabfield[$id]); if ($action == 'add') { @@ -681,7 +732,7 @@ if ($action == 'add') { } if ($valuetoshow != '') { - print ''; + print ''; if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) { print ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; } elseif (!empty($tabhelp[$id][$value])) { @@ -693,12 +744,12 @@ if ($action == 'add') { } else { print $valuetoshow; } - print ''; + print ''; } } - print ''; + print ''; print ''; - print ''; + print ''; print ''; $obj = new stdClass(); @@ -742,7 +793,7 @@ if ($action == 'add') { $fieldsforcontent = array('topic', 'joinfiles', 'content', 'content_lines'); } foreach ($fieldsforcontent as $tmpfieldlist) { - print ''; + print ''; // Label if ($tmpfieldlist == 'topic') { @@ -773,24 +824,33 @@ if ($action == 'add') { print $doleditor->Create(1); } print ''; - if ($tmpfieldlist == 'topic') { - print ''; - if ($action != 'edit') { - print '
'; - print ''; - } - print ''; - } - // else print ''; print ''; } print ''; + + if ($action != 'edit') { + print '
'; + print ' '; + print ''; + print '
'; + } + print ''; print '
'; - print '
'; + print '

'; } // END IF not edit +// List of available record in database +dol_syslog("htdocs/admin/dict", LOG_DEBUG); +$resql = $db->query($sql); +if (!$resql) { + dol_print_error($db); + exit; +} + +$num = $db->num_rows($resql); + print '
'; print ''; print ''; @@ -798,157 +858,155 @@ print ''; print ''; -// List of available record in database -dol_syslog("htdocs/admin/dict", LOG_DEBUG); -$resql = $db->query($sql); -if ($resql) { - $num = $db->num_rows($resql); - $i = 0; +$i = 0; - $param = '&id='.$id; - if ($search_label) { - $param .= '&search_label='.urlencode($search_label); - } - if ($search_lang > 0) { - $param .= '&search_lang='.urlencode($search_lang); - } - if ($search_type_template != '-1') { - $param .= '&search_type_template='.urlencode($search_type_template); - } - if ($search_fk_user > 0) { - $param .= '&search_fk_user='.urlencode($search_fk_user); - } - if ($search_topic) { - $param .= '&search_topic='.urlencode($search_topic); - } +$param = '&id='.$id; +if ($search_label) { + $param .= '&search_label='.urlencode($search_label); +} +if ($search_lang > 0) { + $param .= '&search_lang='.urlencode($search_lang); +} +if ($search_type_template != '-1') { + $param .= '&search_type_template='.urlencode($search_type_template); +} +if ($search_fk_user > 0) { + $param .= '&search_fk_user='.urlencode($search_fk_user); +} +if ($search_topic) { + $param .= '&search_topic='.urlencode($search_topic); +} - $paramwithsearch = $param; - if ($sortorder) { - $paramwithsearch .= '&sortorder='.urlencode($sortorder); - } - if ($sortfield) { - $paramwithsearch .= '&sortfield='.urlencode($sortfield); - } - if (GETPOST('from', 'alpha')) { - $paramwithsearch .= '&from='.urlencode(GETPOST('from', 'alpha')); - } +$paramwithsearch = $param; +if ($sortorder) { + $paramwithsearch .= '&sortorder='.urlencode($sortorder); +} +if ($sortfield) { + $paramwithsearch .= '&sortfield='.urlencode($sortfield); +} +if (GETPOST('from', 'alpha')) { + $paramwithsearch .= '&from='.urlencode(GETPOST('from', 'alpha')); +} - // There is several pages - if ($num > $listlimit) { - print ''; - } +// There is several pages +if ($num > $listlimit) { + print ''; +} - // Title line with search boxes - print ''; +// Title line with search boxes +print ''; - foreach ($fieldlist as $field => $value) { - if ($value == 'label') { - print ''; - } elseif ($value == 'lang') { - print ''; - } elseif ($value == 'fk_user') { - print ''; - } elseif ($value == 'topic') { - print ''; - } elseif ($value == 'type_template') { - print ''; - } elseif (!in_array($value, array('content', 'content_lines'))) { - print ''; - } - } - - if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { +foreach ($fieldlist as $field => $value) { + if ($value == 'label') { + print ''; + } elseif ($value == 'lang') { + print ''; + } elseif ($value == 'fk_user') { + print ''; + } elseif ($value == 'topic') { + print ''; + } elseif ($value == 'type_template') { + print ''; + } elseif (!in_array($value, array('content', 'content_lines'))) { print ''; } +} - // Action column - print ''; - print ''; +if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { + print ''; +} - // Title of lines - print ''; - foreach ($fieldlist as $field => $value) { - $showfield = 1; // By defaut - $align = "left"; - $sortable = 1; - $valuetoshow = ''; - $forcenowrap = 1; - /* - $tmparray=getLabelOfField($fieldlist[$field]); - $showfield=$tmp['showfield']; - $valuetoshow=$tmp['valuetoshow']; - $align=$tmp['align']; - $sortable=$tmp['sortable']; - */ - $valuetoshow = ucfirst($fieldlist[$field]); // By defaut - $valuetoshow = $langs->trans($valuetoshow); // try to translate - if ($fieldlist[$field] == 'fk_user') { - $valuetoshow = $langs->trans("Owner"); - } - if ($fieldlist[$field] == 'lang') { - $valuetoshow = $langs->trans("Language"); - } - if ($fieldlist[$field] == 'type') { - $valuetoshow = $langs->trans("Type"); - } - if ($fieldlist[$field] == 'libelle' || $fieldlist[$field] == 'label') { - $valuetoshow = $langs->trans("Code"); - } - if ($fieldlist[$field] == 'type_template') { - $align = 'center'; - $valuetoshow = $langs->trans("TypeOfTemplate"); - } - if ($fieldlist[$field] == 'private') { - $align = 'center'; - } - if ($fieldlist[$field] == 'position') { - $align = 'center'; - } +// Action column +print ''; +print ''; - if ($fieldlist[$field] == 'joinfiles') { - $valuetoshow = $langs->trans("FilesAttachedToEmail"); $align = 'center'; $forcenowrap = 0; - } - if ($fieldlist[$field] == 'content') { - $valuetoshow = $langs->trans("Content"); $showfield = 0; - } - if ($fieldlist[$field] == 'content_lines') { - $valuetoshow = $langs->trans("ContentForLines"); $showfield = 0; - } - - // Show fields - if ($showfield) { - if (!empty($tabhelp[$id][$value])) { - if (in_array($value, array('topic'))) { - $valuetoshow = $form->textwithpicto($valuetoshow, $tabhelp[$id][$value], 1, 'help', '', 0, 2, 'tooltip'.$value, $forcenowrap); // Tooltip on click - } else { - $valuetoshow = $form->textwithpicto($valuetoshow, $tabhelp[$id][$value], 1, 'help', '', 0, 2, '', $forcenowrap); // Tooltip on hover - } - } - print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], ($sortable ? $fieldlist[$field] : ''), ($page ? 'page='.$page.'&' : ''), $param, "align=".$align, $sortfield, $sortorder); - } +// Title of lines +print ''; +foreach ($fieldlist as $field => $value) { + $showfield = 1; // By defaut + $align = "left"; + $sortable = 1; + $valuetoshow = ''; + $forcenowrap = 1; + /* + $tmparray=getLabelOfField($fieldlist[$field]); + $showfield=$tmp['showfield']; + $valuetoshow=$tmp['valuetoshow']; + $align=$tmp['align']; + $sortable=$tmp['sortable']; + */ + $valuetoshow = ucfirst($fieldlist[$field]); // By defaut + $valuetoshow = $langs->trans($valuetoshow); // try to translate + if ($fieldlist[$field] == 'fk_user') { + $valuetoshow = $langs->trans("Owner"); + } + if ($fieldlist[$field] == 'lang') { + $valuetoshow = $langs->trans("Language"); + } + if ($fieldlist[$field] == 'type') { + $valuetoshow = $langs->trans("Type"); + } + if ($fieldlist[$field] == 'libelle' || $fieldlist[$field] == 'label') { + $valuetoshow = $langs->trans("Code"); + } + if ($fieldlist[$field] == 'type_template') { + $align = 'center'; + $valuetoshow = $langs->trans("TypeOfTemplate"); + } + if ($fieldlist[$field] == 'private') { + $align = 'center'; + } + if ($fieldlist[$field] == 'position') { + $align = 'center'; } - print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], "active", ($page ? 'page='.$page.'&' : ''), $param, 'align="center"', $sortfield, $sortorder); - print getTitleFieldOfList(''); - print ''; + if ($fieldlist[$field] == 'joinfiles') { + $valuetoshow = $langs->trans("FilesAttachedToEmail"); $align = 'center'; $forcenowrap = 0; + } + if ($fieldlist[$field] == 'content') { + $valuetoshow = $langs->trans("Content"); $showfield = 0; + } + if ($fieldlist[$field] == 'content_lines') { + $valuetoshow = $langs->trans("ContentForLines"); $showfield = 0; + } - if ($num) { - // Lines with values - while ($i < $num) { - $obj = $db->fetch_object($resql); + // Show fields + if ($showfield) { + if (!empty($tabhelp[$id][$value])) { + if (in_array($value, array('topic'))) { + $valuetoshow = $form->textwithpicto($valuetoshow, $tabhelp[$id][$value], 1, 'help', '', 0, 2, 'tooltip'.$value, $forcenowrap); // Tooltip on click + } else { + $valuetoshow = $form->textwithpicto($valuetoshow, $tabhelp[$id][$value], 1, 'help', '', 0, 2, '', $forcenowrap); // Tooltip on hover + } + } + print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], ($sortable ? $fieldlist[$field] : ''), ($page ? 'page='.$page.'&' : ''), $param, "align=".$align, $sortfield, $sortorder); + } +} +print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], "active", ($page ? 'page='.$page.'&' : ''), $param, 'align="center"', $sortfield, $sortorder); +print getTitleFieldOfList(''); +print ''; + +if ($num) { + $nbqualified = 0; + + // Lines with values + while ($i < $num) { + $obj = $db->fetch_object($resql); + + if ($obj) { if ($action == 'edit' && ($rowid == (!empty($obj->rowid) ? $obj->rowid : $obj->code))) { print ''; @@ -1018,6 +1076,8 @@ if ($resql) { } print "\n"; + + $nbqualified++; } else { // If template is for a module, check module is enabled. if ($obj->module) { @@ -1039,6 +1099,8 @@ if ($resql) { continue; // Email template not qualified } + $nbqualified++; + print ''; $tmpaction = 'view'; @@ -1155,13 +1217,16 @@ if ($resql) { print "\n"; } - - - $i++; } + + $i++; } -} else { - dol_print_error($db); +} + +// If no record found +if ($nbqualified == 0) { + $colspan = 10; + print ''; } print '
'; - print_fleche_navigation($page, $_SERVER["PHP_SELF"], $paramwithsearch, ($num > $listlimit), ''); - print '
'; + print_fleche_navigation($page, $_SERVER["PHP_SELF"], $paramwithsearch, ($num > $listlimit), ''); + print '
'; - print $formadmin->select_language($search_lang, 'search_lang', 0, null, 1, 0, 0, 'maxwidth150'); - print ''; - print $form->select_dolusers($search_fk_user, 'search_fk_user', 1, null, 0, ($user->admin ? '' : 'hierarchyme'), null, 0, 0, 0, '', 0, '', 'maxwidth150'); - print ''; - print $form->selectarray('search_type_template', $elementList, $search_type_template, 1, 0, 0, '', 0, 0, 0, '', 'minwidth150', 1, '', 0, 1); - print ''; + print $formadmin->select_language($search_lang, 'search_lang', 0, null, 1, 0, 0, 'maxwidth150'); + print ''; + print $form->select_dolusers($search_fk_user, 'search_fk_user', 1, null, 0, ($user->admin ? '' : 'hierarchyme'), null, 0, 0, 0, '', 0, '', 'maxwidth150'); + print ''; + print $form->selectarray('search_type_template', $elementList, $search_type_template, 1, 0, 0, '', 0, 0, 0, '', 'minwidth150', 1, '', 0, 1); + print ''; - $searchpicto = $form->showFilterButtons(); - print $searchpicto; - print '
'; +$searchpicto = $form->showFilterButtons(); +print $searchpicto; +print '
'.$langs->trans("NoRecordFound").'
'; diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index 716dbc32ca7..0c53bebfc52 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -172,6 +172,10 @@ foreach ($modulesdir as $dir) { $moduleposition = '80'; // External modules at end by default } + if (empty($familyinfo[$familykey]['position'])) { + $familyinfo[$familykey]['position'] = '0'; + } + $orders[$i] = $familyinfo[$familykey]['position']."_".$familykey."_".$moduleposition."_".$j; // Sort by family, then by module position then number $dirmod[$i] = $dir; //print $i.'-'.$dirmod[$i].'
'; @@ -250,19 +254,19 @@ if (!empty($conf->global->$const_name)) { $text .= $langs->trans("Disabled"); } $tmp = $objMod->getLastActivationInfo(); -$authorid = $tmp['authorid']; +$authorid = (empty($tmp['authorid']) ? '' : $tmp['authorid']); if ($authorid > 0) { $tmpuser = new User($db); $tmpuser->fetch($authorid); $text .= '
'.$langs->trans("LastActivationAuthor").': '; $text .= $tmpuser->getNomUrl(1); } -$ip = $tmp['ip']; +$ip = (empty($tmp['ip']) ? '' : $tmp['ip']); if ($ip) { $text .= '
'.$langs->trans("LastActivationIP").': '; $text .= $ip; } -$lastactivationversion = $tmp['lastactivationversion']; +$lastactivationversion = (empty($tmp['lastactivationversion']) ? '' : $tmp['lastactivationversion']); if ($lastactivationversion) { $text .= '
'.$langs->trans("LastActivationVersion").': '; $text .= $lastactivationversion; diff --git a/htdocs/admin/translation.php b/htdocs/admin/translation.php index 10f0f8375e3..18ce707c839 100644 --- a/htdocs/admin/translation.php +++ b/htdocs/admin/translation.php @@ -90,7 +90,7 @@ include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers $transkey = ''; $transvalue = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } diff --git a/htdocs/admin/workstation.php b/htdocs/admin/workstation.php index 58118827ed4..6ac7a425246 100644 --- a/htdocs/admin/workstation.php +++ b/htdocs/admin/workstation.php @@ -295,7 +295,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print ''; $constforvar = 'WORKSTATION_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $file) { + if (getDolGlobalString($constforvar) == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { print ''; @@ -437,7 +437,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Default print ''; $constforvar = 'WORKSTATION_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $name) { + if (getDolGlobalString($constforvar) == $name) { print img_picto($langs->trans("Default"), 'on'); } else { print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; diff --git a/htdocs/asset/admin/setup.php b/htdocs/asset/admin/setup.php index afa4777de3d..29ee4b074fb 100644 --- a/htdocs/asset/admin/setup.php +++ b/htdocs/asset/admin/setup.php @@ -266,7 +266,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print ''; $constforvar = 'ASSET_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $file) { + if (getDolGlobalString($constforvar) == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { print ''; @@ -408,7 +408,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Default print ''; $constforvar = 'ASSET_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $name) { + if (getDolGlobalString($constforvar) == $name) { //print img_picto($langs->trans("Default"), 'on'); // Even if choice is the default value, we allow to disable it. Replace this with previous line if you need to disable unset print 'scandir).'&label='.urlencode($module->name).'&type='.urlencode($type).'" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').''; diff --git a/htdocs/barcode/codeinit.php b/htdocs/barcode/codeinit.php index ef3c23eff2b..1a5f99b27ee 100644 --- a/htdocs/barcode/codeinit.php +++ b/htdocs/barcode/codeinit.php @@ -286,7 +286,7 @@ if ($conf->product->enabled || $conf->product->service) { print ''; $moretags2 = (($nbno == $nbtotal) ? ' disabled' : ''); print '   '; - print ''; + print ''; print '



'; } diff --git a/htdocs/blockedlog/admin/blockedlog_list.php b/htdocs/blockedlog/admin/blockedlog_list.php index 4698222bda8..4490b3897df 100644 --- a/htdocs/blockedlog/admin/blockedlog_list.php +++ b/htdocs/blockedlog/admin/blockedlog_list.php @@ -118,7 +118,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_ref = ''; $search_amount = ''; $search_showonlyerrors = 0; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php index 327876f17c2..7d12f571c06 100644 --- a/htdocs/categories/viewcat.php +++ b/htdocs/categories/viewcat.php @@ -734,9 +734,9 @@ if ($type == Categorie::TYPE_MEMBER) { print ''; print ''; print ''; + print ''; print ''; print '
'; - print $langs->trans("AddMemberIntoCategory").'  '; + print $langs->trans("AssignCategoryTo").'  '; print $form->selectMembers('', 'elemid'); - print '
'; print '
'; diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php index f6932cc4bef..86b8a3b5ce5 100644 --- a/htdocs/comm/action/list.php +++ b/htdocs/comm/action/list.php @@ -217,7 +217,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $dateend_dtstart = ''; $dateend_dtend = ''; $search_status = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 4aca208681b..411efc5ae93 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -173,7 +173,7 @@ if (empty($reshook)) { // terms of the settlement if ($action == 'setconditions' && $user->rights->societe->creer) { $object->fetch($id); - $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); + $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'), GETPOST('cond_reglement_id_deposit_percent', 'alpha')); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); } @@ -415,9 +415,9 @@ if ($object->id > 0) { print ''; print ''; if ($action == 'editconditions') { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->cond_reglement_id, 'cond_reglement_id', 1); + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->cond_reglement_id, 'cond_reglement_id', 1, '', 1, $object->deposit_percent); } else { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->cond_reglement_id, 'none'); + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->cond_reglement_id, 'none', 0, '', 1, $object->deposit_percent); } print ""; print ''; diff --git a/htdocs/comm/mailing/list.php b/htdocs/comm/mailing/list.php index be458d41fe3..ecde836c428 100644 --- a/htdocs/comm/mailing/list.php +++ b/htdocs/comm/mailing/list.php @@ -103,7 +103,7 @@ if (empty($reshook)) { }*/ $search_ref = ''; $search_all = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index e89f30ce60a..485b5b0daf9 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -402,6 +402,7 @@ if (empty($reshook)) { $object->warehouse_id = GETPOST('warehouse_id', 'int'); $object->duree_validite = $duration; $object->cond_reglement_id = GETPOST('cond_reglement_id'); + $object->deposit_percent = GETPOST('cond_reglement_id_deposit_percent', 'alpha'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); $object->fk_account = GETPOST('fk_account', 'int'); $object->remise_absolue = price2num(GETPOST('remise_absolue'), 'MU', 2); // deprecated @@ -434,6 +435,7 @@ if (empty($reshook)) { $object->warehouse_id = GETPOST('warehouse_id', 'int'); $object->duree_validite = price2num(GETPOST('duree_validite', 'alpha')); $object->cond_reglement_id = GETPOST('cond_reglement_id', 'int'); + $object->deposit_percent = GETPOST('cond_reglement_id_deposit_percent', 'alpha'); $object->mode_reglement_id = GETPOST('mode_reglement_id', 'int'); $object->fk_account = GETPOST('fk_account', 'int'); $object->contact_id = GETPOST('contactid', 'int'); @@ -687,11 +689,59 @@ if (empty($reshook)) { $error++; } + $deposit = null; + $locationTarget = $_SERVER['PHP_SELF'] . '?id=' . $object->id; + + $deposit_percent_from_payment_terms = getDictionaryValue(MAIN_DB_PREFIX . 'c_payment_term', 'deposit_percent', $object->cond_reglement_id); + + if ( + !$error && GETPOST('statut', 'int') == $object::STATUS_SIGNED && GETPOST('generate_deposit', 'alpha') == 'on' + && ! empty($deposit_percent_from_payment_terms) && ! empty($conf->facture->enabled) && ! empty($user->rights->facture->creer) + ) { + require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; + + $date = dol_mktime(0, 0, 0, GETPOST('datefmonth', 'int'), GETPOST('datefday', 'int'), GETPOST('datefyear', 'int')); + $forceFields = array(); + + if (GETPOSTISSET('date_pointoftax')) { + $forceFields['date_pointoftax'] = dol_mktime(0, 0, 0, GETPOST('date_pointoftaxmonth', 'int'), GETPOST('date_pointoftaxday', 'int'), GETPOST('date_pointoftaxyear', 'int')); + } + + $deposit = Facture::createDepositFromOrigin($object, $date, GETPOST('cond_reglement_id', 'int'), $user, 0, GETPOST('validate_generated_deposit', 'alpha') == 'on', $forceFields); + + if ($deposit) { + setEventMessage('DepositGenerated'); + $locationTarget = DOL_URL_ROOT . '/compta/facture/card.php?id=' . $deposit->id; + } else { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + } + } + if (!$error) { $db->commit(); + if ($deposit && empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $ret = $deposit->fetch($deposit->id); // Reload to get new records + $outputlangs = $langs; + + if ($conf->global->MAIN_MULTILANGS) { + $outputlangs = new Translate('', $conf); + $outputlangs->setDefaultLang($deposit->thirdparty->default_lang); + $outputlangs->load('products'); + } + + $result = $deposit->generateDocument($deposit->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + + if ($result < 0) { + setEventMessages($deposit->error, $deposit->errors, 'errors'); + } + } } else { $db->rollback(); } + + header('Location: ' . $locationTarget); + exit; } } } elseif ($action == 'confirm_reopen' && $usercanclose && !GETPOST('cancel', 'alpha')) { @@ -1370,7 +1420,7 @@ if (empty($reshook)) { $result = $object->set_demand_reason($user, GETPOST('demand_reason_id', 'int')); } elseif ($action == 'setconditions' && $usercancreate) { // Terms of payment - $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); + $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'), GETPOST('cond_reglement_id_deposit_percent', 'alpha')); } elseif ($action == 'setremisepercent' && $usercancreate) { $result = $object->set_remise_percent($user, price2num(GETPOST('remise_percent'), '', 2)); } elseif ($action == 'setremiseabsolue' && $usercancreate) { @@ -1656,9 +1706,9 @@ if ($action == 'create') { print ''.$langs->trans("ValidityDuration").''.img_picto('', 'clock', 'class="paddingright"').' '.$langs->trans("days").''; // Terms of payment - print ''.$langs->trans('PaymentConditionsShort').''; - print img_picto('', 'payment', 'class="pictofixedwidth"'); - $form->select_conditions_paiements((GETPOSTISSET('cond_reglement_id') && GETPOST('cond_reglement_id') != 0) ? GETPOST('cond_reglement_id', 'int') : $soc->cond_reglement_id, 'cond_reglement_id', -1, 1); + print ''.$langs->trans('PaymentConditionsShort').''; + print img_picto('', 'paiment'); + $form->select_conditions_paiements((GETPOSTISSET('cond_reglement_id') && GETPOST('cond_reglement_id') != 0) ? GETPOST('cond_reglement_id', 'int') : $soc->cond_reglement_id, 'cond_reglement_id', 1, 1, 0, '', (GETPOSTISSET('cond_reglement_id_deposit_percent') ? GETPOST('cond_reglement_id_deposit_percent', 'alpha') : $soc->deposit_percent)); print ''; // Mode of payment @@ -1945,6 +1995,129 @@ if ($action == 'create') { array('type' => 'text', 'name' => 'note_private', 'label' => $langs->trans("Note"), 'value' => '') // Field to complete private note (not replace) ); + $deposit_percent_from_payment_terms = getDictionaryValue(MAIN_DB_PREFIX . 'c_payment_term', 'deposit_percent', $object->cond_reglement_id); + + if (! empty($deposit_percent_from_payment_terms) && ! empty($conf->facture->enabled) && ! empty($user->rights->facture->creer)) { + require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; + + $object->fetchObjectLinked(); + + $eligibleForDepositGeneration = true; + + if (array_key_exists('facture', $object->linkedObjects)) { + foreach ($object->linkedObjects['facture'] as $invoice) { + if ($invoice->type == Facture::TYPE_DEPOSIT) { + $eligibleForDepositGeneration = false; + break; + } + } + } + + if ($eligibleForDepositGeneration && array_key_exists('commande', $object->linkedObjects)) { + foreach ($object->linkedObjects['commande'] as $order) { + $order->fetchObjectLinked(); + + if (array_key_exists('facture', $order->linkedObjects)) { + foreach ($order->linkedObjects['facture'] as $invoice) { + if ($invoice->type == Facture::TYPE_DEPOSIT) { + $eligibleForDepositGeneration = false; + break 2; + } + } + } + } + } + + + if ($eligibleForDepositGeneration) { + $formquestion[] = array( + 'type' => 'checkbox', + 'tdclass' => 'showonlyifsigned', + 'name' => 'generate_deposit', + 'label' => $form->textwithpicto($langs->trans('GenerateDeposit', $object->deposit_percent), $langs->trans('DepositGenerationPermittedByThePaymentTermsSelected')) + ); + + $formquestion[] = array( + 'type' => 'date', + 'tdclass' => 'fieldrequired showonlyifgeneratedeposit', + 'name' => 'datef', + 'label' => $langs->trans('DateInvoice'), + 'value' => dol_now(), + 'datenow' => true + ); + + if (! empty($conf->global->INVOICE_POINTOFTAX_DATE)) { + $formquestion[] = array( + 'type' => 'date', + 'tdclass' => 'fieldrequired showonlyifgeneratedeposit', + 'name' => 'date_pointoftax', + 'label' => $langs->trans('DatePointOfTax'), + 'value' => dol_now(), + 'datenow' => true + ); + } + + ob_start(); + $form->select_conditions_paiements(0, 'cond_reglement_id', -1, 0, 0, 'minwidth200'); + $paymentTermsSelect = ob_get_clean(); + + $formquestion[] = array( + 'type' => 'other', + 'tdclass' => 'fieldrequired showonlyifgeneratedeposit', + 'name' => 'cond_reglement_id', + 'label' => $langs->trans('PaymentTerm'), + 'value' => $paymentTermsSelect + ); + + $formquestion[] = array( + 'type' => 'checkbox', + 'tdclass' => 'showonlyifgeneratedeposit', + 'name' => 'validate_generated_deposit', + 'label' => $langs->trans('ValidateGeneratedDeposit') + ); + + $formquestion[] = array( + 'type' => 'onecolumn', + 'value' => ' + + ' + ); + } + } + if (!empty($conf->notification->enabled)) { require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php'; $notify = new Notify($db); @@ -2171,9 +2344,9 @@ if ($action == 'create') { print ''; print ''; if ($action == 'editconditions' && $usercancreate && $caneditfield) { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'cond_reglement_id'); + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'cond_reglement_id', 0, '', 1, $object->deposit_percent); } else { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'none'); + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'none', 0, '', 1, $object->deposit_percent); } print ''; print ''; diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index cfe2a15f2db..0d7c301f7b0 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -206,6 +206,7 @@ class Propal extends CommonObject public $total; public $cond_reglement_code; + public $deposit_percent; public $mode_reglement_code; public $remise_percent; @@ -319,6 +320,7 @@ class Propal extends CommonObject 'fk_account' =>array('type'=>'integer', 'label'=>'BankAccount', 'enabled'=>1, 'visible'=>-1, 'position'=>150), 'fk_currency' =>array('type'=>'varchar(3)', 'label'=>'Currency', 'enabled'=>1, 'visible'=>-1, 'position'=>155), 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>-1, 'position'=>160), + 'deposit_percent' =>array('type'=>'varchar(63)', 'label'=>'DepositPercent', 'enabled'=>1, 'visible'=>-1, 'position'=>161), 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'PaymentMode', 'enabled'=>1, 'visible'=>-1, 'position'=>165), 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>170), 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>175), @@ -1100,6 +1102,7 @@ class Propal extends CommonObject $sql .= ", model_pdf"; $sql .= ", fin_validite"; $sql .= ", fk_cond_reglement"; + $sql .= ", deposit_percent"; $sql .= ", fk_mode_reglement"; $sql .= ", fk_account"; $sql .= ", ref_client"; @@ -1133,6 +1136,7 @@ class Propal extends CommonObject $sql .= ", '".$this->db->escape($this->model_pdf)."'"; $sql .= ", ".($this->fin_validite != '' ? "'".$this->db->idate($this->fin_validite)."'" : "NULL"); $sql .= ", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) : 'NULL'); + $sql .= ", ".(! empty($this->deposit_percent) ? "'".$this->db->escape($this->deposit_percent)."'" : 'NULL'); $sql .= ", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) : 'NULL'); $sql .= ", ".($this->fk_account > 0 ? ((int) $this->fk_account) : 'NULL'); $sql .= ", '".$this->db->escape($this->ref_client)."'"; @@ -1360,6 +1364,7 @@ class Propal extends CommonObject if ($objsoc->fetch($socid) > 0) { $object->socid = $objsoc->id; $object->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0); + $object->deposit_percent = (!empty($objsoc->deposit_percent) ? $objsoc->deposit_percent : null); $object->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0); $object->fk_delivery_address = ''; @@ -1536,7 +1541,7 @@ class Propal extends CommonObject $sql .= ", c.label as statut_label"; $sql .= ", ca.code as availability_code, ca.label as availability"; $sql .= ", dr.code as demand_reason_code, dr.label as demand_reason"; - $sql .= ", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc"; + $sql .= ", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc, p.deposit_percent"; $sql .= ", cp.code as mode_reglement_code, cp.libelle as mode_reglement"; $sql .= " FROM ".MAIN_DB_PREFIX."propal as p"; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_propalst as c ON p.fk_statut = c.id'; @@ -1619,6 +1624,7 @@ class Propal extends CommonObject $this->cond_reglement_code = $obj->cond_reglement_code; $this->cond_reglement = $obj->cond_reglement; $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc; + $this->deposit_percent = $obj->deposit_percent; $this->extraparams = (array) json_decode($obj->extraparams, true); @@ -1728,6 +1734,7 @@ class Propal extends CommonObject $sql .= " fk_user_valid=".(isset($this->user_valid) ? $this->user_valid : "null").","; $sql .= " fk_projet=".(isset($this->fk_project) ? $this->fk_project : "null").","; $sql .= " fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id : "null").","; + $sql .= " deposit_percent=".(! empty($this->deposit_percent) ? "'".$this->db->escape($this->deposit_percent)."'" : "null").","; $sql .= " fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id : "null").","; $sql .= " fk_input_reason=".(isset($this->demand_reason_id) ? $this->demand_reason_id : "null").","; $sql .= " note_private=".(isset($this->note_private) ? "'".$this->db->escape($this->note_private)."'" : "null").","; diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 0056716972b..eb5b310edd1 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -340,7 +340,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_availability = ''; $search_status = ''; $object_statut = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); $search_categ_cus = 0; $search_fk_cond_reglement = ''; @@ -537,7 +537,7 @@ $sql .= ' p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multic $sql .= ' p.datec as date_creation, p.tms as date_update, p.date_cloture as date_cloture,'; $sql .= ' p.date_signature as dsignature,'; $sql .= ' p.note_public, p.note_private,'; -$sql .= ' p.fk_cond_reglement,p.fk_mode_reglement,p.fk_shipping_method,p.fk_input_reason,'; +$sql .= ' p.fk_cond_reglement,p.deposit_percent,p.fk_mode_reglement,p.fk_shipping_method,p.fk_input_reason,'; $sql .= " pr.rowid as project_id, pr.ref as project_ref, pr.title as project_label,"; $sql .= ' u.login, u.lastname, u.firstname, u.email as user_email, u.statut as user_statut, u.entity as user_entity, u.photo, u.office_phone, u.office_fax, u.user_mobile, u.job, u.gender'; if (empty($user->rights->societe->client->voir) && !$socid) { @@ -1224,7 +1224,7 @@ if ($resql) { // Payment term if (!empty($arrayfields['p.fk_cond_reglement']['checked'])) { print ''; - $form->select_conditions_paiements($search_fk_cond_reglement, 'search_fk_cond_reglement', -1, 1, 1); + $form->select_conditions_paiements($search_fk_cond_reglement, 'search_fk_cond_reglement', 1, 1, 1); print ''; } // Payment mode @@ -1821,7 +1821,7 @@ if ($resql) { // Payment terms if (!empty($arrayfields['p.fk_cond_reglement']['checked'])) { print ''; - $form->form_conditions_reglement($_SERVER['PHP_SELF'], $obj->fk_cond_reglement, 'none'); + $form->form_conditions_reglement($_SERVER['PHP_SELF'], $obj->fk_cond_reglement, 'none', 0, '', 1, $obj->deposit_percent); print ''; if (!$i) { $totalarray['nbfield']++; diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index ecd647c7206..1a35ff937b9 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -272,6 +272,7 @@ if (empty($reshook)) { $object->ref_client = GETPOST('ref_client', 'alpha'); $object->model_pdf = GETPOST('model'); $object->cond_reglement_id = GETPOST('cond_reglement_id'); + $object->deposit_percent = GETPOST('cond_reglement_id_deposit_percent', 'alpha'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); $object->fk_account = GETPOST('fk_account', 'int'); $object->availability_id = GETPOST('availability_id'); @@ -571,7 +572,7 @@ if (empty($reshook)) { setEventMessages($object->error, $object->errors, 'errors'); } } elseif ($action == 'setconditions' && $usercancreate) { - $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); + $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'), GETPOST('cond_reglement_id_deposit_percent', 'alpha')); if ($result < 0) { dol_print_error($db, $object->error); } else { @@ -1176,30 +1177,75 @@ if (empty($reshook)) { } if (!$error) { + $locationTarget = $_SERVER['PHP_SELF'] . '?id=' . $object->id; + $db->begin(); $result = $object->valid($user, $idwarehouse); if ($result >= 0) { - // Define output language - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) { - $newlang = GETPOST('lang_id', 'aZ09'); - } - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) { - $newlang = $object->thirdparty->default_lang; - } - if (!empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $model = $object->model_pdf; - $ret = $object->fetch($id); // Reload to get new records + $error = 0; + $deposit = null; - $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + $deposit_percent_from_payment_terms = getDictionaryValue(MAIN_DB_PREFIX . 'c_payment_term', 'deposit_percent', $object->cond_reglement_id); + + if ( + GETPOST('generate_deposit', 'alpha') == 'on' && ! empty($deposit_percent_from_payment_terms) + && ! empty($conf->facture->enabled) && ! empty($user->rights->facture->creer) + ) { + require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; + + $date = dol_mktime(0, 0, 0, GETPOST('datefmonth', 'int'), GETPOST('datefday', 'int'), GETPOST('datefyear', 'int')); + $forceFields = array(); + + if (GETPOSTISSET('date_pointoftax')) { + $forceFields['date_pointoftax'] = dol_mktime(0, 0, 0, GETPOST('date_pointoftaxmonth', 'int'), GETPOST('date_pointoftaxday', 'int'), GETPOST('date_pointoftaxyear', 'int')); + } + + $deposit = Facture::createDepositFromOrigin($object, $date, GETPOST('cond_reglement_id', 'int'), $user, 0, GETPOST('validate_generated_deposit', 'alpha') == 'on', $forceFields); + + if ($deposit) { + setEventMessage('DepositGenerated'); + $locationTarget = DOL_URL_ROOT . '/compta/facture/card.php?id=' . $deposit->id; + } else { + setEventMessages($object->error, $object->errors, 'errors'); + } + } + + // Define output language + if (! $error) { + $db->commit(); + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) { + $newlang = GETPOST('lang_id', 'aZ09'); + } + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) { + $newlang = $object->thirdparty->default_lang; + } + if (!empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model = $object->model_pdf; + $ret = $object->fetch($id); // Reload to get new records + + $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + + if ($deposit) { + $deposit->fetch($deposit->id); // Reload to get new records + $deposit->generateDocument($deposit->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + } else { + $db->rollback(); } } else { + $db->rollback(); setEventMessages($object->error, $object->errors, 'errors'); } + + header('Location: ' . $locationTarget); + exit; } } elseif ($action == 'confirm_modif' && $usercancreate) { // Go back to draft status @@ -1460,6 +1506,10 @@ if ($action == 'create' && $usercancreate) { $currency_code = $conf->currency; + $cond_reglement_id = GETPOST('cond_reglement_id', 'int'); + $deposit_percent = GETPOST('cond_reglement_id_deposit_percent', 'alpha'); + $mode_reglement_id = GETPOST('mode_reglement_id', 'int'); + if (!empty($origin) && !empty($originid)) { // Parse element/subelement (ex: project_task) $element = $subelement = $origin; @@ -1475,6 +1525,9 @@ if ($action == 'create' && $usercancreate) { if (!$cond_reglement_id) { $cond_reglement_id = $soc->cond_reglement_id; } + if (!$deposit_percent) { + $deposit_percent = $soc->deposit_percent; + } if (!$mode_reglement_id) { $mode_reglement_id = $soc->mode_reglement_id; } @@ -1515,6 +1568,7 @@ if ($action == 'create' && $usercancreate) { $soc = $objectsrc->thirdparty; $cond_reglement_id = (!empty($objectsrc->cond_reglement_id) ? $objectsrc->cond_reglement_id : (!empty($soc->cond_reglement_id) ? $soc->cond_reglement_id : 0)); // TODO maybe add default value option + $deposit_percent = (!empty($objectsrc->deposit_percent) ? $objectsrc->deposit_percent : (!empty($soc->deposit_percent) ? $soc->deposit_percent : null)); $mode_reglement_id = (!empty($objectsrc->mode_reglement_id) ? $objectsrc->mode_reglement_id : (!empty($soc->mode_reglement_id) ? $soc->mode_reglement_id : 0)); $fk_account = (!empty($objectsrc->fk_account) ? $objectsrc->fk_account : (!empty($soc->fk_account) ? $soc->fk_account : 0)); $availability_id = (!empty($objectsrc->availability_id) ? $objectsrc->availability_id : 0); @@ -1547,6 +1601,7 @@ if ($action == 'create' && $usercancreate) { } } else { $cond_reglement_id = $soc->cond_reglement_id; + $deposit_percent = $soc->deposit_percent; $mode_reglement_id = $soc->mode_reglement_id; $fk_account = $soc->fk_account; $availability_id = 0; @@ -1677,8 +1732,8 @@ if ($action == 'create' && $usercancreate) { // Terms of the settlement print ''.$langs->trans('PaymentConditionsShort').''; - print img_picto('', 'payment', 'class="pictofixedwidth"'); - $form->select_conditions_paiements($cond_reglement_id, 'cond_reglement_id', - 1, 1); + print img_picto('', 'paiment', 'class="pictofixedwidth"'); + $form->select_conditions_paiements($cond_reglement_id, 'cond_reglement_id', 1, 1, 0, '', $deposit_percent); print ''; // Payment mode @@ -1967,6 +2022,111 @@ if ($action == 'create' && $usercancreate) { if ($nbMandated > 0 ) $text .= '
'.$langs->trans("mandatoryPeriodNeedTobeSetMsgValidate").'
'; + $deposit_percent_from_payment_terms = getDictionaryValue(MAIN_DB_PREFIX . 'c_payment_term', 'deposit_percent', $object->cond_reglement_id); + + if (! empty($deposit_percent_from_payment_terms) && ! empty($conf->facture->enabled) && ! empty($user->rights->facture->creer)) { + require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; + + $object->fetchObjectLinked(); + + $eligibleForDepositGeneration = true; + + if (array_key_exists('facture', $object->linkedObjects)) { + foreach ($object->linkedObjects['facture'] as $invoice) { + if ($invoice->type == Facture::TYPE_DEPOSIT) { + $eligibleForDepositGeneration = false; + break; + } + } + } + + if ($eligibleForDepositGeneration && array_key_exists('propal', $object->linkedObjects)) { + foreach ($object->linkedObjects['propal'] as $proposal) { + $proposal->fetchObjectLinked(); + + if (array_key_exists('facture', $proposal->linkedObjects)) { + foreach ($proposal->linkedObjects['facture'] as $invoice) { + if ($invoice->type == Facture::TYPE_DEPOSIT) { + $eligibleForDepositGeneration = false; + break 2; + } + } + } + } + } + + + if ($eligibleForDepositGeneration) { + $formquestion[] = array( + 'type' => 'checkbox', + 'tdclass' => '', + 'name' => 'generate_deposit', + 'label' => $form->textwithpicto($langs->trans('GenerateDeposit', $object->deposit_percent), $langs->trans('DepositGenerationPermittedByThePaymentTermsSelected')) + ); + + $formquestion[] = array( + 'type' => 'date', + 'tdclass' => 'fieldrequired showonlyifgeneratedeposit', + 'name' => 'datef', + 'label' => $langs->trans('DateInvoice'), + 'value' => dol_now(), + 'datenow' => true + ); + + if (! empty($conf->global->INVOICE_POINTOFTAX_DATE)) { + $formquestion[] = array( + 'type' => 'date', + 'tdclass' => 'fieldrequired showonlyifgeneratedeposit', + 'name' => 'date_pointoftax', + 'label' => $langs->trans('DatePointOfTax'), + 'value' => dol_now(), + 'datenow' => true + ); + } + + ob_start(); + $form->select_conditions_paiements(0, 'cond_reglement_id', -1, 0, 0, 'minwidth200'); + $paymentTermsSelect = ob_get_clean(); + + $formquestion[] = array( + 'type' => 'other', + 'tdclass' => 'fieldrequired showonlyifgeneratedeposit', + 'name' => 'cond_reglement_id', + 'label' => $langs->trans('PaymentTerm'), + 'value' => $paymentTermsSelect + ); + + $formquestion[] = array( + 'type' => 'checkbox', + 'tdclass' => 'showonlyifgeneratedeposit', + 'name' => 'validate_generated_deposit', + 'label' => $langs->trans('ValidateGeneratedDeposit') + ); + + $formquestion[] = array( + 'type' => 'onecolumn', + 'value' => ' + + ' + ); + } + } + if (!$error) { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateOrder'), $text, 'confirm_validate', $formquestion, 0, 1, 220); } @@ -2270,9 +2430,9 @@ if ($action == 'create' && $usercancreate) { print $form->editfieldkey("PaymentConditionsShort", 'conditions', '', $object, $editenable); print ''; if ($action == 'editconditions') { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'cond_reglement_id', 1); + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'cond_reglement_id', 1, '', 1, $object->deposit_percent); } else { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'none', 1); + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'none', 1, '', 1, $object->deposit_percent); } print ''; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 58395162f87..ca149d1f681 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -134,6 +134,11 @@ class Commande extends CommonOrder */ public $cond_reglement_code; + /** + * @var double Deposit % for payment terms + */ + public $deposit_percent; + /** * @var int bank account ID */ @@ -332,6 +337,7 @@ class Commande extends CommonOrder 'fk_account' =>array('type'=>'integer', 'label'=>'BankAccount', 'enabled'=>1, 'visible'=>-1, 'position'=>170), 'fk_currency' =>array('type'=>'varchar(3)', 'label'=>'MulticurrencyID', 'enabled'=>1, 'visible'=>-1, 'position'=>175), 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>-1, 'position'=>180), + 'deposit_percent' =>array('type'=>'varchar(63)', 'label'=>'DepositPercent', 'enabled'=>1, 'visible'=>-1, 'position'=>181), 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'PaymentMode', 'enabled'=>1, 'visible'=>-1, 'position'=>185), 'date_livraison' =>array('type'=>'date', 'label'=>'DateDeliveryPlanned', 'enabled'=>1, 'visible'=>-1, 'position'=>190), 'fk_shipping_method' =>array('type'=>'integer', 'label'=>'ShippingMethod', 'enabled'=>1, 'visible'=>-1, 'position'=>195), @@ -940,7 +946,7 @@ class Commande extends CommonOrder $sql = "INSERT INTO ".MAIN_DB_PREFIX."commande ("; $sql .= " ref, fk_soc, date_creation, fk_user_author, fk_projet, date_commande, source, note_private, note_public, ref_ext, ref_client, ref_int"; - $sql .= ", model_pdf, fk_cond_reglement, fk_mode_reglement, fk_account, fk_availability, fk_input_reason, date_livraison, fk_delivery_address"; + $sql .= ", model_pdf, fk_cond_reglement, deposit_percent, fk_mode_reglement, fk_account, fk_availability, fk_input_reason, date_livraison, fk_delivery_address"; $sql .= ", fk_shipping_method"; $sql .= ", fk_warehouse"; $sql .= ", remise_absolue, remise_percent"; @@ -961,6 +967,7 @@ class Commande extends CommonOrder $sql .= ", ".($this->ref_int ? "'".$this->db->escape($this->ref_int)."'" : "null"); $sql .= ", '".$this->db->escape($this->model_pdf)."'"; $sql .= ", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) : "null"); + $sql .= ", ".(! empty($this->deposit_percent) ? "'".$this->db->escape($this->deposit_percent)."'" : "null"); $sql .= ", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) : "null"); $sql .= ", ".($this->fk_account > 0 ? ((int) $this->fk_account) : 'NULL'); $sql .= ", ".($this->availability_id > 0 ? ((int) $this->availability_id) : "null"); @@ -1212,6 +1219,7 @@ class Commande extends CommonOrder if ($objsoc->fetch($socid) > 0) { $this->socid = $objsoc->id; $this->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0); + $this->deposit_percent = (!empty($objsoc->deposit_percent) ? $objsoc->deposit_percent : null); $this->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0); $this->fk_project = 0; $this->fk_delivery_address = 0; @@ -1354,6 +1362,7 @@ class Commande extends CommonOrder $this->socid = $object->socid; $this->fk_project = $object->fk_project; $this->cond_reglement_id = $object->cond_reglement_id; + $this->deposit_percent = $object->deposit_percent; $this->mode_reglement_id = $object->mode_reglement_id; $this->fk_account = $object->fk_account; $this->availability_id = $object->availability_id; @@ -1811,7 +1820,7 @@ class Commande extends CommonOrder } $sql = 'SELECT c.rowid, c.entity, c.date_creation, c.ref, c.fk_soc, c.fk_user_author, c.fk_user_valid, c.fk_user_modif, c.fk_statut'; - $sql .= ', c.amount_ht, c.total_ht, c.total_ttc, c.total_tva, c.localtax1 as total_localtax1, c.localtax2 as total_localtax2, c.fk_cond_reglement, c.fk_mode_reglement, c.fk_availability, c.fk_input_reason'; + $sql .= ', c.amount_ht, c.total_ht, c.total_ttc, c.total_tva, c.localtax1 as total_localtax1, c.localtax2 as total_localtax2, c.fk_cond_reglement, c.deposit_percent, c.fk_mode_reglement, c.fk_availability, c.fk_input_reason'; $sql .= ', c.fk_account'; $sql .= ', c.date_commande, c.date_valid, c.tms'; $sql .= ', c.date_livraison as delivery_date'; @@ -1904,6 +1913,7 @@ class Commande extends CommonOrder $this->cond_reglement_code = $obj->cond_reglement_code; $this->cond_reglement = $obj->cond_reglement_libelle; $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc; + $this->deposit_percent = $obj->deposit_percent; $this->fk_account = $obj->fk_account; $this->availability_id = $obj->fk_availability; $this->availability_code = $obj->availability_code; @@ -3340,6 +3350,7 @@ class Commande extends CommonOrder $sql .= " fk_user_valid=".(isset($this->user_valid) ? $this->user_valid : "null").","; $sql .= " fk_projet=".(isset($this->fk_project) ? $this->fk_project : "null").","; $sql .= " fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id : "null").","; + $sql .= " deposit_percent=".(! empty($this->deposit_percent) ? strval($this->deposit_percent) : "null").","; $sql .= " fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id : "null").","; $sql .= " date_livraison=".(strval($this->delivery_date) != '' ? "'".$this->db->idate($this->delivery_date)."'" : 'null').","; $sql .= " fk_shipping_method=".(isset($this->shipping_method_id) ? $this->shipping_method_id : "null").","; diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index e1a08d47f3f..b2bf9615d17 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -267,7 +267,7 @@ if (empty($reshook)) { $search_project = ''; $search_status = ''; $search_billed = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); $search_categ_cus = 0; $search_datecloture_start = ''; @@ -787,7 +787,7 @@ $sql .= ' c.date_valid, c.date_commande, c.note_public, c.note_private, c.date_l $sql .= ' c.date_creation as date_creation, c.tms as date_update, c.date_cloture as date_cloture,'; $sql .= ' p.rowid as project_id, p.ref as project_ref, p.title as project_label,'; $sql .= ' u.login, u.lastname, u.firstname, u.email as user_email, u.statut as user_statut, u.entity, u.photo, u.office_phone, u.office_fax, u.user_mobile, u.job, u.gender,'; -$sql .= ' c.fk_cond_reglement,c.fk_mode_reglement,c.fk_shipping_method,'; +$sql .= ' c.fk_cond_reglement,c.deposit_percent,c.fk_mode_reglement,c.fk_shipping_method,'; $sql .= ' c.fk_input_reason, c.import_key'; if (($search_categ_cus > 0) || ($search_categ_cus == -2)) { $sql .= ", cc.fk_categorie, cc.fk_soc"; @@ -1479,7 +1479,7 @@ if ($resql) { // Payment term if (!empty($arrayfields['c.fk_cond_reglement']['checked'])) { print ''; - $form->select_conditions_paiements($search_fk_cond_reglement, 'search_fk_cond_reglement', -1, 1, 1); + $form->select_conditions_paiements($search_fk_cond_reglement, 'search_fk_cond_reglement', 1, 1, 1); print ''; } // Payment mode @@ -2032,7 +2032,7 @@ if ($resql) { // Payment terms if (!empty($arrayfields['c.fk_cond_reglement']['checked'])) { print ''; - $form->form_conditions_reglement($_SERVER['PHP_SELF'], $obj->fk_cond_reglement, 'none'); + $form->form_conditions_reglement($_SERVER['PHP_SELF'], $obj->fk_cond_reglement, 'none', 0, '', 1, $obj->deposit_percent); print ''; if (!$i) { $totalarray['nbfield']++; diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index 4d133c50dda..05b30d69668 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -214,7 +214,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_thirdparty_user = ''; $search_num_releve = ''; $search_conciliated = ''; - $toselect = ''; + $toselect = array(); $search_account = ""; if ($id > 0 || !empty($ref)) { diff --git a/htdocs/compta/cashcontrol/cashcontrol_list.php b/htdocs/compta/cashcontrol/cashcontrol_list.php index 7822819c06a..2315f12757a 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_list.php +++ b/htdocs/compta/cashcontrol/cashcontrol_list.php @@ -165,7 +165,7 @@ if (empty($reshook)) { $search[$key.'_dtend'] = ''; } } - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 0a13114fbbc..e3fac863c77 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -3287,10 +3287,21 @@ if ($action == 'create') { 'variable' => $langs->transnoentitiesnoconv('VarAmountOneLine', $langs->transnoentitiesnoconv('Deposit')), 'variablealllines' => $langs->transnoentitiesnoconv('VarAmountAllLines') ); - print $form->selectarray('typedeposit', $arraylist, GETPOST('typedeposit', 'aZ09'), 0, 0, 0, '', 1); + $typedeposit = GETPOST('typedeposit', 'aZ09'); + $valuedeposit = GETPOST('valuedeposit', 'int'); + if (empty($typedeposit) && ! empty($objectsrc->deposit_percent)) { + $origin_payment_conditions_deposit_percent = getDictionaryValue(MAIN_DB_PREFIX . 'c_payment_term', 'deposit_percent', $objectsrc->cond_reglement_id); + if (! empty($origin_payment_conditions_deposit_percent)) { + $typedeposit = 'variable'; + } + } + if (empty($valuedeposit) && $typedeposit == 'variable' && ! empty($objectsrc->deposit_percent)) { + $valuedeposit = $objectsrc->deposit_percent; + } + print $form->selectarray('typedeposit', $arraylist, $typedeposit, 0, 0, 0, '', 1); print ''; print ''; - print ''.$langs->trans("AmountOrPercent").''; + print ''.$langs->trans("AmountOrPercent").''; print ''; } print ''; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index b3175949376..0804f55b1ee 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1463,6 +1463,292 @@ class Facture extends CommonInvoice } } + /** + * Creates a deposit from a proposal or an order by grouping lines by VAT rates + * + * @param Propal|Commande $origin The original proposal or order + * @param int $date Invoice date + * @param int $payment_terms_id Invoice payment terms + * @param User $user Object user + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @param bool $autoValidateDeposit Whether to aumatically validate the deposit created + * @param array $overrideFields Array of fields to force values + * @return Facture|null The deposit created, or null if error (populates $origin->error in this case) + */ + static public function createDepositFromOrigin(CommonObject $origin, $date, $payment_terms_id, User $user, $notrigger = 0, $autoValidateDeposit = false, $overrideFields = array()) + { + global $conf, $langs, $hookmanager, $action; + + if (! in_array($origin->element, array('propal', 'commande'))) { + $origin->error = 'ErrorCanOnlyAutomaticallyGenerateADepositFromProposalOrOrder'; + return null; + } + + if (empty($date)) { + $origin->error = $langs->trans('ErrorFieldRequired', $langs->transnoentities('DateInvoice')); + return null; + } + + require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php'; + + if ($date > (dol_get_last_hour(dol_now('tzuserrel')) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { + $origin->error = 'ErrorDateIsInFuture'; + return null; + } + + if ($payment_terms_id <= 0) { + $origin->error = $langs->trans('ErrorFieldRequired', $langs->transnoentities('PaymentConditionsShort')); + return null; + } + + $payment_conditions_deposit_percent = getDictionaryValue(MAIN_DB_PREFIX . 'c_payment_term', 'deposit_percent', $origin->cond_reglement_id); + + if (empty($payment_conditions_deposit_percent)) { + $origin->error = 'ErrorPaymentConditionsNotEligibleToDepositCreation'; + return null; + } + + if (empty($origin->deposit_percent)) { + $origin->error = $langs->trans('ErrorFieldRequired', $langs->transnoentities('DepositPercent')); + return null; + } + + $deposit = new self($origin->db); + $deposit->socid = $origin->socid; + $deposit->type = self::TYPE_DEPOSIT; + $deposit->fk_project = $origin->fk_project; + $deposit->ref_client = $origin->ref_client; + $deposit->date = $date; + $deposit->mode_reglement_id = $origin->mode_reglement_id; + $deposit->cond_reglement_id = $payment_terms_id; + $deposit->availability_id = $origin->availability_id; + $deposit->demand_reason_id = $origin->demand_reason_id; + $deposit->fk_account = $origin->fk_account; + $deposit->fk_incoterms = $origin->fk_incoterms; + $deposit->location_incoterms = $origin->location_incoterms; + $deposit->fk_multicurrency = $origin->fk_multicurrency; + $deposit->multicurrency_code = $origin->multicurrency_code; + $deposit->multicurrency_tx = $origin->multicurrency_tx; + $deposit->module_source = $origin->module_source; + $deposit->pos_source = $origin->pos_source; + $deposit->model_pdf = 'crabe'; + + $modelByTypeConfName = 'FACTURE_ADDON_PDF_' . $deposit->type; + + if (!empty($conf->global->$modelByTypeConfName)) { + $deposit->model_pdf = $conf->global->$modelByTypeConfName; + } elseif (!empty($conf->global->FACTURE_ADDON_PDF)) { + $deposit->model_pdf = $conf->global->FACTURE_ADDON_PDF; + } + + if (empty($conf->global->MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN)) { + $deposit->note_private = $origin->note_private; + $deposit->note_public = $origin->note_public; + } + + $deposit->origin = $origin->element; + $deposit->origin_id = $origin->id; + + $origin->fetch_optionals(); + + foreach ($origin->array_options as $extrakey => $value) { + $deposit->array_options[$extrakey] = $value; + } + + $deposit->linked_objects[$deposit->origin] = $deposit->origin_id; + + foreach ($overrideFields as $key => $value) { + $deposit->$key = $value; + } + + $deposit->context['createdepositfromorigin'] = 'createdepositfromorigin'; + + $origin->db->begin(); + + // Facture::create() also imports contact from origin + $createReturn = $deposit->create($user, $notrigger); + + if ($createReturn <= 0) { + $origin->db->rollback(); + $origin->error = $deposit->error; + $origin->errors = $deposit->errors; + return null; + } + + $amount_ttc_diff = 0; + $amountdeposit = array(); + $descriptions = array(); + + if (! empty($conf->global->MAIN_DEPOSIT_MULTI_TVA)) { + $amount = $origin->total_ttc * ($origin->deposit_percent / 100); + + $TTotalByTva = array(); + foreach ($origin->lines as &$line) { + if (!empty($line->special_code)) { + continue; + } + $TTotalByTva[$line->tva_tx] += $line->total_ttc; + $descriptions[$line->tva_tx] .= '
  • ' . (! empty($line->product_ref) ? $line->product_ref . ' - ' : ''); + $descriptions[$line->tva_tx] .= (! empty($line->product_label) ? $line->product_label . ' - ' : ''); + $descriptions[$line->tva_tx] .= $langs->trans('Qty') . ' : ' . $line->qty; + $descriptions[$line->tva_tx] .= ' - ' . $langs->trans('TotalHT') . ' : ' . price($line->total_ht) . '
  • '; + } + + foreach ($TTotalByTva as $tva => &$total) { + $coef = $total / $origin->total_ttc; // Calc coef + $am = $amount * $coef; + $amount_ttc_diff += $am; + $amountdeposit[$tva] += $am / (1 + $tva / 100); // Convert into HT for the addline + } + } else { + $totalamount = 0; + $lines = $origin->lines; + $numlines = count($lines); + for ($i = 0; $i < $numlines; $i++) { + if (empty($lines[$i]->qty)) { + continue; // We discard qty=0, it is an option + } + if (!empty($lines[$i]->special_code)) { + continue; // We discard special_code (frais port, ecotaxe, option, ...) + } + + $totalamount += $lines[$i]->total_ht; // Fixme : is it not for the customer ? Shouldn't we take total_ttc ? + $tva_tx = $lines[$i]->tva_tx; + $amountdeposit[$tva_tx] += ($lines[$i]->total_ht * $origin->deposit_percent) / 100; + $descriptions[$tva_tx] .= '
  • ' . (! empty($lines[$i]->product_ref) ? $lines[$i]->product_ref . ' - ' : ''); + $descriptions[$tva_tx] .= (! empty($lines[$i]->product_label) ? $lines[$i]->product_label . ' - ' : ''); + $descriptions[$tva_tx] .= $langs->trans('Qty') . ' : ' . $lines[$i]->qty; + $descriptions[$tva_tx] .= ' - ' . $langs->trans('TotalHT') . ' : ' . price($lines[$i]->total_ht) . '
  • '; + } + + if ($totalamount == 0) { + $amountdeposit[0] = 0; + } + + $amount_ttc_diff = $amountdeposit[0]; + } + + foreach ($amountdeposit as $tva => $amount) { + if (empty($amount)) { + continue; + } + + $descline = '(DEPOSIT) ('. $origin->deposit_percent .'%) - '.$origin->ref; + + // Hidden conf + if (! empty($conf->global->INVOICE_DEPOSIT_VARIABLE_MODE_DETAIL_LINES_IN_DESCRIPTION) && ! empty($descriptions[$tva])) { + $descline .= ''; + } + + $addlineResult = $deposit->addline( + $descline, + $amount, // subprice + 1, // quantity + $tva, // vat rate + 0, // localtax1_tx + 0, // localtax2_tx + (empty($conf->global->INVOICE_PRODUCTID_DEPOSIT) ? 0 : $conf->global->INVOICE_PRODUCTID_DEPOSIT), // fk_product + 0, // remise_percent + 0, // date_start + 0, // date_end + 0, + $lines[$i]->info_bits, // info_bits + 0, + 'HT', + 0, + 0, // product_type + 1, + $lines[$i]->special_code, + $deposit->origin, + 0, + 0, + 0, + 0 + //,$langs->trans('Deposit') //Deprecated + ); + + if ($addlineResult < 0) { + $origin->db->rollback(); + $origin->error = $deposit->error; + $origin->errors = $deposit->errors; + return null; + } + } + + $diff = $deposit->total_ttc - $amount_ttc_diff; + + if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA) && $diff != 0) { + $deposit->fetch_lines(); + $subprice_diff = $deposit->lines[0]->subprice - $diff / (1 + $deposit->lines[0]->tva_tx / 100); + + $updatelineResult = $deposit->updateline( + $deposit->lines[0]->id, + $deposit->lines[0]->desc, + $subprice_diff, + $deposit->lines[0]->qty, + $deposit->lines[0]->remise_percent, + $deposit->lines[0]->date_start, + $deposit->lines[0]->date_end, + $deposit->lines[0]->tva_tx, + 0, + 0, + 'HT', + $deposit->lines[0]->info_bits, + $deposit->lines[0]->product_type, + 0, + 0, + 0, + $deposit->lines[0]->pa_ht, + $deposit->lines[0]->label, + 0, + array(), + 100 + ); + + if ($updatelineResult < 0) { + $origin->db->rollback(); + $origin->error = $deposit->error; + $origin->errors = $deposit->errors; + return null; + } + } + + + if (! is_object($hookmanager)) { + require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($origin->db); + } + + $hookmanager->initHooks(array('invoicedao')); + + $parameters = array('objFrom' => $origin); + $reshook = $hookmanager->executeHooks('createFrom', $parameters, $deposit, $action); // Note that $action and $object may have been + // modified by hook + if ($reshook < 0) { + $origin->db->rollback(); + $origin->error = $hookmanager->error; + $origin->errors = $hookmanager->errors; + return null; + } + + if (! empty($autoValidateDeposit)) { + $validateReturn = $deposit->validate($user, '', 0, $notrigger); + + if ($validateReturn < 0) { + $origin->db->rollback(); + $origin->error = $deposit->error; + $origin->errors = $deposit->errors; + return null; + } + } + + unset($deposit->context['createdepositfromorigin']); + + $origin->db->commit(); + + return $deposit; + } + /** * Return clicable link of object (with eventually picto) * diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index f3173b0ac22..2ef50801717 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -366,7 +366,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', $search_fac_rec_source_title = ''; $option = ''; $filter = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); $search_categ_cus = 0; } diff --git a/htdocs/compta/paiement/list.php b/htdocs/compta/paiement/list.php index d2ed6b939c8..3d0698118ff 100644 --- a/htdocs/compta/paiement/list.php +++ b/htdocs/compta/paiement/list.php @@ -148,7 +148,7 @@ if (empty($reshook)) { $search_company = ''; $search_status = ''; $option = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } } diff --git a/htdocs/compta/sociales/payments.php b/htdocs/compta/sociales/payments.php index 77230bac407..43e9d5d4668 100644 --- a/htdocs/compta/sociales/payments.php +++ b/htdocs/compta/sociales/payments.php @@ -80,7 +80,7 @@ $result = restrictedArea($user, 'tax', '', 'chargesociales', 'charges'); // Purge search criteria if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers $search_sc_type = ''; - //$toselect = ''; + //$toselect = array(); //$search_array_options = array(); } diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index cbcfa2b6efe..57b4657eab4 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -203,7 +203,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_date_end = ''; $sall = ""; $search_status = ""; - $toselect = ''; + $toselect = array(); $search_type_thirdparty = ''; $search_array_options = array(); } @@ -312,6 +312,9 @@ if ($search_zip) { if ($search_town) { $sql .= natural_search(array('s.town'), $search_town); } +if ($search_country && $search_country != '-1') { + $sql .= " AND s.fk_pays IN (".$db->sanitize($search_country).')'; +} if ($search_sale > 0) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $search_sale); } @@ -489,6 +492,9 @@ if ($search_user > 0) { if ($search_type_thirdparty > 0) { $param .= '&search_type_thirdparty='.urlencode($search_type_thirdparty); } +if ($search_country != '') { + $param .= "&search_country=".urlencode($search_country); +} if ($search_product_category > 0) { $param .= '&search_product_category='.urlencode($search_product_category); } diff --git a/htdocs/contrat/services_list.php b/htdocs/contrat/services_list.php index f12d48df44a..1f3ccf70f3a 100644 --- a/htdocs/contrat/services_list.php +++ b/htdocs/contrat/services_list.php @@ -201,7 +201,7 @@ if (empty($reshook)) { $filter_opcloture = ""; $mode = ''; $filter = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } } diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index d7e5812ac9a..383684b377a 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -1302,6 +1302,49 @@ if (!$error && ($massaction == 'disable' || ($action == 'disable' && $confirm == } } +if (!$error && $action == 'confirm_edit_value_extrafields' && $confirm == 'yes' && $permissiontoadd) { + $db->begin(); + + $objecttmp = new $objectclass($db); + $e = new ExtraFields($db);// fetch optionals attributes and labels + $e->fetch_name_optionals_label($objecttmp->table_element); + + $nbok = 0; + $extrafieldKeyToUpdate = GETPOST('extrafield-key-to-update'); + + + foreach ($toselect as $toselectid) { + /** @var CommonObject $objecttmp */ + $objecttmp = new $objectclass($db); // to avoid ghost data + $result = $objecttmp->fetch($toselectid); + if ($result>0) { + // Fill array 'array_options' with data from add form + $ret = $e->setOptionalsFromPost(null, $objecttmp, $extrafieldKeyToUpdate); + if ($ret > 0) { + $objecttmp->insertExtraFields(); + } else { + $error++; + setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); + } + } else { + setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); + $error++; + break; + } + } + + if (!$error) { + if ($nbok > 1) { + setEventMessages($langs->trans("RecordsDisabled", $nbok), null, 'mesgs'); + } else { + setEventMessages($langs->trans("save"), null, 'mesgs'); + } + $db->commit(); + } else { + $db->rollback(); + } +} + if (!$error && ($massaction == 'affectcommercial' || ($action == 'affectcommercial' && $confirm == 'yes')) && $permissiontoadd) { $db->begin(); diff --git a/htdocs/core/boxes/box_members_by_type.php b/htdocs/core/boxes/box_members_by_type.php index 4bbf20e9cbf..23542999b47 100644 --- a/htdocs/core/boxes/box_members_by_type.php +++ b/htdocs/core/boxes/box_members_by_type.php @@ -173,27 +173,34 @@ class box_members_by_type extends ModeleBoxes $line = 0; $this->info_box_contents[$line][] = array( 'td' => 'class=""', - 'text' => $langs->trans("MembersTypes"), + 'text' => '', ); + $labelstatus = $staticmember->LibStatut($staticmember::STATUS_DRAFT, 0, 0, 1); $this->info_box_contents[$line][] = array( - 'td' => 'class="right"', - 'text' => $langs->trans("MembersStatusToValid"), // Draft + 'td' => 'class="right tdoverflowmax100" width="15%" title="'.dol_escape_htmltag($labelstatus).'"', + 'text' => $labelstatus ); + $labelstatus = $langs->trans("UpToDate"); + $labelstatus = $staticmember->LibStatut($staticmember::STATUS_VALIDATED, 1, dol_now() + 86400, 1); $this->info_box_contents[$line][] = array( - 'td' => 'class="right"', - 'text' => $langs->trans("UpToDate"), + 'td' => 'class="right tdoverflowmax100" width="15%" title="'.dol_escape_htmltag($labelstatus).'"', + 'text' => $labelstatus, ); + $labelstatus = $langs->trans("OutOfDate"); + $labelstatus = $staticmember->LibStatut($staticmember::STATUS_VALIDATED, 1, dol_now() - 86400, 1); $this->info_box_contents[$line][] = array( - 'td' => 'class="right"', - 'text' => $langs->trans("OutOfDate"), + 'td' => 'class="right tdoverflowmax100" width="15%" title="'.dol_escape_htmltag($labelstatus).'"', + 'text' => $labelstatus ); + $labelstatus = $staticmember->LibStatut($staticmember::STATUS_EXCLUDED, 0, 0, 1); $this->info_box_contents[$line][] = array( - 'td' => 'class="right"', - 'text' => $langs->trans("MembersStatusExcluded"), + 'td' => 'class="right tdoverflowmax100" width="15%" title="'.dol_escape_htmltag($labelstatus).'"', + 'text' => $labelstatus ); + $labelstatus = $staticmember->LibStatut($staticmember::STATUS_RESILIATED, 0, 0, 1); $this->info_box_contents[$line][] = array( - 'td' => 'class="right"', - 'text' => $langs->trans("MembersStatusResiliated"), + 'td' => 'class="right tdoverflowmax100" width="15%" title="'.dol_escape_htmltag($labelstatus).'"', + 'text' => $labelstatus ); $line++; foreach ($AdherentType as $key => $adhtype) { diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index 246bec42ba4..910e6d3ca77 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -222,7 +222,7 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" box // Show box title if (!empty($head['text']) || !empty($head['sublink']) || !empty($head['subpicto'])) { $out .= ''; - $out .= ' 0) { $out .= ' colspan="'.$nbcol.'"'; } @@ -268,7 +268,7 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" box $out .= ''; } - $out .= ""; + $out .= ""; $out .= "\n"; } diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index e2bd6c5199a..7a4d105cfac 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2588,12 +2588,13 @@ abstract class CommonObject /** * Change the payments terms * - * @param int $id Id of new payment terms - * @return int >0 if OK, <0 if KO + * @param int $id Id of new payment terms + * @param string $deposit_percent % of deposit if needed by payment terms + * @return int >0 if OK, <0 if KO */ - public function setPaymentTerms($id) + public function setPaymentTerms($id, $deposit_percent = null) { - dol_syslog(get_class($this).'::setPaymentTerms('.$id.')'); + dol_syslog(get_class($this).'::setPaymentTerms('.$id.', '.var_export($deposit_percent, true).')'); if ($this->statut >= 0 || $this->element == 'societe') { // TODO uniformize field name $fieldname = 'fk_cond_reglement'; @@ -2604,8 +2605,17 @@ abstract class CommonObject $fieldname = 'cond_reglement_supplier'; } + if (empty($deposit_percent) || $deposit_percent < 0) { + $deposit_percent = getDictionaryValue(MAIN_DB_PREFIX . 'c_payment_term', 'deposit_percent', $id); + } + + if ($deposit_percent > 100) { + $deposit_percent = 100; + } + $sql = 'UPDATE '.$this->db->prefix().$this->table_element; $sql .= " SET ".$fieldname." = ".(($id > 0 || $id == '0') ? ((int) $id) : 'NULL'); + $sql .= " , deposit_percent = " . (! empty($deposit_percent) ? "'".$this->db->escape($deposit_percent)."'" : 'NULL'); $sql .= ' WHERE rowid='.((int) $this->id); if ($this->db->query($sql)) { @@ -2615,6 +2625,7 @@ abstract class CommonObject $this->cond_reglement_supplier_id = $id; } $this->cond_reglement = $id; // for compatibility + $this->deposit_percent = $deposit_percent; return 1; } else { dol_syslog(get_class($this).'::setPaymentTerms Error '.$sql.' - '.$this->db->error()); diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 85f0de5de90..3a396e365d7 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -956,6 +956,8 @@ class ExtraFields $morecss = 'minwidth400'; } elseif ($type == 'boolean') { $morecss = ''; + } elseif ($type == 'radio') { + $morecss = 'width25'; } else { if (empty($size) || round($size) < 12) { $morecss = 'minwidth100'; @@ -1147,7 +1149,7 @@ class ExtraFields $sql = "SELECT ".$keyList; $sql .= ' FROM '.$this->db->prefix().$InfoFieldList[0]; if (!empty($InfoFieldList[4])) { - // can use curent entity filter + // can use current entity filter if (strpos($InfoFieldList[4], '$ENTITY$') !== false) { $InfoFieldList[4] = str_replace('$ENTITY$', $conf->entity, $InfoFieldList[4]); } @@ -1262,7 +1264,7 @@ class ExtraFields $out .= ' value="'.$keyopt.'"'; $out .= ' id="'.$keyprefix.$key.$keysuffix.'_'.$keyopt.'"'; $out .= ($value == $keyopt ? 'checked' : ''); - $out .= '/>
    '; + $out .= '/>
    '; } } elseif ($type == 'chkbxlst') { if (is_array($value)) { @@ -1315,6 +1317,10 @@ class ExtraFields $sql = "SELECT ".$keyList; $sql .= ' FROM '.$this->db->prefix().$InfoFieldList[0]; if (!empty($InfoFieldList[4])) { + // can use current entity filter + if (strpos($InfoFieldList[4], '$ENTITY$') !== false) { + $InfoFieldList[4] = str_replace('$ENTITY$', $conf->entity, $InfoFieldList[4]); + } // can use SELECT request if (strpos($InfoFieldList[4], '$SEL$') !== false) { $InfoFieldList[4] = str_replace('$SEL$', 'SELECT', $InfoFieldList[4]); @@ -1666,7 +1672,7 @@ class ExtraFields dol_syslog(get_class($this).'::showOutputField error '.$this->db->lasterror(), LOG_WARNING); } } elseif ($type == 'radio') { - $value = $param['options'][$value]; + $value = $langs->trans($param['options'][$value]); } elseif ($type == 'checkbox') { $value_arr = explode(',', $value); $value = ''; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 59540db4f1e..c803c83e97a 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3729,7 +3729,7 @@ class Form dol_syslog(__METHOD__, LOG_DEBUG); - $sql = "SELECT rowid, code, libelle as label"; + $sql = "SELECT rowid, code, libelle as label, deposit_percent"; $sql .= " FROM ".$this->db->prefix().'c_payment_term'; $sql .= " WHERE entity IN (".getEntity('c_payment_term').")"; $sql .= " AND active > 0"; @@ -3746,6 +3746,7 @@ class Form $label = ($langs->trans("PaymentConditionShort".$obj->code) != ("PaymentConditionShort".$obj->code) ? $langs->trans("PaymentConditionShort".$obj->code) : ($obj->label != '-' ? $obj->label : '')); $this->cache_conditions_paiements[$obj->rowid]['code'] = $obj->code; $this->cache_conditions_paiements[$obj->rowid]['label'] = $label; + $this->cache_conditions_paiements[$obj->rowid]['deposit_percent'] = $obj->deposit_percent; $i++; } @@ -3991,39 +3992,45 @@ class Form // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * print list of payment modes. - * Constant MAIN_DEFAULT_PAYMENT_TERM_ID can used to set default value but scope is all application, probably not what you want. - * See instead to force the default value by the caller. + * print list of payment modes. + * Constant MAIN_DEFAULT_PAYMENT_TERM_ID can used to set default value but scope is all application, probably not what you want. + * See instead to force the default value by the caller. * - * @param int $selected Id of payment term to preselect by default - * @param string $htmlname Nom de la zone select - * @param int $filtertype Not used - * @param int $addempty Add an empty entry - * @param int $noinfoadmin 0=Add admin info, 1=Disable admin info - * @param string $morecss Add more CSS on select tag - * @return void + * @param int $selected Id of payment term to preselect by default + * @param string $htmlname Nom de la zone select + * @param int $filtertype If > 0, include payment terms with deposit percentage (for objects other than invoices and invoice templates) + * @param int $addempty Add an empty entry + * @param int $noinfoadmin 0=Add admin info, 1=Disable admin info + * @param string $morecss Add more CSS on select tag + * @param string $deposit_percent < 0 : deposit_percent input makes no sense (for example, in list filters) + * 0 : use default deposit percentage from entry + * > 0 : force deposit percentage (for example, from company object) + * @return void */ - public function select_conditions_paiements($selected = 0, $htmlname = 'condid', $filtertype = -1, $addempty = 0, $noinfoadmin = 0, $morecss = '') + public function select_conditions_paiements($selected = 0, $htmlname = 'condid', $filtertype = -1, $addempty = 0, $noinfoadmin = 0, $morecss = '', $deposit_percent = -1) { // phpcs:enable - print $this->getSelectConditionsPaiements($selected, $htmlname, $filtertype, $addempty, $noinfoadmin, $morecss); + print $this->getSelectConditionsPaiements($selected, $htmlname, $filtertype, $addempty, $noinfoadmin, $morecss, $deposit_percent = -1); } /** - * Return list of payment modes. - * Constant MAIN_DEFAULT_PAYMENT_TERM_ID can used to set default value but scope is all application, probably not what you want. - * See instead to force the default value by the caller. + * Return list of payment modes. + * Constant MAIN_DEFAULT_PAYMENT_TERM_ID can used to set default value but scope is all application, probably not what you want. + * See instead to force the default value by the caller. * - * @param int $selected Id of payment term to preselect by default - * @param string $htmlname Nom de la zone select - * @param int $filtertype Not used - * @param int $addempty Add an empty entry - * @param int $noinfoadmin 0=Add admin info, 1=Disable admin info - * @param string $morecss Add more CSS on select tag - * @return void + * @param int $selected Id of payment term to preselect by default + * @param string $htmlname Nom de la zone select + * @param int $filtertype If > 0, include payment terms with deposit percentage (for objects other than invoices and invoice templates) + * @param int $addempty Add an empty entry + * @param int $noinfoadmin 0=Add admin info, 1=Disable admin info + * @param string $morecss Add more CSS on select tag + * @param string $deposit_percent < 0 : deposit_percent input makes no sense (for example, in list filters) + * 0 : use default deposit percentage from entry + * > 0 : force deposit percentage (for example, from company object) + * @return string */ - public function getSelectConditionsPaiements($selected = 0, $htmlname = 'condid', $filtertype = -1, $addempty = 0, $noinfoadmin = 0, $morecss = '') + public function getSelectConditionsPaiements($selected = 0, $htmlname = 'condid', $filtertype = -1, $addempty = 0, $noinfoadmin = 0, $deposit_percent = -1) { global $langs, $user, $conf; @@ -4041,20 +4048,59 @@ class Form if ($addempty) { $out.= ''; } + + $selectedDepositPercent = null; + foreach ($this->cache_conditions_paiements as $id => $arrayconditions) { - if ($selected == $id) { - $out.= ''; + + if ($selected == $id) { + $selectedDepositPercent = $deposit_percent > 0 ? $deposit_percent : $arrayconditions['deposit_percent']; + $out .= ''; } $out.= ''; if ($user->admin && empty($noinfoadmin)) { $out.= info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); } $out.= ajax_combobox($htmlname); + + if ($deposit_percent >= 0) { + $out .= ' '; + $out .= ' + '; + } + return $out; } @@ -5245,14 +5291,18 @@ class Form /** * Show a form to select payment conditions * - * @param int $page Page - * @param string $selected Id condition pre-selectionne - * @param string $htmlname Name of select html field - * @param int $addempty Add empty entry - * @param string $type Type ('direct-debit' or 'bank-transfer') + * @param int $page Page + * @param string $selected Id condition pre-selectionne + * @param string $htmlname Name of select html field + * @param int $addempty Add empty entry + * @param string $type Type ('direct-debit' or 'bank-transfer') + * @param int $filtertype If > 0, include payment terms with deposit percentage (for objects other than invoices and invoice templates) + * @param string $deposit_percent < 0 : deposit_percent input makes no sense (for example, in list filters) + * 0 : use default deposit percentage from entry + * > 0 : force deposit percentage (for example, from company object) * @return void */ - public function form_conditions_reglement($page, $selected = '', $htmlname = 'cond_reglement_id', $addempty = 0, $type = '') + public function form_conditions_reglement($page, $selected = '', $htmlname = 'cond_reglement_id', $addempty = 0, $type = '', $filtertype = -1, $deposit_percent = -1) { // phpcs:enable global $langs; @@ -5263,14 +5313,20 @@ class Form if ($type) { print ''; } - $this->select_conditions_paiements($selected, $htmlname, -1, $addempty, 0, ''); + $this->select_conditions_paiements($selected, $htmlname, $filtertype, $addempty, 0, '', $deposit_percent); print ''; print ''; } else { if ($selected) { $this->load_cache_conditions_paiements(); if (isset($this->cache_conditions_paiements[$selected])) { - print $this->cache_conditions_paiements[$selected]['label']; + $label = $this->cache_conditions_paiements[$selected]['label']; + + if (! empty($this->cache_conditions_paiements[$selected]['deposit_percent'])) { + $label = str_replace('__DEPOSIT_PERCENT__', $deposit_percent > 0 ? $deposit_percent : $this->cache_conditions_paiements[$selected]['deposit_percent'], $label); + } + + print $label; } else { $langs->load('errors'); print $langs->trans('ErrorNotInDictionaryPaymentConditions'); @@ -7226,6 +7282,8 @@ class Form unset($adherenttmpselect); } + $urloption = ''; + $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/adherents/ajax/adherents.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 1, $ajaxoptions); if (empty($hidelabel)) $out .= $langs->trans("RefOrLabel").' : '; @@ -7240,7 +7298,9 @@ class Form $out .= img_picto($langs->trans("Search"), 'search'); } } else { - $out .= $this->selectMembersList($selected, $htmlname, $filtertype, $limit, $status, 0, $socid, $showempty, $forcecombo, $morecss); + $filterkey = ''; + + $out .= $this->selectMembersList($selected, $htmlname, $filtertype, $limit, $filterkey, $status, 0, $showempty, $forcecombo, $morecss); } if (empty($nooutput)) print $out; @@ -7255,8 +7315,8 @@ class Form * @param string $htmlname Name of select html * @param string $filtertype Filter on adherent type * @param int $limit Limit on number of returned lines - * @param string $filterkey Filter on adherent ref or subject - * @param int $status Ticket status + * @param string $filterkey Filter on member status + * @param int $status Member status * @param int $outputmode 0=HTML select string, 1=Array * @param string $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. * @param int $forcecombo Force to use combo box @@ -7270,7 +7330,7 @@ class Form $out = ''; $outarray = array(); - $selectFields = " p.rowid, p.ref"; + $selectFields = " p.rowid, p.ref, p.firstname, p.lastname"; $sql = "SELECT "; $sql .= $selectFields; @@ -7280,21 +7340,23 @@ class Form // Add criteria on ref/label if ($filterkey != '') { $sql .= ' AND ('; - $prefix = empty($conf->global->TICKET_DONOTSEARCH_ANYWHERE) ? '%' : ''; // Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on + $prefix = empty($conf->global->MEMBER_DONOTSEARCH_ANYWHERE) ? '%' : ''; // Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on // For natural search $scrit = explode(' ', $filterkey); $i = 0; if (count($scrit) > 1) $sql .= "("; foreach ($scrit as $crit) { if ($i > 0) $sql .= " AND "; - $sql .= "p.ref LIKE '".$this->db->escape($prefix.$crit)."%'"; - $sql .= ""; + $sql .= "(p.firstname LIKE '".$this->db->escape($prefix.$crit)."%'"; + $sql .= " OR p.lastname LIKE '".$this->db->escape($prefix.$crit)."%')"; $i++; } if (count($scrit) > 1) $sql .= ")"; $sql .= ')'; } - + if ($status != -1) { + $sql .= ' AND statut = '.((int) $status); + } $sql .= $this->db->plimit($limit, 0); // Build output string @@ -7324,7 +7386,9 @@ class Form } else { if ($showempty && !is_numeric($showempty)) $textifempty = $langs->trans($showempty); } - if ($showempty) $out .= ''; + if ($showempty) { + $out .= ''; + } $i = 0; while ($num && $i < $num) { @@ -7333,6 +7397,7 @@ class Form $objp = $this->db->fetch_object($result); $this->constructMemberListOption($objp, $opt, $optJson, $selected, $filterkey); + // Add new entry // "key" value of json key array is used by jQuery automatically as selected value // "label" value of json key array is used by jQuery automatically as text for combo box @@ -7367,28 +7432,23 @@ class Form protected function constructMemberListOption(&$objp, &$opt, &$optJson, $selected, $filterkey = '') { $outkey = ''; - $outval = ''; - $outref = ''; $outlabel = ''; $outtype = ''; - $label = $objp->label; - $outkey = $objp->rowid; - $outref = $objp->ref; - $outlabel = $objp->label; - $outtype = $objp->fk_product_type; + $outlabel = dolGetFirstLastname($objp->firstname, $objp->lastname); + $outtype = $objp->fk_adherent_type; $opt = '\n"; - $optJson = array('key'=>$outkey, 'value'=>$outref, 'type'=>$outtype); + + $optJson = array('key'=>$outkey, 'value'=>$outlabel, 'type'=>$outtype); } /** diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index 9e2c45fd634..6f54229c993 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -234,7 +234,7 @@ class Ldap } } - if (is_resource($this->connection)) { + if (is_resource($this->connection) || is_object($this->connection)) { // Upgrade connexion to TLS, if requested by the configuration if (!empty($conf->global->LDAP_SERVER_USE_TLS)) { // For test/debug diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index 27f3ca1c836..94bd36799fc 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -1089,11 +1089,12 @@ class Translate $i = 0; while ($i < $num) { $obj = $db->fetch_object($resql); - - // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut - $this->cache_currencies[$obj->code_iso]['label'] = ($obj->code_iso && $this->trans("Currency".$obj->code_iso) != "Currency".$obj->code_iso ? $this->trans("Currency".$obj->code_iso) : ($obj->label != '-' ? $obj->label : '')); - $this->cache_currencies[$obj->code_iso]['unicode'] = (array) json_decode($obj->unicode, true); - $label[$obj->code_iso] = $this->cache_currencies[$obj->code_iso]['label']; + if ($obj) { + // If a translation exists, we use it lese we use the default label + $this->cache_currencies[$obj->code_iso]['label'] = ($obj->code_iso && $this->trans("Currency".$obj->code_iso) != "Currency".$obj->code_iso ? $this->trans("Currency".$obj->code_iso) : ($obj->label != '-' ? $obj->label : '')); + $this->cache_currencies[$obj->code_iso]['unicode'] = (array) json_decode($obj->unicode, true); + $label[$obj->code_iso] = $this->cache_currencies[$obj->code_iso]['label']; + } $i++; } if (empty($currency_code)) { diff --git a/htdocs/core/db/Database.interface.php b/htdocs/core/db/Database.interface.php index e349072ddec..1d24b058614 100644 --- a/htdocs/core/db/Database.interface.php +++ b/htdocs/core/db/Database.interface.php @@ -502,8 +502,8 @@ interface Database /** * Returns the current line (as an object) for the resultset cursor * - * @param resource $resultset Cursor of the desired request - * @return Object Object result line or false if KO or end of cursor + * @param resource|Connection $resultset Handler of the desired request + * @return Object Object result line or false if KO or end of cursor */ public function fetch_object($resultset); // phpcs:enable diff --git a/htdocs/core/db/pgsql.class.php b/htdocs/core/db/pgsql.class.php index 74abf7a1e36..5a2a1c1b753 100644 --- a/htdocs/core/db/pgsql.class.php +++ b/htdocs/core/db/pgsql.class.php @@ -116,7 +116,7 @@ class DoliDBPgsql extends DoliDB $this->connected = false; $this->ok = false; $this->error = 'Host, login or password incorrect'; - dol_syslog(get_class($this)."::DoliDBPgsql : Erreur Connect ".$this->error, LOG_ERR); + dol_syslog(get_class($this)."::DoliDBPgsql : Erreur Connect ".$this->error.'. Failed to connect to host='.$host.' port='.$port.' user='.$user, LOG_ERR); } // Si connexion serveur ok et si connexion base demandee, on essaie connexion base @@ -423,7 +423,7 @@ class DoliDBPgsql extends DoliDB } // if local connection failed or not requested, use TCP/IP - if (!$this->db) { + if (empty($this->db)) { if (!$host) { $host = "localhost"; } @@ -432,7 +432,11 @@ class DoliDBPgsql extends DoliDB } $con_string = "host='".$host."' port='".$port."' dbname='".$name."' user='".$login."' password='".$passwd."'"; - $this->db = @pg_connect($con_string); + try { + $this->db = @pg_connect($con_string); + } catch (Exception $e) { + print $e->getMessage(); + } } // now we test if at least one connect method was a success @@ -580,7 +584,7 @@ class DoliDBPgsql extends DoliDB { // phpcs:enable // If resultset not provided, we take the last used by connexion - if (!is_resource($resultset)) { + if (!is_resource($resultset) && !is_object($resultset)) { $resultset = $this->_results; } return pg_fetch_object($resultset); @@ -597,7 +601,7 @@ class DoliDBPgsql extends DoliDB { // phpcs:enable // If resultset not provided, we take the last used by connexion - if (!is_resource($resultset)) { + if (!is_resource($resultset) && !is_object($resultset)) { $resultset = $this->_results; } return pg_fetch_array($resultset); @@ -614,7 +618,7 @@ class DoliDBPgsql extends DoliDB { // phpcs:enable // Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion - if (!is_resource($resultset)) { + if (!is_resource($resultset) && !is_object($resultset)) { $resultset = $this->_results; } return pg_fetch_row($resultset); @@ -632,7 +636,7 @@ class DoliDBPgsql extends DoliDB { // phpcs:enable // If resultset not provided, we take the last used by connexion - if (!is_resource($resultset)) { + if (!is_resource($resultset) && !is_object($resultset)) { $resultset = $this->_results; } return pg_num_rows($resultset); @@ -650,7 +654,7 @@ class DoliDBPgsql extends DoliDB { // phpcs:enable // If resultset not provided, we take the last used by connexion - if (!is_resource($resultset)) { + if (!is_resource($resultset) && !is_object($resultset)) { $resultset = $this->_results; } // pgsql necessite un resultset pour cette fonction contrairement @@ -668,11 +672,11 @@ class DoliDBPgsql extends DoliDB public function free($resultset = null) { // If resultset not provided, we take the last used by connexion - if (!is_resource($resultset)) { + if (!is_resource($resultset) && !is_object($resultset)) { $resultset = $this->_results; } // Si resultset en est un, on libere la memoire - if (is_resource($resultset)) { + if (is_resource($resultset) || is_object($resultset)) { pg_free_result($resultset); } } @@ -916,7 +920,8 @@ class DoliDBPgsql extends DoliDB // Test charset match LC_TYPE (pgsql error otherwise) //print $charset.' '.setlocale(LC_CTYPE,'0'); exit; - $sql = "CREATE DATABASE '".$this->escape($database)."' OWNER '".$this->escape($owner)."' ENCODING '".$this->escape($charset)."'"; + // NOTE: Do not use ' around the database name + $sql = "CREATE DATABASE ".$this->escape($database)." OWNER '".$this->escape($owner)."' ENCODING '".$this->escape($charset)."'"; dol_syslog($sql, LOG_DEBUG); $ret = $this->query($sql); return $ret; diff --git a/htdocs/core/js/lib_head.js.php b/htdocs/core/js/lib_head.js.php index 2bf03129210..ac3de08af10 100644 --- a/htdocs/core/js/lib_head.js.php +++ b/htdocs/core/js/lib_head.js.php @@ -127,6 +127,19 @@ $langs->trans("FridayMin"), $langs->trans("SaturdayMin") ); + +$dec = ','; +$thousand = ' '; +if ($langs->transnoentitiesnoconv("SeparatorDecimal") != "SeparatorDecimal") { + $dec = $langs->transnoentitiesnoconv("SeparatorDecimal"); +} +if ($langs->transnoentitiesnoconv("SeparatorThousand") != "SeparatorThousand") { + $thousand = $langs->transnoentitiesnoconv("SeparatorThousand"); +} +if ($thousand == 'Space') { + $thousand = ' '; +} + ?> // Javascript libraries for Dolibarr ERP CRM (https://www.dolibarr.org) @@ -136,6 +149,7 @@ var tradMonthsShort = ; var tradDays = ; var tradDaysShort = ; var tradDaysMin = ; +var currencyCache = cache_currencies) ?>; // For JQuery date picker $(document).ready(function() { @@ -1091,22 +1105,87 @@ function getParameterByName(name, valueifnotfound) // Another solution, easier, to build a javascript rounding function function dolroundjs(number, decimals) { return +(Math.round(number + "e+" + decimals) + "e-" + decimals); } - /** * Function similar to PHP price() * + * Example use: + * pricejs(13312.448, 'MT', 'EUR', 'fr_FR') + * // (depending on conf for 'MT'): '13 312.45 €' + * + * pricejs(343000.121, 'MT') + * // assuming conf for 'MT' is 2 and $langs->defaultlang is 'en_US': '343,000.12' + * * @param {number|string} amount The amount to show * @param {string} mode 'MT' or 'MU' + * @param {string} currency_code ISO code of currency (empty by default) + * @param {string} force_locale ISO code locale to use (if empty, will use Dolibarr's current locale code) * @return {string} The amount with digits + * */ -function pricejs(amount, mode) { +function pricejs(amount, mode = 'MT', currency_code = '', force_locale = '') { var main_max_dec_shown = global->MAIN_MAX_DECIMALS_SHOWN); ?>; var main_rounding_unit = global->MAIN_MAX_DECIMALS_UNIT; ?>; var main_rounding_tot = global->MAIN_MAX_DECIMALS_TOT; ?>; + var main_decimal_separator = ; + var main_thousand_separator = ; + var locale_code = force_locale || defaultlang) ?>; + var amountAsLocalizedString; + var useIntl = Boolean(Intl && Intl.NumberFormat); + var nDigits; + if (currency_code === 'auto') currency_code = currency) ?>; - if (mode == 'MU') return amount.toFixed(main_rounding_unit); - if (mode == 'MT') return amount.toFixed(main_rounding_tot); - return 'Bad value for parameter mode'; + if (mode === 'MU') nDigits = main_rounding_unit; + else if (mode === 'MT') nDigits = main_rounding_tot; + else return 'Bad value for parameter mode'; + + if (useIntl) { + // simple version: let the browser decide how to format the number using the provided language / currency + // parameters + var formattingOptions = { + minimumFractionDigits: nDigits, + maximumFractionDigits: nDigits + }; + if (currency_code) { + formattingOptions['style'] = 'currency'; + formattingOptions['currency'] = currency_code; + } + return Intl.NumberFormat(locale_code.replace('_', '-'), formattingOptions).format(amount); + } + + // No Intl -> attempt to format the number in a way similar to Dolibarr PHP's `price()` function + amountAsLocalizedString = amount.toFixed(nDigits).replace( + /((?!^)(?:\d{3})*)(?:\.(\d+))?$/, + (fullMatch, digitsByThree, decimals) => + digitsByThree.replace( + /\d{3}/g, + (groupOfThree) => main_thousand_separator + groupOfThree + ) + (decimals !== undefined ? main_decimal_separator + decimals : '') + ).replace(/ /, ' '); + if (!currency_code) return amountAsLocalizedString; + + // print with currency + var currency_symbol = currency_code; + + // codes of languages / currencies where the symbol must be placed before the amount + var currencyBeforeAmountCodes = { + currency: ['AUD', 'CAD', 'CNY', 'COP', 'CLP', 'GBP', 'HKD', 'MXN', 'PEN', 'USD'], + language: ['nl_NL'] + }; + + if (currencyCache[currency_code] + && currencyCache[currency_code]['unicode'] + && currencyCache[currency_code]['unicode'].length) { + currency_symbol = currencyCache[currency_code]['unicode'].reduce(function (res, cur) {return res + cur}, ''); + } + + if (currencyBeforeAmountCodes.currency.indexOf(currency_code) >= 0 + || currencyBeforeAmountCodes.language.indexOf(locale_code)) { + // if we use a language or a currency where the symbol is placed before the amount + return currency_symbol + amountAsLocalizedString; + } + + // by default: currency symbol after the amount + return amountAsLocalizedString + ' ' + currency_symbol; } /** @@ -1119,20 +1198,8 @@ function pricejs(amount, mode) { function price2numjs(amount) { if (amount == '') return ''; - transnoentitiesnoconv("SeparatorDecimal") != "SeparatorDecimal") { - $dec = $langs->transnoentitiesnoconv("SeparatorDecimal"); - } - if ($langs->transnoentitiesnoconv("SeparatorThousand") != "SeparatorThousand") { - $thousand = $langs->transnoentitiesnoconv("SeparatorThousand"); - } - if ($thousand == 'Space') { - $thousand = ' '; - } - print "var dec='".dol_escape_js($dec)."'; var thousand='".dol_escape_js($thousand)."';\n"; // Set var in javascript - ?> + var dec = ; + var thousand = ; var main_max_dec_shown = global->MAIN_MAX_DECIMALS_SHOWN); ?>; var main_rounding_unit = global->MAIN_MAX_DECIMALS_UNIT; ?>; diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index 9bc0a59cf86..e14302da340 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -29,10 +29,10 @@ /** * Prepare array with list of tabs * - * @param Object $object Object related to tabs + * @param User $object Object related to tabs * @return array Array of tabs to show */ -function user_prepare_head($object) +function user_prepare_head(User $object) { global $langs, $conf, $user, $db; diff --git a/htdocs/core/login/functions_ldap.php b/htdocs/core/login/functions_ldap.php index 1d86bd19549..022186b8de1 100644 --- a/htdocs/core/login/functions_ldap.php +++ b/htdocs/core/login/functions_ldap.php @@ -260,7 +260,7 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest) ** 53 - Account inactive (manually locked out by administrator) */ dol_syslog("functions_ldap::check_user_password_ldap Authentication KO failed to connect to LDAP for '".$usertotest."'", LOG_NOTICE); - if (is_resource($ldap->connection)) { // If connection ok but bind ko + if (is_resource($ldap->connection) || is_object($ldap->connection)) { // If connection ok but bind ko $ldap->ldapErrorCode = ldap_errno($ldap->connection); $ldap->ldapErrorText = ldap_error($ldap->connection); dol_syslog("functions_ldap::check_user_password_ldap ".$ldap->ldapErrorCode." ".$ldap->ldapErrorText); diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 71abeda1f03..b579c9b0059 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -956,11 +956,11 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it $err++; } else { $obj = $this->db->fetch_object($resql); - $tmp = array(); - if ($obj->note) { - $tmp = json_decode($obj->note, true); - } if ($obj) { + $tmp = array(); + if ($obj->note) { + $tmp = json_decode($obj->note, true); + } return array( 'authorid' => $tmp['authorid'], 'ip' => $tmp['ip'], @@ -1054,16 +1054,16 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps,PEAR.NamingConventions.ValidFunctionName.PublicUnderscore /** * Create tables and keys required by module: - * - Files module.sql with create table instructions - * - Then modules.key.sql with create keys instructions + * - Files table.sql or table-module.sql with create table instructions + * - Then table.key.sql or table-module.key.sql with create keys instructions * - Then data_xxx.sql (usualy provided by external modules only) * - Then update_xxx.sql (usualy provided by external modules only) - * Files must be stored in directory defined by reldir (Example: '/install/mysql/tables' or '/module/sql/') + * Files must be stored in subdirectory 'tables' or 'data' into directory $reldir (Example: '/install/mysql/' or '/module/sql/') * This function may also be called by : - * - _load_tables('/install/mysql/tables/', 'modulename') into the this->init() of core module descriptors. + * - _load_tables('/install/mysql/', 'modulename') into the this->init() of core module descriptors. * - _load_tables('/mymodule/sql/') into the this->init() of external module descriptors. * - * @param string $reldir Relative directory where to scan files. Example: '/install/mysql/tables' or '/module/sql/' + * @param string $reldir Relative directory where to scan files. Example: '/install/mysql/' or '/module/sql/' * @param string $onlywithsuffix Only with the defined suffix * @return int <=0 if KO, >0 if OK */ @@ -1084,112 +1084,147 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it $ok = 1; foreach ($conf->file->dol_document_root as $dirroot) { if ($ok) { - $dir = $dirroot.$reldir; + $dirsql = $dirroot.$reldir; $ok = 0; - $handle = @opendir($dir); // Dir may not exists - if (is_resource($handle)) { - $dirfound++; + // We will loop on xxx/, xxx/tables/, xxx/data/ + $listofsubdir = array('', 'tables/', 'data/'); + if ($this->db->type == 'pgsql') { + $listofsubdir[] = '../pgsql/functions/'; + } - // Run llx_mytable.sql files, then llx_mytable_*.sql - $files = array(); - while (($file = readdir($handle)) !== false) { - $files[] = $file; - } - sort($files); - foreach ($files as $file) { - if ($onlywithsuffix) { - if (!preg_match('/\-'.preg_quote($onlywithsuffix, '/').'\./i', $file)) { - //print 'File '.$file.' does not match suffix '.$onlywithsuffix.' so it is discarded
    '."\n"; - continue; - } else { - //print 'File '.$file.' match suffix '.$onlywithsuffix.' so we keep it
    '."\n"; + foreach ($listofsubdir as $subdir) { + $dir = $dirsql.$subdir; + + $handle = @opendir($dir); // Dir may not exists + if (is_resource($handle)) { + $dirfound++; + + // Run llx_mytable.sql files, then llx_mytable_*.sql + $files = array(); + while (($file = readdir($handle)) !== false) { + $files[] = $file; + } + sort($files); + foreach ($files as $file) { + if ($onlywithsuffix) { + if (!preg_match('/\-'.preg_quote($onlywithsuffix, '/').'\./i', $file)) { + //print 'File '.$file.' does not match suffix '.$onlywithsuffix.' so it is discarded
    '."\n"; + continue; + } else { + //print 'File '.$file.' match suffix '.$onlywithsuffix.' so we keep it
    '."\n"; + } + } + if (preg_match('/\.sql$/i', $file) && !preg_match('/\.key\.sql$/i', $file) && substr($file, 0, 4) == 'llx_') { + $result = run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0, '', 1); + if ($result <= 0) { + $error++; + } } } - if (preg_match('/\.sql$/i', $file) && !preg_match('/\.key\.sql$/i', $file) && substr($file, 0, 4) == 'llx_' && substr($file, 0, 4) != 'data') { - $result = run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0, '', 1); - if ($result <= 0) { - $error++; + + rewinddir($handle); + + // Run llx_mytable.key.sql files (Must be done after llx_mytable.sql) then then llx_mytable_*.key.sql + $files = array(); + while (($file = readdir($handle)) !== false) { + $files[] = $file; + } + sort($files); + foreach ($files as $file) { + if ($onlywithsuffix) { + if (!preg_match('/\-'.preg_quote($onlywithsuffix, '/').'\./i', $file)) { + //print 'File '.$file.' does not match suffix '.$onlywithsuffix.' so it is discarded
    '."\n"; + continue; + } else { + //print 'File '.$file.' match suffix '.$onlywithsuffix.' so we keep it
    '."\n"; + } + } + if (preg_match('/\.key\.sql$/i', $file) && substr($file, 0, 4) == 'llx_') { + $result = run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0, '', 1); + if ($result <= 0) { + $error++; + } } } - } - rewinddir($handle); + rewinddir($handle); - // Run llx_mytable.key.sql files (Must be done after llx_mytable.sql) then then llx_mytable_*.key.sql - $files = array(); - while (($file = readdir($handle)) !== false) { - $files[] = $file; - } - sort($files); - foreach ($files as $file) { - if ($onlywithsuffix) { - if (!preg_match('/\-'.preg_quote($onlywithsuffix, '/').'\./i', $file)) { - //print 'File '.$file.' does not match suffix '.$onlywithsuffix.' so it is discarded
    '."\n"; - continue; - } else { - //print 'File '.$file.' match suffix '.$onlywithsuffix.' so we keep it
    '."\n"; + // Run functions-xxx.sql files (Must be done after llx_mytable.key.sql) + $files = array(); + while (($file = readdir($handle)) !== false) { + $files[] = $file; + } + sort($files); + foreach ($files as $file) { + if ($onlywithsuffix) { + if (!preg_match('/\-'.preg_quote($onlywithsuffix, '/').'\./i', $file)) { + //print 'File '.$file.' does not match suffix '.$onlywithsuffix.' so it is discarded
    '."\n"; + continue; + } else { + //print 'File '.$file.' match suffix '.$onlywithsuffix.' so we keep it
    '."\n"; + } + } + if (preg_match('/\.sql$/i', $file) && !preg_match('/\.key\.sql$/i', $file) && substr($file, 0, 9) == 'functions') { + $result = run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0, '', 1); + if ($result <= 0) { + $error++; + } } } - if (preg_match('/\.key\.sql$/i', $file) && substr($file, 0, 4) == 'llx_' && substr($file, 0, 4) != 'data') { - $result = run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0, '', 1); - if ($result <= 0) { - $error++; + + rewinddir($handle); + + // Run data_xxx.sql files (Must be done after llx_mytable.key.sql) + $files = array(); + while (($file = readdir($handle)) !== false) { + $files[] = $file; + } + sort($files); + foreach ($files as $file) { + if ($onlywithsuffix) { + if (!preg_match('/\-'.preg_quote($onlywithsuffix, '/').'\./i', $file)) { + //print 'File '.$file.' does not match suffix '.$onlywithsuffix.' so it is discarded
    '."\n"; + continue; + } else { + //print 'File '.$file.' match suffix '.$onlywithsuffix.' so we keep it
    '."\n"; + } + } + if (preg_match('/\.sql$/i', $file) && !preg_match('/\.key\.sql$/i', $file) && substr($file, 0, 4) == 'data') { + $result = run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0, '', 1); + if ($result <= 0) { + $error++; + } } } - } - rewinddir($handle); + rewinddir($handle); - // Run data_xxx.sql files (Must be done after llx_mytable.key.sql) - $files = array(); - while (($file = readdir($handle)) !== false) { - $files[] = $file; - } - sort($files); - foreach ($files as $file) { - if ($onlywithsuffix) { - if (!preg_match('/\-'.preg_quote($onlywithsuffix, '/').'\./i', $file)) { - //print 'File '.$file.' does not match suffix '.$onlywithsuffix.' so it is discarded
    '."\n"; - continue; - } else { - //print 'File '.$file.' match suffix '.$onlywithsuffix.' so we keep it
    '."\n"; + // Run update_xxx.sql files + $files = array(); + while (($file = readdir($handle)) !== false) { + $files[] = $file; + } + sort($files); + foreach ($files as $file) { + if ($onlywithsuffix) { + if (!preg_match('/\-'.preg_quote($onlywithsuffix, '/').'\./i', $file)) { + //print 'File '.$file.' does not match suffix '.$onlywithsuffix.' so it is discarded
    '."\n"; + continue; + } else { + //print 'File '.$file.' match suffix '.$onlywithsuffix.' so we keep it
    '."\n"; + } + } + if (preg_match('/\.sql$/i', $file) && !preg_match('/\.key\.sql$/i', $file) && substr($file, 0, 6) == 'update') { + $result = run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0, '', 1); + if ($result <= 0) { + $error++; + } } } - if (preg_match('/\.sql$/i', $file) && !preg_match('/\.key\.sql$/i', $file) && substr($file, 0, 4) == 'data') { - $result = run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0, '', 1); - if ($result <= 0) { - $error++; - } - } - } - rewinddir($handle); - - // Run update_xxx.sql files - $files = array(); - while (($file = readdir($handle)) !== false) { - $files[] = $file; + closedir($handle); } - sort($files); - foreach ($files as $file) { - if ($onlywithsuffix) { - if (!preg_match('/\-'.preg_quote($onlywithsuffix, '/').'\./i', $file)) { - //print 'File '.$file.' does not match suffix '.$onlywithsuffix.' so it is discarded
    '."\n"; - continue; - } else { - //print 'File '.$file.' match suffix '.$onlywithsuffix.' so we keep it
    '."\n"; - } - } - if (preg_match('/\.sql$/i', $file) && !preg_match('/\.key\.sql$/i', $file) && substr($file, 0, 6) == 'update') { - $result = run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0, '', 1); - if ($result <= 0) { - $error++; - } - } - } - - closedir($handle); } if ($error == 0) { diff --git a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php index db961962ba6..fa9d83ea926 100644 --- a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php @@ -742,6 +742,9 @@ class pdf_einstein extends ModelePDFCommandes $pdf->SetXY($posxval, $posy); $lib_condition_paiement = $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) != ('PaymentCondition'.$object->cond_reglement_code) ? $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) : $outputlangs->convToOutputCharset($object->cond_reglement_doc ? $object->cond_reglement_doc : $object->cond_reglement_label); $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement); + if ($object->deposit_percent > 0) { + $lib_condition_paiement = str_replace('__DEPOSIT_PERCENT__', $object->deposit_percent, $lib_condition_paiement); + } $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L'); $posy = $pdf->GetY() + 3; diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php index 560344a9eeb..b5f2ee5af43 100644 --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php @@ -960,6 +960,9 @@ class pdf_eratosthene extends ModelePDFCommandes $pdf->SetXY($posxval, $posy); $lib_condition_paiement = $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) != ('PaymentCondition'.$object->cond_reglement_code) ? $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) : $outputlangs->convToOutputCharset($object->cond_reglement_doc ? $object->cond_reglement_doc : $object->cond_reglement_label); $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement); + if ($object->deposit_percent > 0) { + $lib_condition_paiement = str_replace('__DEPOSIT_PERCENT__', $object->deposit_percent, $lib_condition_paiement); + } $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L'); $posy = $pdf->GetY() + 3; diff --git a/htdocs/core/modules/modAsset.class.php b/htdocs/core/modules/modAsset.class.php index 2146de367e1..a217cb8d72c 100644 --- a/htdocs/core/modules/modAsset.class.php +++ b/htdocs/core/modules/modAsset.class.php @@ -240,7 +240,7 @@ class modAsset extends DolibarrModules */ public function init($options = '') { - $result = $this->_load_tables('/install/mysql/tables/', 'asset'); + $result = $this->_load_tables('/install/mysql/', 'asset'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') } diff --git a/htdocs/core/modules/modDeplacement.class.php b/htdocs/core/modules/modDeplacement.class.php index bceb313e120..450aa76258e 100644 --- a/htdocs/core/modules/modDeplacement.class.php +++ b/htdocs/core/modules/modDeplacement.class.php @@ -159,7 +159,7 @@ class modDeplacement extends DolibarrModules */ public function init($options = '') { - $result = $this->_load_tables('/install/mysql/tables/', 'deplacement'); + $result = $this->_load_tables('/install/mysql/', 'deplacement'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') } diff --git a/htdocs/core/modules/modDon.class.php b/htdocs/core/modules/modDon.class.php index f2564cd3cc6..c5c790ca28c 100644 --- a/htdocs/core/modules/modDon.class.php +++ b/htdocs/core/modules/modDon.class.php @@ -155,7 +155,7 @@ class modDon extends DolibarrModules { global $conf; - $result = $this->_load_tables('/install/mysql/tables/', 'deplacement'); + $result = $this->_load_tables('/install/mysql/', 'don'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') } diff --git a/htdocs/core/modules/modHRM.class.php b/htdocs/core/modules/modHRM.class.php index bd81f06dae7..7df3bcc6dcf 100644 --- a/htdocs/core/modules/modHRM.class.php +++ b/htdocs/core/modules/modHRM.class.php @@ -280,7 +280,7 @@ class modHRM extends DolibarrModules // Permissions $this->remove($options); - $result = $this->_load_tables('/install/mysql/tables/', 'hrm'); + $result = $this->_load_tables('/install/mysql/', 'hrm'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') } diff --git a/htdocs/core/modules/modIntracommreport.class.php b/htdocs/core/modules/modIntracommreport.class.php index 50758f90f0c..25f26050ed0 100644 --- a/htdocs/core/modules/modIntracommreport.class.php +++ b/htdocs/core/modules/modIntracommreport.class.php @@ -138,7 +138,7 @@ class modIntracommreport extends DolibarrModules { global $conf; - $result = $this->_load_tables('/install/mysql/tables/', 'intracommreport'); + $result = $this->_load_tables('/install/mysql/', 'intracommreport'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') } diff --git a/htdocs/core/modules/modKnowledgeManagement.class.php b/htdocs/core/modules/modKnowledgeManagement.class.php index 93b44f31204..434cc9d6faf 100644 --- a/htdocs/core/modules/modKnowledgeManagement.class.php +++ b/htdocs/core/modules/modKnowledgeManagement.class.php @@ -442,7 +442,7 @@ class modKnowledgeManagement extends DolibarrModules { global $conf, $langs; - $result = $this->_load_tables('/install/mysql/tables/', 'knowledgemanagement'); + $result = $this->_load_tables('/install/mysql/', 'knowledgemanagement'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') } diff --git a/htdocs/core/modules/modLoan.class.php b/htdocs/core/modules/modLoan.class.php index e19ec1b81f8..8f9de88b83f 100644 --- a/htdocs/core/modules/modLoan.class.php +++ b/htdocs/core/modules/modLoan.class.php @@ -160,7 +160,7 @@ class modLoan extends DolibarrModules { global $conf; - $result = $this->_load_tables('/install/mysql/tables/', 'loan'); + $result = $this->_load_tables('/install/mysql/', 'loan'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') } diff --git a/htdocs/core/modules/modMailing.class.php b/htdocs/core/modules/modMailing.class.php index 1a31aad9c8b..7e3d4b6aeb1 100644 --- a/htdocs/core/modules/modMailing.class.php +++ b/htdocs/core/modules/modMailing.class.php @@ -159,7 +159,7 @@ class modMailing extends DolibarrModules */ public function init($options = '') { - $result = $this->_load_tables('/install/mysql/tables/', 'mailing'); + $result = $this->_load_tables('/install/mysql/', 'mailing'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') } diff --git a/htdocs/core/modules/modOpenSurvey.class.php b/htdocs/core/modules/modOpenSurvey.class.php index 9cc9310cd19..04a8cd54082 100644 --- a/htdocs/core/modules/modOpenSurvey.class.php +++ b/htdocs/core/modules/modOpenSurvey.class.php @@ -184,7 +184,7 @@ class modOpenSurvey extends DolibarrModules { global $conf, $langs; - $result = $this->_load_tables('/install/mysql/tables/', 'opensurvey'); + $result = $this->_load_tables('/install/mysql/', 'opensurvey'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') } diff --git a/htdocs/core/modules/modPartnership.class.php b/htdocs/core/modules/modPartnership.class.php index c08cf66db06..f37d7d2403d 100644 --- a/htdocs/core/modules/modPartnership.class.php +++ b/htdocs/core/modules/modPartnership.class.php @@ -410,7 +410,7 @@ class modPartnership extends DolibarrModules { global $conf, $langs; - $result = $this->_load_tables('/install/mysql/tables/', 'partnership'); + $result = $this->_load_tables('/install/mysql/', 'partnership'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') } diff --git a/htdocs/core/modules/modProjet.class.php b/htdocs/core/modules/modProjet.class.php index f18a55ff6d8..f8b82e8faa3 100644 --- a/htdocs/core/modules/modProjet.class.php +++ b/htdocs/core/modules/modProjet.class.php @@ -152,7 +152,7 @@ class modProjet extends DolibarrModules $r++; $this->rights[$r][0] = 41; // id de la permission - $this->rights[$r][1] = "Read projects and tasks (shared projects or projects I am contact for). Can also enter time consumed on assigned tasks (timesheet)"; // libelle de la permission + $this->rights[$r][1] = "Read projects and tasks (shared projects or projects I am contact for)"; // libelle de la permission $this->rights[$r][2] = 'r'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'lire'; @@ -188,7 +188,7 @@ class modProjet extends DolibarrModules $r++; $this->rights[$r][0] = 142; // id de la permission - $this->rights[$r][1] = "Create/modify all projects and tasks (also private projects I am not contact for). Can also enter time consumed on assigned tasks (timesheet)"; // libelle de la permission + $this->rights[$r][1] = "Create/modify all projects and tasks (also private projects I am not contact for)"; // libelle de la permission $this->rights[$r][2] = 'w'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'all'; @@ -202,6 +202,12 @@ class modProjet extends DolibarrModules $this->rights[$r][4] = 'all'; $this->rights[$r][5] = 'supprimer'; + $r++; + $this->rights[$r][0] = 145; // id de la permission + $this->rights[$r][1] = "Can enter time consumed on assigned tasks (timesheet)"; // libelle de la permission + $this->rights[$r][2] = 'w'; // type de la permission (deprecie a ce jour) + $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut + $this->rights[$r][4] = 'time'; // Menus //------- diff --git a/htdocs/core/modules/modRecruitment.class.php b/htdocs/core/modules/modRecruitment.class.php index c4bbd573fa9..fb64e43486d 100644 --- a/htdocs/core/modules/modRecruitment.class.php +++ b/htdocs/core/modules/modRecruitment.class.php @@ -403,7 +403,7 @@ class modRecruitment extends DolibarrModules { global $conf, $langs; - $result = $this->_load_tables('/install/mysql/tables/', 'recruitment'); + $result = $this->_load_tables('/install/mysql/', 'recruitment'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') } diff --git a/htdocs/core/modules/modStock.class.php b/htdocs/core/modules/modStock.class.php index 839a62325f3..52a3843fd12 100644 --- a/htdocs/core/modules/modStock.class.php +++ b/htdocs/core/modules/modStock.class.php @@ -434,7 +434,7 @@ class modStock extends DolibarrModules { global $conf, $langs; - $result = $this->_load_tables('/install/mysql/tables/', 'stock'); + $result = $this->_load_tables('/install/mysql/', 'stock'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') } diff --git a/htdocs/core/modules/modTicket.class.php b/htdocs/core/modules/modTicket.class.php index 86a657c0509..688da3061d9 100644 --- a/htdocs/core/modules/modTicket.class.php +++ b/htdocs/core/modules/modTicket.class.php @@ -331,7 +331,7 @@ class modTicket extends DolibarrModules { global $conf, $langs; - $result = $this->_load_tables('/install/mysql/tables/', 'ticket'); + $result = $this->_load_tables('/install/mysql/', 'ticket'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') } diff --git a/htdocs/core/modules/modWebsite.class.php b/htdocs/core/modules/modWebsite.class.php index 7ea6b5a890c..e27e7a2f6b0 100644 --- a/htdocs/core/modules/modWebsite.class.php +++ b/htdocs/core/modules/modWebsite.class.php @@ -164,7 +164,7 @@ class modWebsite extends DolibarrModules { global $conf, $langs; - $result = $this->_load_tables('/install/mysql/tables/', 'website'); + $result = $this->_load_tables('/install/mysql/', 'website'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') } diff --git a/htdocs/core/modules/modWorkstation.class.php b/htdocs/core/modules/modWorkstation.class.php index 854dd45b969..80a401b4846 100644 --- a/htdocs/core/modules/modWorkstation.class.php +++ b/htdocs/core/modules/modWorkstation.class.php @@ -390,7 +390,7 @@ class modWorkstation extends DolibarrModules { global $conf, $langs; - $result = $this->_load_tables('/install/mysql/tables/', 'workstation'); + $result = $this->_load_tables('/install/mysql/', 'workstation'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') } diff --git a/htdocs/core/modules/modZapier.class.php b/htdocs/core/modules/modZapier.class.php index e638d906693..b6ef25e150e 100644 --- a/htdocs/core/modules/modZapier.class.php +++ b/htdocs/core/modules/modZapier.class.php @@ -281,7 +281,7 @@ class modZapier extends DolibarrModules */ public function init($options = '') { - $result = $this->_load_tables('/install/mysql/tables/', 'zapier'); + $result = $this->_load_tables('/install/mysql/', 'zapier'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') } diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php index 5135a1708af..c6bb975092d 100644 --- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php @@ -964,6 +964,9 @@ class pdf_azur extends ModelePDFPropales $pdf->SetXY($posxval, $posy); $lib_condition_paiement = $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) != ('PaymentCondition'.$object->cond_reglement_code) ? $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) : $outputlangs->convToOutputCharset($object->cond_reglement_doc ? $object->cond_reglement_doc : $object->cond_reglement_label); $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement); + if ($object->deposit_percent > 0) { + $lib_condition_paiement = str_replace('__DEPOSIT_PERCENT__', $object->deposit_percent, $lib_condition_paiement); + } $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L'); $posy = $pdf->GetY() + 3; diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php index 26ee429f97e..8651a9e720f 100644 --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php @@ -1083,6 +1083,9 @@ class pdf_cyan extends ModelePDFPropales $pdf->SetXY($posxval, $posy); $lib_condition_paiement = $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) != ('PaymentCondition'.$object->cond_reglement_code) ? $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) : $outputlangs->convToOutputCharset($object->cond_reglement_doc ? $object->cond_reglement_doc : $object->cond_reglement_label); $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement); + if ($object->deposit_percent > 0) { + $lib_condition_paiement = str_replace('__DEPOSIT_PERCENT__', $object->deposit_percent, $lib_condition_paiement); + } $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L'); $posy = $pdf->GetY() + 3; diff --git a/htdocs/core/tpl/massactions_pre.tpl.php b/htdocs/core/tpl/massactions_pre.tpl.php index 4e138b0f1dc..207dc1b7265 100644 --- a/htdocs/core/tpl/massactions_pre.tpl.php +++ b/htdocs/core/tpl/massactions_pre.tpl.php @@ -211,6 +211,59 @@ if ($massaction == 'presend') { print dol_get_fiche_end(); } +if ($massaction == 'edit_extrafields') { + require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + $elementtype = $objecttmp->element; + /** @var CommonObject $objecttmp */ + $extrafields = new ExtraFields($db); + $keysuffix = ''; + $extrafields->fetch_name_optionals_label($elementtype); + $extrafields_list = $extrafields->attributes[$elementtype]['label']; + + $formquestion = array(); + if (!empty($extrafields_list)) { + $myParamExtra = $object->showOptionals($extrafields, 'create'); + + $formquestion[] = array( + 'type' => 'other', + 'value' => $form->selectarray('extrafield-key-to-update', $extrafields_list, GETPOST('extrafield-key-to-update'), 1) + ); + + + $outputShowOutputFields = '
    '; + + foreach ($extrafields_list as $extraKey => $extraLabel) { + $outputShowOutputFields.= ''; + } + $outputShowOutputFields.= ''; + $outputShowOutputFields.= '
    '; + + + + $formquestion[] = array( + 'type' => 'other', + 'value' => $outputShowOutputFields + ); + + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmEditExtrafield"), $langs->trans("ConfirmEditExtrafieldQuestion", count($toselect)), "confirm_edit_value_extrafields", $formquestion, 1, 0, 200, 500, 1); + } else { + setEventMessage($langs->trans("noExtrafields")); + } +} + if ($massaction == 'preenable') { print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassEnabling"), $langs->trans("ConfirmMassEnablingQuestion", count($toselect)), "enable", null, 'yes', 0, 200, 500, 1); } diff --git a/htdocs/cron/list.php b/htdocs/cron/list.php index 7ee64ec2c6f..1072f68b48f 100644 --- a/htdocs/cron/list.php +++ b/htdocs/cron/list.php @@ -115,7 +115,7 @@ if (empty($reshook)) { $search_label = ''; $search_status = -1; $search_lastresult = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') diff --git a/htdocs/debugbar/class/TraceableDB.php b/htdocs/debugbar/class/TraceableDB.php index 2d9f70a1eb5..082e45e4f43 100644 --- a/htdocs/debugbar/class/TraceableDB.php +++ b/htdocs/debugbar/class/TraceableDB.php @@ -684,10 +684,10 @@ class TraceableDB extends DoliDB // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Renvoie la ligne courante (comme un objet) pour le curseur resultset + * Returns the current line (as an object) for the resultset cursor * - * @param resource $resultset Curseur de la requete voulue - * @return Object Object result line or false if KO or end of cursor + * @param resource|Connection $resultset Handler of the desired SQL request + * @return Object Object result line or false if KO or end of cursor */ public function fetch_object($resultset) { diff --git a/htdocs/eventorganization/class/conferenceorbooth.class.php b/htdocs/eventorganization/class/conferenceorbooth.class.php index 15493425231..fb608eca8ba 100644 --- a/htdocs/eventorganization/class/conferenceorbooth.class.php +++ b/htdocs/eventorganization/class/conferenceorbooth.class.php @@ -105,7 +105,7 @@ class ConferenceOrBooth extends ActionComm public $fields = array( 'id' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), 'ref' => array('type'=>'integer', 'label'=>'Ref', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>2, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), - 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>0, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'help'=>"Help text", 'showoncombobox'=>'1',), + 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>0, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'csslist'=>'tdoverflowmax125', 'help'=>"Help text", 'showoncombobox'=>'1',), 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'ThirdParty', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'help'=>"LinkToThirparty", 'picto'=>'company', 'css'=>'tdoverflowmax150 maxwidth500'), 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1:t.usage_organize_event=1', 'label'=>'Project', 'enabled'=>'1', 'position'=>52, 'notnull'=>-1, 'visible'=>-1, 'index'=>1, 'picto'=>'project', 'css'=>'tdoverflowmax150 maxwidth500'), 'note' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>1), diff --git a/htdocs/eventorganization/conferenceorbooth_list.php b/htdocs/eventorganization/conferenceorbooth_list.php index 0ba93ea1c82..88dad1bbac0 100644 --- a/htdocs/eventorganization/conferenceorbooth_list.php +++ b/htdocs/eventorganization/conferenceorbooth_list.php @@ -205,7 +205,7 @@ if (empty($reshook)) { $search[$key.'_dtend'] = ''; } } - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') @@ -705,15 +705,16 @@ print ''; foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['css']) ? '' : $val['css']); $searchkey = (empty($search[$key]) ? '' : $search[$key]); + + $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')) && !in_array($key, array('rowid', 'ref')) && $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'])) { diff --git a/htdocs/eventorganization/conferenceorboothattendee_list.php b/htdocs/eventorganization/conferenceorboothattendee_list.php index be24d7b6797..ee7fe97421a 100644 --- a/htdocs/eventorganization/conferenceorboothattendee_list.php +++ b/htdocs/eventorganization/conferenceorboothattendee_list.php @@ -206,7 +206,7 @@ if (empty($reshook)) { $search[$key.'_dtend'] = ''; } } - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index 7ae586020c6..6b67f419da5 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -196,7 +196,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_datereceipt_start = ''; $search_datereceipt_end = ''; $search_status = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); $search_categ_cus = 0; } diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index ab763dc8a11..551957d0a69 100644 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -224,7 +224,7 @@ if (empty($reshook)) { $search_date_endendyear = ''; $search_date_end = ''; $search_date_endend = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index 9ec00d62b8e..f0e028ea92f 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -171,7 +171,7 @@ if (empty($reshook)) { $search_contrat_ref = ""; $search_desc = ""; $search_status = ""; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index e14322a62e9..c2962836fa2 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -34,7 +34,7 @@ if (!defined('DOL_APPLICATION_TITLE')) { define('DOL_APPLICATION_TITLE', 'Dolibarr'); } if (!defined('DOL_VERSION')) { - define('DOL_VERSION', '16.0.0-alpha'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c + define('DOL_VERSION', '16.0.0-beta'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c } if (!defined('EURO')) { @@ -115,6 +115,13 @@ if (!$result && !empty($_SERVER["GATEWAY_INTERFACE"])) { // If install not do } header("Location: ".$path."install/index.php"); + + /* + print '
    '; + print 'The conf/conf.php file was not found or is not readable by the web server. If this is your first access, click here to start the Dolibarr installation process to create it...'; + print '

    '; + */ + exit; } diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index 9298c67ad9f..8ad44d198a8 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -266,7 +266,7 @@ if ($object->id > 0) { print '
    '; print ''; if ($action == 'editconditions') { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->cond_reglement_supplier_id, 'cond_reglement_supplier_id', -1, 1); + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->cond_reglement_supplier_id, 'cond_reglement_supplier_id', 1); } else { $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->cond_reglement_supplier_id, 'none'); } diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 98df5e11170..224a36e4acd 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -291,7 +291,7 @@ if (empty($reshook)) { $search_date_approve_end = ''; $billed = ''; $search_billed = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index bc0e80e9f69..a851e95e089 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -290,7 +290,7 @@ if (empty($reshook)) { $search_datelimit_endyear = ''; $search_datelimit_start = ''; $search_datelimit_end = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); $filter = ''; $option = ''; @@ -1474,7 +1474,7 @@ if ($resql) { // Payment condition if (!empty($arrayfields['f.fk_cond_reglement']['checked'])) { print ''; - $form->form_conditions_reglement($_SERVER['PHP_SELF'], $obj->fk_cond_reglement, 'none', '', -1); + $form->form_conditions_reglement($_SERVER['PHP_SELF'], $obj->fk_cond_reglement, 'none', 1); print ''; if (!$i) { $totalarray['nbfield']++; diff --git a/htdocs/fourn/product/list.php b/htdocs/fourn/product/list.php index a20e586e2ee..2665f987a10 100644 --- a/htdocs/fourn/product/list.php +++ b/htdocs/fourn/product/list.php @@ -108,7 +108,7 @@ if (empty($reshook)) { $search_field2 = ''; $search_date_creation = ''; $search_date_update = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } } diff --git a/htdocs/holiday/define_holiday.php b/htdocs/holiday/define_holiday.php index 12a32ba3f50..dedc7d1da0f 100644 --- a/htdocs/holiday/define_holiday.php +++ b/htdocs/holiday/define_holiday.php @@ -111,7 +111,7 @@ if (empty($reshook)) { if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers $search_name = ''; $search_supervisor = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index efafac7f823..5dc05d1c617 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -200,7 +200,7 @@ if (empty($reshook)) { $search_valideur = ""; $search_status = ""; $search_type = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') diff --git a/htdocs/holiday/month_report.php b/htdocs/holiday/month_report.php index e76d316bf6c..67c860e6f70 100644 --- a/htdocs/holiday/month_report.php +++ b/htdocs/holiday/month_report.php @@ -95,7 +95,7 @@ if (empty($reshook)) { $search_employee = ''; $search_type = ''; $search_description = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } diff --git a/htdocs/holiday/view_log.php b/htdocs/holiday/view_log.php index 1a621d55a98..7dffc0adbfe 100644 --- a/htdocs/holiday/view_log.php +++ b/htdocs/holiday/view_log.php @@ -133,7 +133,7 @@ if (empty($reshook)) { $search_type = ''; $search_prev_solde = ''; $search_new_solde = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } diff --git a/htdocs/hrm/admin/evaluation_extrafields.php b/htdocs/hrm/admin/evaluation_extrafields.php index a9614ccd03f..133be0c0f08 100644 --- a/htdocs/hrm/admin/evaluation_extrafields.php +++ b/htdocs/hrm/admin/evaluation_extrafields.php @@ -91,6 +91,8 @@ require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; * View */ +$textobject = $langs->transnoentitiesnoconv("Evaluation"); + $help_url = ''; $page_name = "HrmSetup"; diff --git a/htdocs/hrm/admin/job_extrafields.php b/htdocs/hrm/admin/job_extrafields.php index 4b0d76e5187..f521b8addb4 100644 --- a/htdocs/hrm/admin/job_extrafields.php +++ b/htdocs/hrm/admin/job_extrafields.php @@ -91,6 +91,8 @@ require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; * View */ +$textobject = $langs->transnoentitiesnoconv("Job"); + $help_url = ''; $page_name = "HrmSetup"; diff --git a/htdocs/hrm/admin/skill_extrafields.php b/htdocs/hrm/admin/skill_extrafields.php index f8d123cce74..e77feaa5002 100644 --- a/htdocs/hrm/admin/skill_extrafields.php +++ b/htdocs/hrm/admin/skill_extrafields.php @@ -91,6 +91,8 @@ require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; * View */ +$textobject = $langs->transnoentitiesnoconv("Skills"); + $help_url = ''; $page_name = "HrmSetup"; diff --git a/htdocs/install/index.php b/htdocs/install/index.php index 09300a75721..a7ce50c819f 100644 --- a/htdocs/install/index.php +++ b/htdocs/install/index.php @@ -49,6 +49,12 @@ $formadmin = new FormAdmin(''); // Note: $db does not exist yet but we don't nee pHeader("", "check"); // Next step = check +if (!is_readable($conffile)) { + print '
    '; + print ''.$langs->trans("NoReadableConfFileSoStartInstall").''; +} + + // Ask installation language print '

    '; print ''; @@ -61,7 +67,9 @@ print ''; print '
    '; -print '

    '.$langs->trans("SomeTranslationAreUncomplete").''; + + +//print '

    '.$langs->trans("SomeTranslationAreUncomplete").''; // If there's no error, we display the next step button if ($err == 0) { diff --git a/htdocs/install/mysql/data/llx_c_partnership_type.sql b/htdocs/install/mysql/data/llx_c_partnership_type-partnership.sql similarity index 100% rename from htdocs/install/mysql/data/llx_c_partnership_type.sql rename to htdocs/install/mysql/data/llx_c_partnership_type-partnership.sql diff --git a/htdocs/install/mysql/data/llx_c_payment_term.sql b/htdocs/install/mysql/data/llx_c_payment_term.sql index b5ff008912b..5a48e57a443 100644 --- a/htdocs/install/mysql/data/llx_c_payment_term.sql +++ b/htdocs/install/mysql/data/llx_c_payment_term.sql @@ -26,17 +26,18 @@ -- Do not include comments at end of line, this file is parsed during install and string '--' are removed. -- -insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (1 ,'RECEP', 1,1, 'Due upon receipt','Due upon receipt',0,1); -insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (2 ,'30D', 2,1, '30 days','Due in 30 days',0,30); -insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (3 ,'30DENDMONTH', 3,1, '30 days end of month','Due in 30 days, end of month',1,30); -insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (4 ,'60D', 4,1, '60 days','Due in 60 days, end of month',0,60); -insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (5 ,'60DENDMONTH', 5,1, '60 days end of month','Due in 60 days, end of month',1,60); -insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (6 ,'PT_ORDER', 6,1, 'Due on order','Due on order',0,1); -insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (7 ,'PT_DELIVERY', 7,1, 'Due on delivery','Due on delivery',0,1); -insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (8 ,'PT_5050', 8,1, '50 and 50','50% on order, 50% on delivery',0,1); +insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour, deposit_percent) values (1 ,'RECEP', 1,1, 'Due upon receipt','Due upon receipt',0,1,NULL); +insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour, deposit_percent) values (2 ,'30D', 2,1, '30 days','Due in 30 days',0,30,NULL); +insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour, deposit_percent) values (3 ,'30DENDMONTH', 3,1, '30 days end of month','Due in 30 days, end of month',1,30,NULL); +insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour, deposit_percent) values (4 ,'60D', 4,1, '60 days','Due in 60 days, end of month',0,60,NULL); +insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour, deposit_percent) values (5 ,'60DENDMONTH', 5,1, '60 days end of month','Due in 60 days, end of month',1,60,NULL); +insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour, deposit_percent) values (6 ,'PT_ORDER', 6,1, 'Due on order','Due on order',0,1,NULL); +insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour, deposit_percent) values (7 ,'PT_DELIVERY', 7,1, 'Due on delivery','Due on delivery',0,1,NULL); +insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour, deposit_percent) values (8 ,'PT_5050', 8,1, '50 and 50','50% on order, 50% on delivery',0,1,NULL); -- Add additional payment terms often needed in Austria -insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (9 ,'10D', 9,1, '10 days','Due in 10 days',0,10); -insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (10,'10DENDMONTH', 10,1, '10 days end of month','Due in 10 days, end of month',1,10); -insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (11,'14D', 11,1, '14 days','Due in 14 days',0,14); -insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour) values (12,'14DENDMONTH', 12,1, '14 days end of month','Due in 14 days, end of month',1,14); +insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour, deposit_percent) values (9 ,'10D', 9,1, '10 days','Due in 10 days',0,10,NULL); +insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour, deposit_percent) values (10,'10DENDMONTH', 10,1, '10 days end of month','Due in 10 days, end of month',1,10,NULL); +insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour, deposit_percent) values (11,'14D', 11,1, '14 days','Due in 14 days',0,14,NULL); +insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour, deposit_percent) values (12,'14DENDMONTH', 12,1, '14 days end of month','Due in 14 days, end of month',1,14,NULL); +insert into llx_c_payment_term(rowid, code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour, deposit_percent) values (13,'DEP30PCTDEL', 13,0, '__DEPOSIT_PERCENT__% deposit','__DEPOSIT_PERCENT__% deposit, remainder on delivery',0,1,'30'); 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 bef32bc7fe7..7355f1d8987 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 @@ -538,6 +538,18 @@ INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle, active) VALUES (154, -- VMYSQL4.3 ALTER TABLE llx_user MODIFY COLUMN fk_soc integer NULL; -- VPGSQL8.2 ALTER TABLE llx_user ALTER COLUMN fk_soc DROP NOT NULL; +CREATE TABLE llx_element_tag +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + fk_categorie integer NOT NULL, + fk_element integer NOT NULL, + import_key varchar(14) +)ENGINE=innodb; + +ALTER TABLE llx_element_tag ADD UNIQUE INDEX idx_element_tag_uk (fk_categorie, fk_element); + +ALTER TABLE llx_element_tag ADD CONSTRAINT fk_element_tag_categorie_rowid FOREIGN KEY (fk_categorie) REFERENCES llx_categorie (rowid); + -- Add column to help to fix a very critical bug when transferring into accounting bank record of a bank account into another currency. -- Idea is to update this column manually in v15 with value in currency of company for bank that are not into the main currency and the transfer -- into accounting will use it in priority if value is not null. The script repair.sql contains the sequence to fix datas in llx_bank. diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql index 186a789cac9..5ff0d82a0d0 100644 --- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -105,6 +105,8 @@ ALTER TABLE llx_bank ADD COLUMN amount_main_currency double(24,8) NULL; -- v16 +ALTER TABLE llx_societe_account DROP FOREIGN KEY llx_societe_account_fk_website; + UPDATE llx_cronjob set label = 'RecurringInvoicesJob' where label = 'RecurringInvoices'; UPDATE llx_cronjob set label = 'RecurringSupplierInvoicesJob' where label = 'RecurringSupplierInvoices'; @@ -325,6 +327,15 @@ UPDATE llx_c_availability SET type_duration = 'w', qty = 2 WHERE code = 'AV_2W'; UPDATE llx_c_availability SET type_duration = 'w', qty = 3 WHERE code = 'AV_3W'; UPDATE llx_c_availability SET type_duration = 'w', qty = 4 WHERE code = 'AV_4W'; + +-- Deposit generation helper with specific payment terms +ALTER TABLE llx_c_payment_term ADD COLUMN deposit_percent VARCHAR(63) DEFAULT NULL AFTER decalage; +ALTER TABLE llx_societe ADD COLUMN deposit_percent VARCHAR(63) DEFAULT NULL AFTER cond_reglement; +ALTER TABLE llx_propal ADD COLUMN deposit_percent VARCHAR(63) DEFAULT NULL AFTER fk_cond_reglement; +ALTER TABLE llx_commande ADD COLUMN deposit_percent VARCHAR(63) DEFAULT NULL AFTER fk_cond_reglement; +INSERT INTO llx_c_payment_term(code, sortorder, active, libelle, libelle_facture, type_cdr, nbjour, deposit_percent) values ('DEP30PCTDEL', 13, 0, '__DEPOSIT_PERCENT__% deposit', '__DEPOSIT_PERCENT__% deposit, remainder on delivery', 0, 1, '30'); + + ALTER TABLE llx_boxes_def ADD COLUMN fk_user integer DEFAULT 0 NOT NULL; ALTER TABLE llx_contratdet ADD COLUMN rang integer DEFAULT 0 AFTER info_bits; @@ -339,8 +350,14 @@ ALTER TABLE llx_takepos_floor_tables ADD UNIQUE(entity,label); ALTER TABLE llx_partnership ADD COLUMN url_to_check varchar(255); ALTER TABLE llx_c_partnership_type ADD COLUMN keyword varchar(128); + ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD COLUMN firstname varchar(100); ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD COLUMN lastname varchar(100); ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD COLUMN email_company varchar(128) after email; -ALTER TABLE llx_inventory ADD COLUMN fk_categories_product VARCHAR(255) DEFAULT NULL AFTER fk_product; +ALTER TABLE llx_inventory ADD COLUMN categories_product VARCHAR(255) DEFAULT NULL AFTER fk_product; + +ALTER TABLE llx_c_email_template ADD COLUMN email_from varchar(255); +ALTER TABLE llx_c_email_template ADD COLUMN email_to varchar(255); +ALTER TABLE llx_c_email_template ADD COLUMN email_tocc varchar(255); +ALTER TABLE llx_c_email_template ADD COLUMN email_tobcc varchar(255); diff --git a/htdocs/install/mysql/tables/llx_c_email_templates.sql b/htdocs/install/mysql/tables/llx_c_email_templates.sql index 04130a208fe..4d22767bc58 100644 --- a/htdocs/install/mysql/tables/llx_c_email_templates.sql +++ b/htdocs/install/mysql/tables/llx_c_email_templates.sql @@ -32,6 +32,10 @@ create table llx_c_email_templates position smallint, -- Position enabled varchar(255) DEFAULT '1', -- Condition to have this module visible active tinyint DEFAULT 1 NOT NULL, + email_from varchar(255), -- default email from + email_to varchar(255), -- default email to + email_tocc varchar(255), -- default email to cc + email_tobcc varchar(255), -- default email to bcc topic text, -- Predefined topic joinfiles text, -- Files to attach content mediumtext, -- Predefined text diff --git a/htdocs/install/mysql/tables/llx_c_payment_term.sql b/htdocs/install/mysql/tables/llx_c_payment_term.sql index 087ab63c184..e7b2b606b65 100644 --- a/htdocs/install/mysql/tables/llx_c_payment_term.sql +++ b/htdocs/install/mysql/tables/llx_c_payment_term.sql @@ -30,6 +30,7 @@ create table llx_c_payment_term type_cdr tinyint, -- Type of change date reckoning. 1=Payment at end of current month, 2=the Nth of next month nbjour smallint, decalage smallint, + deposit_percent varchar(63) DEFAULT NULL, module varchar(32) NULL, position integer NOT NULL DEFAULT 0 )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_commande.sql b/htdocs/install/mysql/tables/llx_commande.sql index 5b8a78c7bf8..94b1f38227d 100644 --- a/htdocs/install/mysql/tables/llx_commande.sql +++ b/htdocs/install/mysql/tables/llx_commande.sql @@ -63,6 +63,7 @@ create table llx_commande fk_account integer, -- bank account fk_currency varchar(3), -- currency code fk_cond_reglement integer, -- condition de reglement + deposit_percent varchar(63) DEFAULT NULL, -- default deposit % if payment term needs it fk_mode_reglement integer, -- mode de reglement date_livraison datetime default NULL, diff --git a/htdocs/install/mysql/tables/llx_inventory-stock.sql b/htdocs/install/mysql/tables/llx_inventory-stock.sql index 7df2f72534a..0c7a6d2eb49 100644 --- a/htdocs/install/mysql/tables/llx_inventory-stock.sql +++ b/htdocs/install/mysql/tables/llx_inventory-stock.sql @@ -29,7 +29,7 @@ CREATE TABLE llx_inventory fk_user_valid integer, -- valideur de la fiche fk_warehouse integer DEFAULT NULL, fk_product integer DEFAULT NULL, - fk_categories_product varchar(255) DEFAULT NULL, -- product categories id separated by comma + categories_product varchar(255) DEFAULT NULL, -- product categories id separated by comma status integer DEFAULT 0, title varchar(255) NOT NULL, date_inventory datetime DEFAULT NULL, diff --git a/htdocs/install/mysql/tables/llx_product.sql b/htdocs/install/mysql/tables/llx_product.sql index 80e3f90b828..83e8882caa7 100644 --- a/htdocs/install/mysql/tables/llx_product.sql +++ b/htdocs/install/mysql/tables/llx_product.sql @@ -40,8 +40,8 @@ create table llx_product customcode varchar(32), -- Optionnal custom code fk_country integer DEFAULT NULL, -- Optionnal id of original country fk_state integer DEFAULT NULL, -- Optionnal id of original state/province - price double(24,8) DEFAULT 0, - price_ttc double(24,8) DEFAULT 0, + price double(24,8) DEFAULT 0, -- price without tax + price_ttc double(24,8) DEFAULT 0, -- price inc vat (but not localtax1 nor localtax2) price_min double(24,8) DEFAULT 0, price_min_ttc double(24,8) DEFAULT 0, price_base_type varchar(3) DEFAULT 'HT', diff --git a/htdocs/install/mysql/tables/llx_product_price.sql b/htdocs/install/mysql/tables/llx_product_price.sql index 77a00939428..2a64fc92c30 100644 --- a/htdocs/install/mysql/tables/llx_product_price.sql +++ b/htdocs/install/mysql/tables/llx_product_price.sql @@ -29,8 +29,8 @@ create table llx_product_price fk_product integer NOT NULL, date_price datetime NOT NULL, price_level smallint NULL DEFAULT 1, - price double(24,8) DEFAULT NULL, - price_ttc double(24,8) DEFAULT NULL, + price double(24,8) DEFAULT NULL, -- price without tax + price_ttc double(24,8) DEFAULT NULL, -- price inc vat (but not localtax1 nor localtax2) price_min double(24,8) default NULL, price_min_ttc double(24,8) default NULL, price_base_type varchar(3) DEFAULT 'HT', diff --git a/htdocs/install/mysql/tables/llx_propal.sql b/htdocs/install/mysql/tables/llx_propal.sql index 3499a51e8b8..a8f0aa3e2c9 100644 --- a/htdocs/install/mysql/tables/llx_propal.sql +++ b/htdocs/install/mysql/tables/llx_propal.sql @@ -58,6 +58,7 @@ create table llx_propal fk_account integer, -- bank account fk_currency varchar(3), -- currency code fk_cond_reglement integer, -- condition de reglement (30 jours, fin de mois ...) + deposit_percent varchar(63) DEFAULT NULL, -- default deposit % if payment term needs it fk_mode_reglement integer, -- mode de reglement (Virement, Prelevement) online_sign_ip varchar(48), diff --git a/htdocs/install/mysql/tables/llx_societe.sql b/htdocs/install/mysql/tables/llx_societe.sql index c27a0fb2910..3c2f8a67be1 100644 --- a/htdocs/install/mysql/tables/llx_societe.sql +++ b/htdocs/install/mysql/tables/llx_societe.sql @@ -52,15 +52,6 @@ create table llx_societe email varchar(128), -- socialnetworks text DEFAULT NULL, -- json with socialnetworks - --skype varchar(255), -- deprecated - --twitter varchar(255), -- deprecated - --facebook varchar(255), -- deprecated - --linkedin varchar(255), -- deprecated - --instagram varchar(255), -- deprecated - --snapchat varchar(255), -- deprecated - --googleplus varchar(255), -- deprecated - --youtube varchar(255), -- deprecated - --whatsapp varchar(255), -- deprecated fk_effectif integer DEFAULT 0, -- fk_typent integer DEFAULT NULL, -- type ent @@ -93,6 +84,7 @@ create table llx_societe remise_supplier real DEFAULT 0, -- discount by default granted by this supplier mode_reglement tinyint, -- payment mode customer cond_reglement tinyint, -- payment term customer + deposit_percent varchar(63) DEFAULT NULL, -- default deposit % if payment term needs it transport_mode tinyint, -- transport mode customer (Intracomm report) mode_reglement_supplier tinyint, -- payment mode supplier cond_reglement_supplier tinyint, -- payment term supplier diff --git a/htdocs/install/mysql/tables/llx_societe_account.key.sql b/htdocs/install/mysql/tables/llx_societe_account.key.sql index e86c12aa306..e889a38d527 100644 --- a/htdocs/install/mysql/tables/llx_societe_account.key.sql +++ b/htdocs/install/mysql/tables/llx_societe_account.key.sql @@ -25,6 +25,8 @@ ALTER TABLE llx_societe_account ADD INDEX idx_societe_account_fk_soc (fk_soc); ALTER TABLE llx_societe_account ADD UNIQUE INDEX uk_societe_account_login_website_soc(entity, fk_soc, login, site, fk_website); ALTER TABLE llx_societe_account ADD UNIQUE INDEX uk_societe_account_key_account_soc(entity, fk_soc, key_account, site, fk_website); -ALTER TABLE llx_societe_account ADD CONSTRAINT llx_societe_account_fk_website FOREIGN KEY (fk_website) REFERENCES llx_website(rowid); +-- Table website does not always exists +--ALTER TABLE llx_societe_account ADD CONSTRAINT llx_societe_account_fk_website FOREIGN KEY (fk_website) REFERENCES llx_website(rowid); + ALTER TABLE llx_societe_account ADD CONSTRAINT llx_societe_account_fk_societe FOREIGN KEY (fk_soc) REFERENCES llx_societe(rowid); diff --git a/htdocs/install/pgsql/functions/functions-don.sql b/htdocs/install/pgsql/functions/functions-don.sql new file mode 100644 index 00000000000..a1a51b57e6d --- /dev/null +++ b/htdocs/install/pgsql/functions/functions-don.sql @@ -0,0 +1,20 @@ +-- ============================================================================ +-- Copyright (C) 2010 Laurent Destailleur +-- +-- 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 . +-- +-- ============================================================================ + +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_don FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_don_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); diff --git a/htdocs/install/pgsql/functions/functions-loan.sql b/htdocs/install/pgsql/functions/functions-loan.sql new file mode 100644 index 00000000000..d63e394e5c9 --- /dev/null +++ b/htdocs/install/pgsql/functions/functions-loan.sql @@ -0,0 +1,19 @@ +-- ============================================================================ +-- Copyright (C) 2010 Laurent Destailleur +-- +-- 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 . +-- +-- ============================================================================ + +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_loan FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); diff --git a/htdocs/install/pgsql/functions/functions-mailing.sql b/htdocs/install/pgsql/functions/functions-mailing.sql new file mode 100644 index 00000000000..d45d620399f --- /dev/null +++ b/htdocs/install/pgsql/functions/functions-mailing.sql @@ -0,0 +1,20 @@ +-- ============================================================================ +-- Copyright (C) 2010 Laurent Destailleur +-- +-- 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 . +-- +-- ============================================================================ + +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mailing FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mailing_cibles FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); diff --git a/htdocs/install/pgsql/functions/functions-opensurvey.sql b/htdocs/install/pgsql/functions/functions-opensurvey.sql new file mode 100644 index 00000000000..d42a8311cb2 --- /dev/null +++ b/htdocs/install/pgsql/functions/functions-opensurvey.sql @@ -0,0 +1,21 @@ +-- ============================================================================ +-- Copyright (C) 2010 Laurent Destailleur +-- +-- 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 . +-- +-- ============================================================================ + +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_opensurvey_comments FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_opensurvey_sondage FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_opensurvey_user_studs FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); diff --git a/htdocs/install/pgsql/functions/functions-partnership.sql b/htdocs/install/pgsql/functions/functions-partnership.sql new file mode 100644 index 00000000000..61e991e1197 --- /dev/null +++ b/htdocs/install/pgsql/functions/functions-partnership.sql @@ -0,0 +1,20 @@ +-- ============================================================================ +-- Copyright (C) 2010 Laurent Destailleur +-- +-- 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 . +-- +-- ============================================================================ + +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_partnership FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_partnership_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); diff --git a/htdocs/install/pgsql/functions/functions-recruitment.sql b/htdocs/install/pgsql/functions/functions-recruitment.sql new file mode 100644 index 00000000000..9fa6023be1a --- /dev/null +++ b/htdocs/install/pgsql/functions/functions-recruitment.sql @@ -0,0 +1,23 @@ +-- ============================================================================ +-- Copyright (C) 2010 Laurent Destailleur +-- +-- 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 . +-- +-- ============================================================================ + +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_recruitment_recruitmentjobposition FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_recruitment_recruitmentjobposition_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_recruitment_recruitmentcandidature FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_recruitment_recruitmentcandidature_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); + diff --git a/htdocs/install/pgsql/functions/functions-website.sql b/htdocs/install/pgsql/functions/functions-website.sql new file mode 100644 index 00000000000..a5597837466 --- /dev/null +++ b/htdocs/install/pgsql/functions/functions-website.sql @@ -0,0 +1,21 @@ +-- ============================================================================ +-- Copyright (C) 2010 Laurent Destailleur +-- +-- 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 . +-- +-- ============================================================================ + +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_website FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_website_page FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); + diff --git a/htdocs/install/pgsql/functions/functions.sql b/htdocs/install/pgsql/functions/functions.sql index d73678bcbab..35bc4e05c11 100644 --- a/htdocs/install/pgsql/functions/functions.sql +++ b/htdocs/install/pgsql/functions/functions.sql @@ -100,9 +100,6 @@ CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_contratdet_extrafiel CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_contratdet_log FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_subscription FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_cronjob FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_deplacement FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_don FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_don_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_ecm_directories FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_ecm_files FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_element_resources FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); @@ -126,19 +123,13 @@ CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_fichinter FOR EACH R CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_fichinter_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_fichinterdet_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_delivery FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_loan FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_localtax FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mailing FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mailing_cibles FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_menu FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_mo FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_mo_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_production FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_notify FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_notify_def FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_opensurvey_comments FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_opensurvey_sondage FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_opensurvey_user_studs FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_paiement FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_paiementcharge FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_paiementfourn FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); @@ -165,10 +156,6 @@ CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_propal_extrafields F CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_propal_merge_pdf_product FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_propaldet_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_resource FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_recruitment_recruitmentjobposition FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_recruitment_recruitmentjobposition_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_recruitment_recruitmentcandidature FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_recruitment_recruitmentcandidature_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_salary FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_societe FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_societe_address FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); @@ -187,5 +174,3 @@ CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_user FOR EACH ROW EX CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_user_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_usergroup FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_usergroup_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_website FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_website_page FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); diff --git a/htdocs/install/step1.php b/htdocs/install/step1.php index 63b8d66539b..9613e1a86b5 100644 --- a/htdocs/install/step1.php +++ b/htdocs/install/step1.php @@ -261,6 +261,7 @@ if (!$error) { $error++; } } + // If we need simple access if (!$error && (empty($db_create_database) && empty($db_create_user))) { $db = getDoliDBInstance($db_type, $db_host, $db_user, $db_pass, $db_name, $db_port); diff --git a/htdocs/install/step4.php b/htdocs/install/step4.php index e1890656f4b..c8be975c19f 100644 --- a/htdocs/install/step4.php +++ b/htdocs/install/step4.php @@ -82,9 +82,9 @@ if ($db->ok) { print ''; print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; if (isset($_GET["error"]) && $_GET["error"] == 1) { diff --git a/htdocs/knowledgemanagement/knowledgerecord_list.php b/htdocs/knowledgemanagement/knowledgerecord_list.php index feadd8d9800..b644546d8b9 100644 --- a/htdocs/knowledgemanagement/knowledgerecord_list.php +++ b/htdocs/knowledgemanagement/knowledgerecord_list.php @@ -189,7 +189,7 @@ if (empty($reshook)) { $search[$key.'_dtend'] = ''; } } - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 69dfc6bd478..4b60b70f7ad 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -718,7 +718,8 @@ Permission34=Delete products Permission36=See/manage hidden products Permission38=Export products Permission39=Ignore minimum price -Permission41=Read projects and tasks (shared project and projects I'm contact for). Can also enter time consumed, for me or my hierarchy, on assigned tasks (Timesheet) +Permission41=Read projects and tasks (shared project and projects I'm contact for). +Permission145=Can enter time consumed, for me or my hierarchy, on assigned tasks (Timesheet) Permission42=Create/modify projects (shared project and projects I'm contact for). Can also create tasks and assign users to project and tasks Permission44=Delete projects (shared project and projects I'm contact for) Permission45=Export projects diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index a70d2eb8f21..22ca3f4cec1 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -429,10 +429,19 @@ PaymentConditionShort14D=14 days PaymentCondition14D=14 days PaymentConditionShort14DENDMONTH=14 days of month-end PaymentCondition14DENDMONTH=Within 14 days following the end of the month +PaymentConditionShortDEP30PCTDEL=__DEPOSIT_PERCENT__%% deposit +PaymentConditionDEP30PCTDEL=__DEPOSIT_PERCENT__%% deposit, remainder on delivery FixAmount=Fixed amount - 1 line with label '%s' VarAmount=Variable amount (%% tot.) VarAmountOneLine=Variable amount (%% tot.) - 1 line with label '%s' VarAmountAllLines=Variable amount (%% tot.) - all lines from origin +DepositPercent=Deposit %% +DepositGenerationPermittedByThePaymentTermsSelected=This is permitted by the payment terms selected +GenerateDeposit=Generate a %s%% deposit invoice +ValidateGeneratedDeposit=Validate the generated deposit +DepositGenerated=Deposit generated +ErrorCanOnlyAutomaticallyGenerateADepositFromProposalOrOrder=You can only automatically generate a deposit from a proposal or an order +ErrorPaymentConditionsNotEligibleToDepositCreation=The chose payment conditions are not eligible for automatic deposit generation # PaymentType PaymentTypeVIR=Bank transfer PaymentTypeShortVIR=Bank transfer diff --git a/htdocs/langs/en_US/categories.lang b/htdocs/langs/en_US/categories.lang index cf0de898bdb..a2d05767cae 100644 --- a/htdocs/langs/en_US/categories.lang +++ b/htdocs/langs/en_US/categories.lang @@ -90,6 +90,7 @@ CategorieRecursivHelp=If option is on, when you add a product into a subcategory AddProductServiceIntoCategory=Add the following product/service AddCustomerIntoCategory=Assign category to customer AddSupplierIntoCategory=Assign category to supplier +AssignCategoryTo=Assign category to ShowCategory=Show tag/category ByDefaultInList=By default in list ChooseCategory=Choose category diff --git a/htdocs/langs/en_US/install.lang b/htdocs/langs/en_US/install.lang index 989f6aa9793..18a2eee941c 100644 --- a/htdocs/langs/en_US/install.lang +++ b/htdocs/langs/en_US/install.lang @@ -8,6 +8,7 @@ ConfFileIsNotWritable=Configuration file %s is not writable. Check permis ConfFileIsWritable=Configuration file %s is writable. ConfFileMustBeAFileNotADir=Configuration file %s must be a file, not a directory. ConfFileReload=Reloading parameters from configuration file. +NoReadableConfFileSoStartInstall=The configuration file conf/conf.php does not exists or is not reabable. We will run the installation process to try to initialize it. PHPSupportPOSTGETOk=This PHP supports variables POST and GET. PHPSupportPOSTGETKo=It's possible your PHP setup does not support variables POST and/or GET. Check the parameter variables_order in php.ini. PHPSupportSessions=This PHP supports sessions. diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index c06271ce1fd..1b2a18ede64 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -424,4 +424,7 @@ PMPExpected=Expected PMP ExpectedValuation=Expected Valuation PMPReal=Real PMP RealValuation=Real Valuation +ConfirmEditExtrafield = Select the extrafield you want modify +ConfirmEditExtrafieldQuestion = Are you sure you want to modify this extrafield? +ModifyValueExtrafields = Modify value of an extrafield OrProductsWithCategories=Or products with tags/categories diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index 034f105f6d8..8aa317ca305 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -718,7 +718,8 @@ Permission34=Supprimer les produits Permission36=Voir/gérer les produits cachés Permission38=Exporter les produits Permission39=Ignorer le prix minimum -Permission41=Lire les projets et tâches (partagés ou dont vous n'êtes pas contact). Permet la saisie de temps passé, pour vous-même et votre hiérarchie (vos subordonnés), sur les tâches assignées (Feuilles de temps). +Permission41=Lire les projets et tâches (partagés ou dont vous n'êtes pas contact). +Permission145=Permet la saisie de temps passé, pour vous-même et votre hiérarchie (vos subordonnés), sur les tâches assignées (Feuilles de temps). Permission42=Créer/modifier les projets (projets partagés et projets pour lesquels je suis contact). Permet aussi de créer des tâches et d'assigner des utilisateurs aux projets et tâches. Permission44=Supprimer les projets et tâches (partagés ou dont je suis contact) Permission45=Exporter les projets diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang index 53ff7d545b3..bc2ce45f8db 100644 --- a/htdocs/langs/fr_FR/main.lang +++ b/htdocs/langs/fr_FR/main.lang @@ -418,7 +418,7 @@ TotalLT2IN=Total SGST HT=HT TTC=TTC INCVATONLY=TVA incluse -INCT=TTC +INCT=TVA+Taxes locales incluses VAT=TVA VATIN=IGST VATs=TVA diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 7e2cb072913..21218f099fe 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -2083,6 +2083,7 @@ function top_menu($head, $title = '', $target = '', $disablejs = 0, $disablehead print "\n"; // end div class="login_block" print ''; + //print '
     
    '; print '
    '; print "\n\n"; @@ -2149,7 +2150,7 @@ function top_menu_user($hideloginname = 0, $urllogout = '') $dropdownBody .= '
    '.$langs->transcountry("ProfId6", $mysoc->country_code).': '.dol_print_profids(getDolGlobalString("MAIN_INFO_PROFID6"), 6).''; } $dropdownBody .= '
    '.$langs->trans("VATIntraShort").': '.dol_print_profids(getDolGlobalString("MAIN_INFO_TVAINTRA"), 'VAT').''; - $dropdownBody .= '
    '.$langs->trans("Country").': '.$langs->trans("Country".$mysoc->country_code).''; + $dropdownBody .= '
    '.$langs->trans("Country").': '.($mysoc->country_code ? $langs->trans("Country".$mysoc->country_code) : '').''; $dropdownBody .= ''; diff --git a/htdocs/modulebuilder/admin/setup.php b/htdocs/modulebuilder/admin/setup.php index 01a02d0c7dd..e7c42578bd6 100644 --- a/htdocs/modulebuilder/admin/setup.php +++ b/htdocs/modulebuilder/admin/setup.php @@ -89,7 +89,8 @@ if (preg_match('/del_(.*)/', $action, $reg)) { $form = new Form($db); -llxHeader('', $langs->trans("ModulebuilderSetup")); +$help_url = ''; +llxHeader('', $langs->trans("ModulebuilderSetup"), $help_url); $linkback = ''.$langs->trans("BackToModuleList").''; diff --git a/htdocs/modulebuilder/template/admin/myobject_extrafields.php b/htdocs/modulebuilder/template/admin/myobject_extrafields.php index 5ce224c8528..e5ed6469fa2 100644 --- a/htdocs/modulebuilder/template/admin/myobject_extrafields.php +++ b/htdocs/modulebuilder/template/admin/myobject_extrafields.php @@ -91,6 +91,8 @@ require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; * View */ +$textobject = $langs->transnoentitiesnoconv("MyObject"); + $help_url = ''; $page_name = "MyModuleSetup"; diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php index fe92596d228..84b394da808 100644 --- a/htdocs/modulebuilder/template/admin/setup.php +++ b/htdocs/modulebuilder/template/admin/setup.php @@ -531,7 +531,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print ''; $constforvar = 'MYMODULE_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $file) { + if (getDolGlobalString($constforvar) == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { print ''; @@ -673,7 +673,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Default print ''; $constforvar = 'MYMODULE_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $name) { + if (getDolGlobalString($constforvar) == $name) { //print img_picto($langs->trans("Default"), 'on'); // Even if choice is the default value, we allow to disable it. Replace this with previous line if you need to disable unset print 'scandir).'&label='.urlencode($module->name).'&type='.urlencode($type).'" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').''; diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php index d843687157a..b6327e230fb 100644 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php @@ -428,7 +428,7 @@ class modMyModule extends DolibarrModules { global $conf, $langs; - //$result = $this->_load_tables('/install/mysql/tables/', 'mymodule'); + //$result = $this->_load_tables('/install/mysql/', 'mymodule'); $result = $this->_load_tables('/mymodule/sql/'); if ($result < 0) { return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') diff --git a/htdocs/mrp/mo_movements.php b/htdocs/mrp/mo_movements.php index 10e430479cf..7bb040abe1f 100644 --- a/htdocs/mrp/mo_movements.php +++ b/htdocs/mrp/mo_movements.php @@ -193,7 +193,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_batch = ""; $search_qty = ''; $sall = ""; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } diff --git a/htdocs/opensurvey/list.php b/htdocs/opensurvey/list.php index b0fafc9e357..0e22c524529 100644 --- a/htdocs/opensurvey/list.php +++ b/htdocs/opensurvey/list.php @@ -137,7 +137,7 @@ if (empty($reshook)) { $search_status = ''; $search_title = ''; $search_ref = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') diff --git a/htdocs/partnership/admin/partnership_extrafields.php b/htdocs/partnership/admin/partnership_extrafields.php index 573f3f1cbba..04f75cf20b2 100644 --- a/htdocs/partnership/admin/partnership_extrafields.php +++ b/htdocs/partnership/admin/partnership_extrafields.php @@ -65,6 +65,8 @@ require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; * View */ +$textobject = $langs->transnoentitiesnoconv("Partnership"); + $help_url = ''; $title = $langs->trans("PartnershipSetup"); diff --git a/htdocs/partnership/partnership_list.php b/htdocs/partnership/partnership_list.php index 2eaa8cc5dd2..42d4354516e 100644 --- a/htdocs/partnership/partnership_list.php +++ b/htdocs/partnership/partnership_list.php @@ -185,7 +185,7 @@ if (empty($reshook)) { $search[$key.'_dtend'] = ''; } } - $toselect = ''; + $toselect = array(); $search_array_options = array(); $search_filter = ""; } diff --git a/htdocs/product/admin/inventory_extrafields.php b/htdocs/product/admin/inventory_extrafields.php index d21328da336..0dd5be8bfae 100644 --- a/htdocs/product/admin/inventory_extrafields.php +++ b/htdocs/product/admin/inventory_extrafields.php @@ -73,6 +73,7 @@ require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; * View */ +$textobject = $langs->transnoentitiesnoconv("Inventory"); llxHeader('', $langs->trans("InventorySetup"), $help_url); diff --git a/htdocs/product/admin/stock_mouvement_extrafields.php b/htdocs/product/admin/stock_mouvement_extrafields.php index 23e5aadc9cc..e7fcf2382f8 100644 --- a/htdocs/product/admin/stock_mouvement_extrafields.php +++ b/htdocs/product/admin/stock_mouvement_extrafields.php @@ -73,6 +73,7 @@ require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; * View */ +$textobject = $langs->transnoentitiesnoconv("StockMovement"); llxHeader('', $langs->trans("StockSetup"), $help_url); diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 5bcde058907..a6cac07d7e1 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2065,7 +2065,7 @@ class Product extends CommonObject /** - * Modify customer price of a product/Service + * Modify customer price of a product/Service for a given level * * @param double $newprice New price * @param string $newpricebase HT or TTC diff --git a/htdocs/product/inventory/class/inventory.class.php b/htdocs/product/inventory/class/inventory.class.php index d3db5d3ce93..639ed284523 100644 --- a/htdocs/product/inventory/class/inventory.class.php +++ b/htdocs/product/inventory/class/inventory.class.php @@ -102,7 +102,7 @@ class Inventory extends CommonObject 'title' => array('type'=>'varchar(255)', 'label'=>'Label', 'visible'=>1, 'enabled'=>1, 'position'=>25, 'css'=>'minwidth300', 'csslist'=>'tdoverflowmax200'), 'fk_warehouse' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Warehouse', 'visible'=>1, 'enabled'=>1, 'position'=>30, 'index'=>1, 'help'=>'InventoryForASpecificWarehouse', 'picto'=>'stock', 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'csslist'=>'tdoverflowmax200'), 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php', 'label'=>'Product', 'visible'=>1, 'enabled'=>1, 'position'=>32, 'index'=>1, 'help'=>'InventoryForASpecificProduct', 'picto'=>'product', 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'csslist'=>'tdoverflowmax200'), - 'fk_categories_product' => array('type'=>'chkbxlst:categorie:label:rowid::type=0:0:', 'label'=>'OrProductsWithCategories', 'visible'=>3, 'enabled'=>1, 'position'=>33, 'help'=>'', 'picto'=>'category', 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx'), + 'categories_product' => array('type'=>'chkbxlst:categorie:label:rowid::type=0:0:', 'label'=>'OrProductsWithCategories', 'visible'=>3, 'enabled'=>1, 'position'=>33, 'help'=>'', 'picto'=>'category', 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx'), 'date_inventory' => array('type'=>'date', 'label'=>'DateValue', 'visible'=>1, 'enabled'=>'$conf->global->STOCK_INVENTORY_ADD_A_VALUE_DATE', 'position'=>35), // This date is not used so disabled by default. 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>500), 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>501), @@ -143,7 +143,7 @@ class Inventory extends CommonObject /** * @var string Categories id separated by comma */ - public $fk_categories_product; + public $categories_product; public $date_inventory; public $title; @@ -297,12 +297,12 @@ class Inventory extends CommonObject if ($this->fk_warehouse > 0) { $sql .= " AND ps.fk_entrepot = ".((int) $this->fk_warehouse); } - if (!empty($this->fk_categories_product)) { + if (!empty($this->categories_product)) { $sql .= " AND EXISTS ("; $sql .= " SELECT cp.fk_product"; $sql .= " FROM ".$this->db->prefix()."categorie_product AS cp"; $sql .= " WHERE cp.fk_product = ps.fk_product"; - $sql .= " AND cp.fk_categorie IN (".$this->db->sanitize($this->fk_categories_product).")"; + $sql .= " AND cp.fk_categorie IN (".$this->db->sanitize($this->categories_product).")"; $sql .= ")"; } diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 5351c55334e..2e157de504a 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -28,6 +28,7 @@ include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; include_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; include_once DOL_DOCUMENT_ROOT.'/product/inventory/lib/inventory.lib.php'; include_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; +include_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; // Load translation files required by the page $langs->loadLangs(array("stocks", "other", "productbatch")); @@ -186,25 +187,6 @@ if (empty($reshook)) { break; } - if (!empty($line->pmp_real) && !empty($conf->global->INVENTORY_MANAGE_REAL_PMP)) { - $sqlpmp = 'UPDATE '.MAIN_DB_PREFIX.'product SET pmp = '.((float) $line->pmp_real).' WHERE rowid = '.((int) $line->fk_product); - $resqlpmp = $db->query($sqlpmp); - if (! $resqlpmp) { - $error++; - setEventMessages($db->lasterror(), null, 'errors'); - break; - } - if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) { - $sqlpmp = 'UPDATE '.MAIN_DB_PREFIX.'product_perentity SET pmp = '.((float) $line->pmp_real).' WHERE fk_product = '.((int) $line->fk_product).' AND entity='.$conf->entity; - $resqlpmp = $db->query($sqlpmp); - if (! $resqlpmp) { - $error++; - setEventMessages($db->lasterror(), null, 'errors'); - break; - } - } - } - // Update line with id of stock movement (and the start quantity if it has changed this last recording) $sqlupdate = "UPDATE ".MAIN_DB_PREFIX."inventorydet"; $sqlupdate .= " SET fk_movement = ".((int) $idstockmove); @@ -219,6 +201,25 @@ if (empty($reshook)) { break; } } + + if (!empty($line->pmp_real) && !empty($conf->global->INVENTORY_MANAGE_REAL_PMP)) { + $sqlpmp = 'UPDATE '.MAIN_DB_PREFIX.'product SET pmp = '.((float) $line->pmp_real).' WHERE rowid = '.((int) $line->fk_product); + $resqlpmp = $db->query($sqlpmp); + if (! $resqlpmp) { + $error++; + setEventMessages($db->lasterror(), null, 'errors'); + break; + } + if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) { + $sqlpmp = 'UPDATE '.MAIN_DB_PREFIX.'product_perentity SET pmp = '.((float) $line->pmp_real).' WHERE fk_product = '.((int) $line->fk_product).' AND entity='.$conf->entity; + $resqlpmp = $db->query($sqlpmp); + if (! $resqlpmp) { + $error++; + setEventMessages($db->lasterror(), null, 'errors'); + break; + } + } + } } $i++; } @@ -910,14 +911,16 @@ if ($object->id > 0) { print ''; } print ''.$langs->trans("ExpectedQty").''; - print ''; - print $form->textwithpicto($langs->trans("RealQty"), $langs->trans("InventoryRealQtyHelp")); - print ''; if (!empty($conf->global->INVENTORY_MANAGE_REAL_PMP)) { print ''.$langs->trans('PMPExpected').''; print ''.$langs->trans('ExpectedValuation').''; + print ''.$form->textwithpicto($langs->trans("RealQty"), $langs->trans("InventoryRealQtyHelp")).''; print ''.$langs->trans('PMPReal').''; print ''.$langs->trans('RealValuation').''; + } else { + print ''; + print $form->textwithpicto($langs->trans("RealQty"), $langs->trans("InventoryRealQtyHelp")); + print ''; } if ($object->status == $object::STATUS_DRAFT || $object->status == $object::STATUS_VALIDATED) { // Actions or link to stock movement @@ -1020,7 +1023,13 @@ if ($object->id > 0) { if (!empty($conf->productbatch->enabled)) { print ''; - print dol_escape_htmltag($obj->batch); + $batch_static = new Productlot($db); + $res = $batch_static->fetch(0, $product_static->id, $obj->batch); + if ($res) { + print $batch_static->getNomUrl(1); + } else { + print dol_escape_htmltag($obj->batch); + } print ''; } @@ -1041,7 +1050,6 @@ if ($object->id > 0) { // Real quantity if ($object->status == $object::STATUS_DRAFT || $object->status == $object::STATUS_VALIDATED) { - print ''; $qty_view = GETPOST("id_".$obj->rowid) && price2num(GETPOST("id_".$obj->rowid), 'MS') >= 0 ? GETPOST("id_".$obj->rowid) : $obj->qty_view; //if (!$hasinput && $qty_view !== null && $obj->qty_stock != $qty_view) { @@ -1049,11 +1057,6 @@ if ($object->id > 0) { $hasinput = true; } - print ''; - print img_picto('', 'eraser', 'class="opacitymedium"'); - print ''; - print ''; - print ''; if (! empty($conf->global->INVENTORY_MANAGE_REAL_PMP)) { //PMP Expected if (! empty($obj->pmp_expected)) $pmp_expected = $obj->pmp_expected; @@ -1066,6 +1069,14 @@ if ($object->id > 0) { print ''; print price($pmp_valuation); print ''; + + print ''; + print ''; + print img_picto('', 'eraser', 'class="opacitymedium"'); + print ''; + print ''; + print ''; + //PMP Real print ''; @@ -1081,18 +1092,22 @@ if ($object->id > 0) { $totalExpectedValuation += $pmp_valuation; $totalRealValuation += $pmp_valuation_real; + } else { + print ''; + print ''; + print img_picto('', 'eraser', 'class="opacitymedium"'); + print ''; + print ''; + print ''; } // Picto delete line print ''; print ''.img_delete().''; $qty_tmp = price2num(GETPOST("id_".$obj->rowid."_input_tmp", 'MS')) >= 0 ? GETPOST("id_".$obj->rowid."_input_tmp") : $qty_view; - print ''; + print ''; print ''; } else { - print ''; - print $obj->qty_view; // qty found - print ''; if (!empty($conf->global->INVENTORY_MANAGE_REAL_PMP)) { //PMP Expected if (! empty($obj->pmp_expected)) $pmp_expected = $obj->pmp_expected; @@ -1105,6 +1120,10 @@ if ($object->id > 0) { print price($pmp_valuation); print ''; + print ''; + print $obj->qty_view; // qty found + print ''; + //PMP Real print ''; if (! empty($obj->pmp_real)) $pmp_real = $obj->pmp_real; @@ -1115,12 +1134,15 @@ if ($object->id > 0) { print ''; print price($pmp_valuation_real); print ''; + print ''; $totalExpectedValuation += $pmp_valuation; $totalRealValuation += $pmp_valuation_real; + } else { + print ''; + print $obj->qty_view; // qty found + print ''; } - - print ''; if ($obj->fk_movement > 0) { $stockmovment = new MouvementStock($db); $stockmovment->fetch($obj->fk_movement); diff --git a/htdocs/product/list.php b/htdocs/product/list.php index de5e4f278b7..2938e524377 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -727,6 +727,7 @@ if ($resql) { // List of mass actions available $arrayofmassactions = array( 'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"), + 'edit_extrafields'=>img_picto('', 'edit', 'class="pictofixedwidth"').$langs->trans("ModifyValueExtrafields"), //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), ); @@ -739,7 +740,7 @@ if ($resql) { $arrayofmassactions['switchonpurchasestatus'] = img_picto('', 'stop-circle', 'class="pictofixedwidth"').$langs->trans("SwitchOnPurchaseStatus"); $arrayofmassactions['preaffecttag'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("AffectTag"); } - if (in_array($massaction, array('presend', 'predelete','preaffecttag'))) { + if (in_array($massaction, array('presend', 'predelete','preaffecttag', 'edit_extrafields'))) { $arrayofmassactions = array(); } $massactionbutton = $form->selectMassAction('', $arrayofmassactions); diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 47322e2c692..ab3086bfd0b 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -192,15 +192,50 @@ if (empty($reshook)) { } if (!$error) { - // Force the update of the price of the product to 0 if error + if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { + for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { + // Force the update of the price of the product using the new VAT + if ($object->multiprices_base_type[$i] == 'HT') { + $oldprice = $object->multiprices[$i]; + $oldminprice = $object->multiprices_min[$i]; + } else { + $oldprice = $object->multiprices_ttc[$i]; + $oldminprice = $object->multiprices_min_ttc[$i]; + } + $oldpricebasetype = $object->multiprices_base_type[$i]; + $oldnpr = $object->multiprices_recuperableonly[$i]; - //$localtaxarray=array('0'=>$localtax1_type,'1'=>$localtax1,'2'=>$localtax2_type,'3'=>$localtax2); - $localtaxarray = array(); // We do not store localtaxes into product, we will use instead the "vat code" to retrieve them. - $ret = $object->updatePrice(0, $object->price_base_type, $user, $tva_tx, '', 0, $npr, 0, 0, $localtaxarray, $vatratecode); + //$localtaxarray=array('0'=>$localtax1_type,'1'=>$localtax1,'2'=>$localtax2_type,'3'=>$localtax2); + $localtaxarray = array(); // We do not store localtaxes into product, we will use instead the "vat code" to retrieve them. + $level = $i; + $ret = $object->updatePrice($oldprice, $oldpricebasetype, $user, $tva_tx, $oldminprice, $level, $oldnpr, 0, 0, $localtaxarray, $vatratecode); - if ($ret < 0) { - $error++; - setEventMessages($object->error, $object->errors, 'errors'); + if ($ret < 0) { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + } + } + } else { + // Force the update of the price of the product using the new VAT + if ($object->price_base_type == 'HT') { + $oldprice = $object->price; + $oldminprice = $object->price_min; + } else { + $oldprice = $object->price_ttc; + $oldminprice = $object->price_min_ttc; + } + $oldpricebasetype = $object->price_base_type; + $oldnpr = $object->tva_npr; + + //$localtaxarray=array('0'=>$localtax1_type,'1'=>$localtax1,'2'=>$localtax2_type,'3'=>$localtax2); + $localtaxarray = array(); // We do not store localtaxes into product, we will use instead the "vat code" to retrieve them. + $level = 0; + $ret = $object->updatePrice($oldprice, $oldpricebasetype, $user, $tva_tx, $oldminprice, $level, $oldnpr, 0, 0, $localtaxarray, $vatratecode); + + if ($ret < 0) { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + } } } @@ -1602,6 +1637,7 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action == 'showlog_defaul } $sql .= " ORDER BY p.date_price DESC, p.rowid DESC, p.price_level ASC"; // $sql .= $db->plimit(); + //print $sql; $result = $db->query($sql); if ($result) { @@ -1640,8 +1676,9 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action == 'showlog_defaul print_barre_liste($langs->trans("PriceByCustomerLog"), 0, $_SERVER["PHP_SELF"], '', '', '', '', 0, $num, 'title_accountancy.png'); } - print '
    '; - print ''; + print ''."\n"; + print '
    '."\n"; + print '
    '."\n"; print ''; print ''; @@ -1659,6 +1696,9 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action == 'showlog_defaul } print ''; print ''; + if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") { + print ''; + } if (!empty($conf->dynamicprices->enabled)) { print ''; } @@ -1725,6 +1765,24 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action == 'showlog_defaul print ""; } + // Line for default price + if ($objp->price_base_type == 'HT') { + $pu = $objp->price; + } else { + $pu = $objp->price_ttc; + } + + // Local tax was not saved into table llx_product on old version. So we will use value linked to VAT code. + $localtaxarray = getLocalTaxesFromRate($objp->tva_tx.($object->default_vat_code ? ' ('.$object->default_vat_code.')' : ''), 0, $mysoc, $mysoc); + // Define part of HT, VAT, TTC + $resultarray = calcul_price_total(1, $pu, 0, $objp->tva_tx, 1, 1, 0, $objp->price_base_type, $objp->recuperableonly, $object->type, $mysoc, $localtaxarray); + // Calcul du total ht sans remise + $total_ht = $resultarray[0]; + $total_vat = $resultarray[1]; + $total_localtax1 = $resultarray[9]; + $total_localtax2 = $resultarray[10]; + $total_ttc = $resultarray[2]; + // Price if (!empty($objp->fk_price_expression) && !empty($conf->dynamicprices->enabled)) { $price_expression = new PriceExpression($db); @@ -1732,32 +1790,46 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action == 'showlog_defaul $title = $price_expression->title; print ''; print ''; + if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") { + print ''; + } print '"; } else { + // Price HT print '"; + // Price TTC print '"; + if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") { + print ''; + } if (!empty($conf->dynamicprices->enabled)) { //Only if module is enabled print ''; } } + // Price min print ''; + // Price min inc tax print ''; @@ -2042,11 +2114,9 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print ''; print ''; print ''; + print ''; if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") { - //print ''; print ''; - } else { - print ''; } print ''; print ''; @@ -2107,11 +2177,9 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print ""; print '"; + print '"; if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") { - //print '"; print ''; - } else { - print '"; } print ''; @@ -2154,12 +2222,15 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print ''; print ''; - print '
    '; - print '
    '.$langs->trans("AppliedPricesFrom").''.$langs->trans("HT").''.$langs->trans("TTC").''.$langs->trans("INCT").''.$langs->trans("PriceExpressionSelected").''.$title."'; if (empty($objp->price_by_qty)) { print price($objp->price); } print "'; if (empty($objp->price_by_qty)) { - print price($objp->price_ttc); + $price_ttc = $objp->price_ttc; + print price($price_ttc); } print "'; + print $resultarray[2]; + print ''; if (empty($objp->price_by_qty)) { print price($objp->price_min); } print ''; if (empty($objp->price_by_qty)) { - print price($objp->price_min_ttc); + $price_min_ttc = $objp->price_min_ttc; + print price($price_min_ttc); } print ''.$langs->trans("PriceBase").''.$langs->trans("DefaultTaxRate").''.$langs->trans("HT").''.$langs->trans("TTC").'' . $langs->trans("INCVATONLY") . ''.$langs->trans("INCT").''.$langs->trans("TTC").''.$langs->trans("MinPrice").' '.$langs->trans("HT").''.$langs->trans("MinPrice").' '.$langs->trans("TTC").''.price($line->price)."'.price($line->price_ttc)."' . price($line->price_ttc) . "'.price($resultarray[2]).''.price($line->price_ttc)."'.price($line->price_min).'
    '; + print ''."\n"; + print '
    '."\n"; + print '
    '."\n"; if (count($prodcustprice->lines) > 0 || $search_soc) { $colspan = 9; - //if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") $colspan++; + if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") { + $colspan++; + } print ''; print ''; @@ -2179,13 +2250,10 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print ''; print ''; print ''; + print ''; if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") { - //print ''; print ''; - } else { - print ''; } - print ''; print ''; print ''; @@ -2199,7 +2267,7 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { $pu = $object->price_ttc; } - // Local tax is not saved into table of product. We use value linked to VAT code. + // Local tax was not saved into table llx_product on old version. So we will use value linked to VAT code. $localtaxarray = getLocalTaxesFromRate($object->tva_tx.($object->default_vat_code ? ' ('.$object->default_vat_code.')' : ''), 0, $mysoc, $mysoc); // Define part of HT, VAT, TTC $resultarray = calcul_price_total(1, $pu, 0, $object->tva_tx, 1, 1, 0, $object->price_base_type, $object->recuperableonly, $object->type, $mysoc, $localtaxarray); @@ -2237,14 +2305,12 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print '"; + print '"; if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") { //print '"; print ''; - } else { - print '"; } - print ''; print ''; print '"; print '"; + print '"; if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") { //print '"; print ''; - } else { - print '"; } print ''; diff --git a/htdocs/product/stock/movement_card.php b/htdocs/product/stock/movement_card.php index abcc5f7da42..e31420b7f21 100644 --- a/htdocs/product/stock/movement_card.php +++ b/htdocs/product/stock/movement_card.php @@ -161,7 +161,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_batch = ""; $search_qty = ''; $sall = ""; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } diff --git a/htdocs/product/stock/movement_list.php b/htdocs/product/stock/movement_list.php index 73c6751262a..2ad77fca49e 100644 --- a/htdocs/product/stock/movement_list.php +++ b/htdocs/product/stock/movement_list.php @@ -223,7 +223,7 @@ if (empty($reshook)) { $search_qty = ''; $search_fk_projet=0; $sall = ""; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php index 74abbad9140..565b309b113 100644 --- a/htdocs/product/stock/productlot_list.php +++ b/htdocs/product/stock/productlot_list.php @@ -168,7 +168,7 @@ if (empty($reshook)) { foreach ($object->fields as $key => $val) { $search[$key] = ''; } - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 9decf78f55a..10d4afcd9a7 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -920,6 +920,7 @@ class Task extends CommonObjectLine // Add where from extra fields $extrafieldsobjectkey = 'projet_task'; $extrafieldsobjectprefix = 'efpt.'; + global $db; // needed for extrafields_list_search_sql.tpl include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks $parameters = array(); diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 6ec329c41f4..0d5c4964003 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -285,7 +285,7 @@ if (empty($reshook)) { $search_accept_booth_suggestions = ''; $search_price_registration = ''; $search_price_booth = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); $search_category_array = array(); } diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index 364fcfe49f1..aabca026f20 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -209,7 +209,7 @@ if (empty($reshook)) { $search_progresscalc = ''; $search_progressdeclare = ''; $search_task_budget_amount = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); $search_date_start_startmonth = ""; $search_date_start_startyear = ""; diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 4374ffb2d37..53d0e6c7f91 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -164,12 +164,12 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_task_label = ''; $search_user = 0; $search_valuebilled = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); $action = ''; } -if ($action == 'addtimespent' && $user->rights->projet->lire) { +if ($action == 'addtimespent' && $user->rights->projet->time) { $error = 0; $timespent_durationhour = GETPOST('timespent_durationhour', 'int'); @@ -313,7 +313,7 @@ if (($action == 'updateline' || $action == 'updatesplitline') && !$cancel && $us } } -if ($action == 'confirm_deleteline' && $confirm == "yes" && $user->rights->projet->lire) { +if ($action == 'confirm_deleteline' && $confirm == "yes" && $user->rights->projet->supprimer) { $object->fetchTimeSpent(GETPOST('lineid', 'int')); // load properties like $object->timespent_id if (in_array($object->timespent_fk_user, $childids) || $user->rights->projet->all->creer) { @@ -888,7 +888,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser $linktocreatetimeBtnStatus = 0; $linktocreatetimeUrl = ''; $linktocreatetimeHelpText = ''; - if ($user->rights->projet->all->lire || $user->rights->projet->lire) { // To enter time, read permission is enough + if ($user->rights->projet->all->lire || $user->rights->projet->time) { if ($projectstatic->public || $userRead > 0) { $linktocreatetimeBtnStatus = 1; @@ -1032,6 +1032,10 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if ($projectstatic->id > 0 || $allprojectforuser > 0) { + if ($action == 'deleteline' && !empty($projectidforalltimes)) { + print $form->formconfirm($_SERVER["PHP_SELF"]."?".($object->id > 0 ? "id=".$object->id : 'projectid='.$projectstatic->id).'&lineid='.GETPOST('lineid', 'int').($withproject ? '&withproject=1' : ''), $langs->trans("DeleteATimeSpent"), $langs->trans("ConfirmDeleteATimeSpent"), "confirm_deleteline", '', '', 1); + } + // Initialize technical object to manage hooks. Note that conf->hooks_modules contains array $hookmanager->initHooks(array('tasktimelist')); @@ -1129,7 +1133,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; } elseif ($action == 'splitline') { print ''; - } elseif ($action == 'createtime' && $user->rights->projet->lire) { + } elseif ($action == 'createtime' && $user->rights->projet->time) { print ''; } elseif ($massaction == 'generateinvoice' && $user->rights->facture->lire) { print ''; @@ -1403,7 +1407,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser /* * Form to add a new line of time spent */ - if ($action == 'createtime' && $user->rights->projet->lire) { + if ($action == 'createtime' && $user->rights->projet->time) { print ''."\n"; if (!empty($id)) { print ''; @@ -1863,8 +1867,8 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; print '
    '; print ''; - } elseif ($user->rights->projet->lire || $user->rights->projet->all->creer) { // Read project and enter time consumed on assigned tasks - if (in_array($task_time->fk_user, $childids) || $user->rights->projet->all->creer) { + } elseif ($user->rights->projet->time || $user->rights->projet->all->creer) { // Read project and enter time consumed on assigned tasks + if ($task_time->fk_user == $user->id || in_array($task_time->fk_user, $childids) || $user->rights->projet->all->creer) { if ($conf->MAIN_FEATURES_LEVEL >= 2) { print ' '; print 'rowid.$param.((empty($id) || $tab == 'timespent') ? '&tab=timespent' : '').'">'; diff --git a/htdocs/public/eventorganization/attendee_new.php b/htdocs/public/eventorganization/attendee_new.php index a7cdd1ceda8..70bad2a31dc 100644 --- a/htdocs/public/eventorganization/attendee_new.php +++ b/htdocs/public/eventorganization/attendee_new.php @@ -262,6 +262,7 @@ if (empty($reshook) && $action == 'add' && (!empty($conference->id) && $conferen $confattendee->fk_project = $project->id; $confattendee->fk_actioncomm = $id; $confattendee->note_public = $note_public; + $resultconfattendee = $confattendee->create($user); if ($resultconfattendee < 0) { $error++; @@ -277,7 +278,7 @@ if (empty($reshook) && $action == 'add' && (!empty($conference->id) && $conferen $securekeyurl = dol_hash($conf->global->EVENTORGANIZATION_SECUREKEY.'conferenceorbooth'.$id, 'master'); $redirection = $dolibarr_main_url_root.'/public/eventorganization/subscriptionok.php?id='.((int) $id).'&securekey='.urlencode($securekeyurl); - $mesg = $langs->trans("RegistrationAndPaymentWereAlreadyRecorder", $email); + $mesg = $langs->trans("RegistrationAndPaymentWereAlreadyRecorded", $email); setEventMessages($mesg, null, 'mesgs'); $db->commit(); diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 43ee8889131..c03aeb4b526 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -1267,7 +1267,7 @@ if ($ispaymentok) { $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")); + $outputlangs->loadLangs(array("main", "members", "eventorganization")); // Get email content from template $arraydefaultmessage = null; @@ -1298,7 +1298,22 @@ if ($ispaymentok) { $ishtml = dol_textishtml($texttosend); // May contain urls - $mailfile = new CMailFile($subjecttosend, $sendto, $from, $texttosend, array(), array(), array(), '', '', 0, $ishtml); + // Attach a file ? + $file = ''; + $listofpaths = array(); + $listofnames = array(); + $listofmimes = array(); + if (is_object($object)) { + $invoicediroutput = $conf->facture->dir_output; + $fileparams = dol_most_recent_file($invoicediroutput.'/'.$object->ref, preg_quote($object->ref, '/').'[^\-]+'); + $file = $fileparams['fullname']; + + $listofpaths = array($file); + $listofnames = array(basename($file)); + $listofmimes = array(dol_mimetype($file)); + } + + $mailfile = new CMailFile($subjecttosend, $sendto, $from, $texttosend, $listofpaths, $listofmimes, $listofnames, '', '', 0, $ishtml); $result = $mailfile->sendfile(); if ($result) { @@ -1456,7 +1471,7 @@ if ($ispaymentok) { $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")); + $outputlangs->loadLangs(array("main", "members", "eventorganization")); // Get email content from template $arraydefaultmessage = null; diff --git a/htdocs/public/ticket/index.php b/htdocs/public/ticket/index.php index 227dcf3867b..f7abe746832 100644 --- a/htdocs/public/ticket/index.php +++ b/htdocs/public/ticket/index.php @@ -28,11 +28,11 @@ if (!defined('NOCSRFCHECK')) { if (!defined('NOREQUIREMENU')) { define('NOREQUIREMENU', '1'); } -if (!defined("NOLOGIN")) { - define("NOLOGIN", '1'); // If this page is public (can be called outside logged session) +if (!defined('NOLOGIN')) { + define('NOLOGIN', '1'); // If this page is public (can be called outside logged session) } if (!defined('NOIPCHECK')) { - define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip + define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip } if (!defined('NOBROWSERNOTIF')) { define('NOBROWSERNOTIF', '1'); diff --git a/htdocs/recruitment/admin/candidature_extrafields.php b/htdocs/recruitment/admin/candidature_extrafields.php index efb68e5ff2c..1977c4b11fe 100644 --- a/htdocs/recruitment/admin/candidature_extrafields.php +++ b/htdocs/recruitment/admin/candidature_extrafields.php @@ -59,7 +59,9 @@ require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; * View */ +$textobject = $langs->transnoentitiesnoconv("Candidature"); +$help_url = ''; llxHeader('', $langs->trans("RecruitmentSetup"), $help_url); diff --git a/htdocs/recruitment/admin/jobposition_extrafields.php b/htdocs/recruitment/admin/jobposition_extrafields.php index d1b0651da64..641b8b96cd0 100644 --- a/htdocs/recruitment/admin/jobposition_extrafields.php +++ b/htdocs/recruitment/admin/jobposition_extrafields.php @@ -59,7 +59,9 @@ require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; * View */ +$textobject = $langs->transnoentitiesnoconv("JobPosition"); +$help_url = ''; llxHeader('', $langs->trans("RecruitmentSetup"), $help_url); diff --git a/htdocs/recruitment/admin/public_interface.php b/htdocs/recruitment/admin/public_interface.php index b091cdea7a0..b951f440005 100644 --- a/htdocs/recruitment/admin/public_interface.php +++ b/htdocs/recruitment/admin/public_interface.php @@ -96,6 +96,7 @@ print dol_get_fiche_head($head, 'publicurl', '', -1, ''); print ''.$langs->trans("PublicInterfaceRecruitmentDesc").'

    '; +$param = ''; $enabledisablehtml = $langs->trans("EnablePublicRecruitmentPages").' '; if (empty($conf->global->RECRUITMENT_ENABLE_PUBLIC_INTERFACE)) { diff --git a/htdocs/recruitment/admin/setup.php b/htdocs/recruitment/admin/setup.php index 30434b207fc..1ef8fa544ad 100644 --- a/htdocs/recruitment/admin/setup.php +++ b/htdocs/recruitment/admin/setup.php @@ -330,7 +330,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print '
    '; - $texte .= ''; + $texte .= ''; $texte .= ''; @@ -132,7 +132,7 @@ class mod_recruitmentjobposition_advanced extends ModeleNumRefRecruitmentJobPosi require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; // We get cursor rule - $mask = $conf->global->RECRUITMENT_RECRUITMENTJOBPOSITION_ADVANCED_MASK; + $mask = getDolGlobalString('RECRUITMENT_RECRUITMENTJOBPOSITION_ADVANCED_MASK'); if (!$mask) { $this->error = 'NotConfigured'; diff --git a/htdocs/salaries/card.php b/htdocs/salaries/card.php index 3deab1e2ed8..3f077255a1c 100644 --- a/htdocs/salaries/card.php +++ b/htdocs/salaries/card.php @@ -554,7 +554,7 @@ if ($action == 'create') { print ''; print ''; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 25d2831f853..1d32063c27b 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -209,6 +209,7 @@ class Societe extends CommonObject //'remise_supplier' =>array('type'=>'double', 'label'=>'SupplierDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>290, 'isameasure'=>1), 'mode_reglement' =>array('type'=>'tinyint(4)', 'label'=>'Mode reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>295), 'cond_reglement' =>array('type'=>'tinyint(4)', 'label'=>'Cond reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>300), + 'deposit_percent' =>array('type'=>'varchar(63)', 'label'=>'DepositPercent', 'enabled'=>1, 'visible'=>-1, 'position'=>301), 'mode_reglement_supplier' =>array('type'=>'integer', 'label'=>'Mode reglement supplier', 'enabled'=>1, 'visible'=>-1, 'position'=>305), 'cond_reglement_supplier' =>array('type'=>'integer', 'label'=>'Cond reglement supplier', 'enabled'=>1, 'visible'=>-1, 'position'=>308), 'outstanding_limit' =>array('type'=>'double(24,8)', 'label'=>'OutstandingBill', 'enabled'=>1, 'visible'=>-1, 'position'=>310, 'isameasure'=>1), @@ -482,6 +483,9 @@ class Societe extends CommonObject public $remise_percent; public $remise_supplier_percent; + public $mode_reglement_id; + public $cond_reglement_id; + public $deposit_percent; public $mode_reglement_supplier_id; public $cond_reglement_supplier_id; public $transport_mode_supplier_id; @@ -1462,6 +1466,7 @@ class Societe extends CommonObject $sql .= ",mode_reglement = ".(!empty($this->mode_reglement_id) ? "'".$this->db->escape($this->mode_reglement_id)."'" : "null"); $sql .= ",cond_reglement = ".(!empty($this->cond_reglement_id) ? "'".$this->db->escape($this->cond_reglement_id)."'" : "null"); + $sql .= ",deposit_percent = ".(!empty($this->deposit_percent) ? "'".$this->db->escape($this->deposit_percent)."'" : "null"); $sql .= ",transport_mode = ".(!empty($this->transport_mode_id) ? "'".$this->db->escape($this->transport_mode_id)."'" : "null"); $sql .= ",mode_reglement_supplier = ".(!empty($this->mode_reglement_supplier_id) ? "'".$this->db->escape($this->mode_reglement_supplier_id)."'" : "null"); $sql .= ",cond_reglement_supplier = ".(!empty($this->cond_reglement_supplier_id) ? "'".$this->db->escape($this->cond_reglement_supplier_id)."'" : "null"); @@ -1691,7 +1696,7 @@ class Societe extends CommonObject $sql .= ', spe.accountancy_code_customer as code_compta, spe.accountancy_code_supplier as code_compta_fournisseur, spe.accountancy_code_buy, spe.accountancy_code_sell'; } $sql .= ', s.code_client, s.code_fournisseur, s.parent, s.barcode'; - $sql .= ', s.fk_departement as state_id, s.fk_pays as country_id, s.fk_stcomm, s.mode_reglement, s.cond_reglement, s.transport_mode'; + $sql .= ', s.fk_departement as state_id, s.fk_pays as country_id, s.fk_stcomm, s.mode_reglement, s.cond_reglement, s.deposit_percent, s.transport_mode'; $sql .= ', s.fk_account, s.tva_assuj'; $sql .= ', s.mode_reglement_supplier, s.cond_reglement_supplier, s.transport_mode_supplier'; $sql .= ', s.localtax1_assuj, s.localtax1_value, s.localtax2_assuj, s.localtax2_value, s.fk_prospectlevel, s.default_lang, s.logo, s.logo_squarred'; @@ -1869,6 +1874,7 @@ class Societe extends CommonObject $this->mode_reglement_id = $obj->mode_reglement; $this->cond_reglement_id = $obj->cond_reglement; + $this->deposit_percent = $obj->deposit_percent; $this->transport_mode_id = $obj->transport_mode; $this->mode_reglement_supplier_id = $obj->mode_reglement_supplier; $this->cond_reglement_supplier_id = $obj->cond_reglement_supplier; diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 5884679950f..746b4dc0db0 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -365,7 +365,7 @@ if (empty($reshook)) { $search_level = ''; $search_parent_name = ''; $search_import_key = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } diff --git a/htdocs/societe/website.php b/htdocs/societe/website.php index 974b3d9b891..2d346282c4c 100644 --- a/htdocs/societe/website.php +++ b/htdocs/societe/website.php @@ -144,7 +144,7 @@ if (empty($reshook)) { foreach ($objectwebsiteaccount->fields as $key => $val) { $search[$key] = ''; } - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index 244386a8180..9df54d1d64b 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -232,7 +232,12 @@ function PrintCategories(first) { continue; } $("#catdivdesc"+i).show(); - $("#catdesc"+i).html(categories[parseInt(i)+parseInt(first)]['label']); + + $("#catdesc"+i).html(categories[parseInt(i)+parseInt(first)]['label'].bold() + ' - ' + categories[parseInt(i)+parseInt(first)]['description']); + + $("#catdesc"+i).text(categories[parseInt(i)+parseInt(first)]['label']); + $("#catimg"+i).attr("src","genimg/index.php?query=cat&id="+categories[parseInt(i)+parseInt(first)]['rowid']); $("#catdiv"+i).data("rowid",categories[parseInt(i)+parseInt(first)]['rowid']); $("#catdiv"+i).attr('class', 'wrapper'); @@ -266,7 +271,12 @@ function MoreCategories(moreorless) { continue; } $("#catdivdesc"+i).show(); - $("#catdesc"+i).html(categories[i+( * pagecategories)]['label']); + + $("#catdesc"+i).html(categories[i+( * pagecategories)]['label'].bold() + ' - ' + categories[i+( * pagecategories)]['description']); + + $("#catdesc"+i).text(categories[i+( * pagecategories)]['label']); + $("#catimg"+i).attr("src","genimg/index.php?query=cat&id="+categories[i+( * pagecategories)]['rowid']); $("#catdiv"+i).data("rowid",categories[i+( * pagecategories)]['rowid']); $("#catwatermark"+i).show(); @@ -295,8 +305,13 @@ function LoadProducts(position, issubcat) { jQuery.each(subcategories, function(i, val) { if (currentcat==val.fk_parent) { $("#prodivdesc"+ishow).show(); - $("#prodesc"+ishow).html(val.label); - $("#probutton"+ishow).html(val.label); + + $("#prodesc"+ishow).html(val.label.bold() + ' - ' + val.description); + $("#probutton"+ishow).html(val.label); + + $("#prodesc"+ishow).text(val.label); + $("#probutton"+ishow).text(val.label); + $("#probutton"+ishow).show(); $("#proprice"+ishow).attr("class", "hidden"); $("#proprice"+ishow).html(""); diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 3a55d82b8ad..3c0fb834f67 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -1292,6 +1292,13 @@ if (getDolGlobalString('TAKEPOS_BAR_RESTAURANT')) { print $langs->trans("Products"); } print ''; + +// complete header by hook +$parameters=array(); +$reshook=$hookmanager->executeHooks('completeTakePosInvoiceHeader', $parameters, $invoice, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +print $hookmanager->resPrint; + if (empty($_SESSION["basiclayout"]) || $_SESSION["basiclayout"] != 1) { print ''; print ''; @@ -1445,6 +1452,13 @@ if ($placeid > 0) { } } $htmlsupplements[$line->fk_parent_line] .= ''; + + // complete line by hook + $parameters=array('line' => $line); + $reshook=$hookmanager->executeHooks('completeTakePosInvoiceParentLine', $parameters, $invoice, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + $htmlsupplements[$line->fk_parent_line] .= $hookmanager->resPrint; + if (empty($_SESSION["basiclayout"]) || $_SESSION["basiclayout"] != 1) { $htmlsupplements[$line->fk_parent_line] .= ''; $htmlsupplements[$line->fk_parent_line] .= ''; @@ -1525,6 +1539,13 @@ if ($placeid > 0) { $htmlforlines .= '
    '.get_date_range($line->date_start, $line->date_end).'
    '; } $htmlforlines .= ''; + + // complete line by hook + $parameters=array('line' => $line); + $reshook=$hookmanager->executeHooks('completeTakePosInvoiceLine', $parameters, $invoice, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + $htmlforlines .= $hookmanager->resPrint; + $htmlforlines .= '
    '; $htmlforlines .= ''; print ''; - if (is_array($permsgroupbyentity[$entity])) { + if (!empty($permsgroupbyentity[$entity]) && is_array($permsgroupbyentity[$entity])) { if (in_array($obj->id, $permsgroupbyentity[$entity])) { // Own permission by group if ($caneditperms) {
    '.$langs->trans("PriceBase").''.$langs->trans("DefaultTaxRate").''.$langs->trans("HT").''.$langs->trans("TTC").'' . $langs->trans("INCVATONLY") . ''.$langs->trans("INCT").''.$langs->trans("TTC").''.$langs->trans("MinPrice").' '.$langs->trans("HT").''.$langs->trans("MinPrice").' '.$langs->trans("TTC").''.$langs->trans("ChangedBy").''.price($object->price)."'.price($object->price_ttc)."' . price($object->price_ttc) . "'.price($resultarray[2]).''.price($object->price_ttc)."'.price($object->price_min).''.price($object->price_min_ttc).''; @@ -2315,11 +2381,10 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print "'.price($line->price)."'.price($line->price_ttc)."' . price($line->price_ttc) . "'.price($resultarray[2]).''.price($line->price_ttc)."'.price($line->price_min).''; $constforvar = 'RECRUITMENT_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $file) { + if (getDolGlobalString($constforvar) == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { print ''; @@ -473,7 +473,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Default print ''; $constforvar = 'RECRUITMENT_'.strtoupper($myTmpObjectKey).'_ADDON_PDF'; - if ($conf->global->$constforvar == $name) { + if (getDolGlobalString($constforvar) == $name) { //print img_picto($langs->trans("Default"), 'on'); // Even if choice is the default value, we allow to disable it. Replace this with previous line if you need to disable unset print 'scandir).'&label='.urlencode($module->name).'&type='.urlencode($type).'" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').''; diff --git a/htdocs/recruitment/admin/setup_candidatures.php b/htdocs/recruitment/admin/setup_candidatures.php index 726e24e89b1..58172c2e767 100644 --- a/htdocs/recruitment/admin/setup_candidatures.php +++ b/htdocs/recruitment/admin/setup_candidatures.php @@ -328,7 +328,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print ''; $constforvar = 'RECRUITMENT_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $file) { + if (getDolGlobalString($constforvar) == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { print ''; @@ -471,7 +471,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Default print ''; $constforvar = 'RECRUITMENT_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $name) { + if (getDolGlobalString($constforvar) == $name) { //print img_picto($langs->trans("Default"), 'on'); // Even if choice is the default value, we allow to disable it. Replace this with previous line if you need to disable unset print 'scandir).'&label='.urlencode($module->name).'&type='.urlencode($type).'" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').''; diff --git a/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php b/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php index e2b7c545aa9..c28bd4a9589 100644 --- a/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php +++ b/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php @@ -130,7 +130,7 @@ class doc_generic_recruitmentjobposition_odt extends ModelePDFRecruitmentJobPosi // List of directories area $texte .= '
    '; $texttitle = $langs->trans("ListOfDirectories"); - $listofdir = explode(',', preg_replace('/[\r\n]+/', ',', trim($conf->global->RECRUITMENT_RECRUITMENTJOBPOSITION_ADDON_PDF_ODT_PATH))); + $listofdir = explode(',', preg_replace('/[\r\n]+/', ',', trim(getDolGlobalString('RECRUITMENT_RECRUITMENTJOBPOSITION_ADDON_PDF_ODT_PATH')))); $listoffiles = array(); foreach ($listofdir as $key => $tmpdir) { $tmpdir = trim($tmpdir); @@ -155,7 +155,7 @@ class doc_generic_recruitmentjobposition_odt extends ModelePDFRecruitmentJobPosi $texte .= $form->textwithpicto($texttitle, $texthelp, 1, 'help', '', 1); $texte .= '
    '; $texte .= ''; $texte .= '
    '; $texte .= ''; diff --git a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php index cc215a855ff..ba1d0a8d9f5 100644 --- a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php +++ b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php @@ -849,8 +849,8 @@ class pdf_standard_recruitmentjobposition extends ModelePDFRecruitmentJobPositio pdf_pagehead($pdf, $outputlangs, $this->page_hauteur); // Show Draft Watermark - if ($object->statut == $object::STATUS_DRAFT && (!empty($conf->global->FACTURE_DRAFT_WATERMARK))) { - pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->FACTURE_DRAFT_WATERMARK); + if ($object->statut == $object::STATUS_DRAFT && (!empty($conf->global->RECRUITMENT_RECRUITMENTJOBPOSITION_DRAFT_WATERMARK))) { + pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->RECRUITMENT_RECRUITMENTJOBPOSITION_DRAFT_WATERMARK); } $pdf->SetTextColor(0, 0, 60); diff --git a/htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php b/htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php index fcc476abacf..e4a07c63633 100644 --- a/htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php +++ b/htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php @@ -79,7 +79,7 @@ class mod_recruitmentjobposition_advanced extends ModeleNumRefRecruitmentJobPosi // Parametrage du prefix $texte .= '
    '.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 1).' 
    '; print $form->editfieldkey('Amount', 'amount', '', $object, 0, 'string', '', 1).''; print ' '; - print '
    '.$langs->trans('ReductionShort').''.$langs->trans('Qty').''.vatrate($line->remise_percent, true).''.$line->qty.''.vatrate($line->remise_percent, true).''; if (!empty($conf->stock->enabled) && !empty($user->rights->stock->mouvement->lire)) { diff --git a/htdocs/theme/eldy/btn.inc.php b/htdocs/theme/eldy/btn.inc.php index 45ed3889a13..b29c55bd02d 100644 --- a/htdocs/theme/eldy/btn.inc.php +++ b/htdocs/theme/eldy/btn.inc.php @@ -147,9 +147,9 @@ span.butActionNewRefused>span.fa, span.butActionNewRefused>span.fa:hover } .butActionDelete, .butActionDelete:link, .butActionDelete:visited, .butActionDelete:hover, .butActionDelete:active, .buttonDelete { - background: var(--butactiondeletebg); + background: var(--butactiondeletebg) !important; /* border: 1px solid #633; */ - color: #633; + color: #633 !important; } .butActionDelete:hover { diff --git a/htdocs/theme/eldy/dropdown.inc.php b/htdocs/theme/eldy/dropdown.inc.php index 6ca9ad67b1f..338b4cf2759 100644 --- a/htdocs/theme/eldy/dropdown.inc.php +++ b/htdocs/theme/eldy/dropdown.inc.php @@ -121,8 +121,17 @@ button.dropdown-item.global-search-item { text-decoration: none !important; } + +/* CSS to hide the arrow to show open/close */ +div#topmenu-quickadd-dropdown, div#topmenu-bookmark-dropdown { + padding-right: 5px; +} +div#topmenu-quickadd-dropdown a::after, div#topmenu-bookmark-dropdown a::after { + display: none; +} + + .dropdown-toggle::after { - /* font part */ font-family: "Font Awesome 5 Free"; font-size: 0.7em; font-weight: 900; @@ -141,6 +150,7 @@ button.dropdown-item.global-search-item { transition: transform .2s ease-in-out; } + .open>.dropdown-toggle::after { transform: rotate(180deg); } diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index ff6fe3c4fb8..db827600b33 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -240,7 +240,7 @@ input, select { } #mainbody input.button:not(.buttongen):not(.bordertransp), #mainbody a.button:not(.buttongen):not(.bordertransp) { background: var(--butactionbg); - color: var(--textbutaction)!important; + color: var(--textbutaction); border-radius: 3px; border-collapse: collapse; border: none; @@ -2605,27 +2605,45 @@ a.tmenuimage:hover{ /* To show text of top menu on hover only (THEME_TOPMENU_DISABLE_IMAGE == 2) */ -.tmenulabel:not(.menuhider), .tmenulabel:not(.menuhider):before { - display: none; +.tmenulabel:not(.menuhider), .tmenulabel:not(.menuhider)::before { + display: none; + /* opacity: 0; To show text after transition */ } -a.tmenuimage:not(.menuhider), a.tmenuimage:not(.menuhider):before, -div.tmenuimage:not(.menuhider), div.tmenuimage:not(.menuhider):before, -span.tmenuimage:not(.menuhider), span.tmenuimage:not(.menuhider):before { +a.tmenuimage:not(.menuhider), a.tmenuimage:not(.menuhider)::before, +div.tmenuimage:not(.menuhider), div.tmenuimage:not(.menuhider)::before, +span.tmenuimage:not(.menuhider), span.tmenuimage:not(.menuhider)::before { font-size: 1.3em; - margin-top: 10px !important; + margin-top: 8px !important; } + -.tmenudiv:hover .tmenulabel:not(.menuhider), .tmenudiv:hover .tmenulabel:not(.menuhider):before { +.tmenudiv:hover .tmenulabel:not(.menuhider), .tmenudiv:hover .tmenulabel:not(.menuhider)::before { + display: block; + position: relative; + overflow: hidden; + text-overflow: ellipsis; + /* For transition transition-delay: 1000ms; + transition-property: all; */ + opacity: 1; display: initial !important; + line-height: 0.6em !important; + height: 1em !important; + overflow: hidden; + text-overflow: ellipsis; + color: var(--colortextbackhmenu); + top: 0px; } -.tmenudiv:hover .tmenuimage:not(.menuhider), .tmenudiv:hover .tmenuimage:not(.menuhider):before { - font-size: 1.1em !important; + +.tmenudiv:hover .tmenuimage:not(.menuhider), .tmenudiv:hover .tmenuimage:not(.menuhider)::before { + /* For transition transition-delay: 1000ms; + transition-property: all; */ margin-top: 0px !important; } + -li.tmenu:hover .tmenulabel:not(.menuhider), li.tmenu:hover .tmenulabel:not(.menuhider):before { +li.tmenu:hover .tmenulabel:not(.menuhider), li.tmenu:hover .tmenulabel:not(.menuhider)::before { display: initial !important; } li.tmenu:hover .tmenuimage:not(.menuhider), li.tmenu:hover .tmenuimage:not(.menuhider):before { @@ -2694,12 +2712,14 @@ li.tmenu:hover .tmenuimage:not(.menuhider), li.tmenu:hover .tmenuimage:not(.menu $url = dol_buildpath($path.'/theme/'.$theme.'/img/menus/generic'.(min($generic, 4))."_over.png", 1); print "div.mainmenu.".$val." {\n"; print " background-image: url(".$url.");\n"; + print " background-position-y: 3px;\n"; print "}\n"; } $generic++; } else { print "div.mainmenu.".$val." {\n"; print " background-image: url(".$url.");\n"; + print " background-position-y: 3px;\n"; print "}\n"; } } @@ -3811,12 +3831,6 @@ div.pagination { div.pagination a { font-weight: normal; } -/*div.pagination a.butAction, div.fichehalfright a.butAction { - margin-right: 0px !important; -} -div.tabsAction a.butActionDelete:last-child, div.tabsAction a.butAction:last-child { - margin-right: 0px !important; -}*/ div.pagination ul { list-style: none; @@ -7327,11 +7341,18 @@ div.clipboardCPValue.hidewithsize { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; + color: var(--colortextbackhmenu); + /* color: var(--colorbackhmenu1); */ } + .tmenuimage { + color: var(--colortextbackhmenu); + } + .mainmenuaspan { font-size: 0.9em; padding-right: 0; + padding-left: 0; } .topmenuimage { background-size: 22px auto; @@ -7386,6 +7407,15 @@ div.clipboardCPValue.hidewithsize { /* rule to reduce top menu - 3rd reduction: The menu for user is on left */ @media only screen and (max-width: global->THEME_ELDY_WITDHOFFSET_FOR_REDUC3) ? round($nbtopmenuentries * 47, 0) + 130 : $conf->global->THEME_ELDY_WITDHOFFSET_FOR_REDUC3; ?>px) /* reduction 3 */ { + + .tmenudiv .tmenulabel span.mainmenuaspan { + display: none !important; + } + .tmenudiv:hover .tmenuimage:not(.menuhider), .tmenudiv:hover .tmenuimage:not(.menuhider):before { + margin-top: 8px !important; + } + + .side-nav { z-index: 200; background: var(--colorbackvmenu1); diff --git a/htdocs/theme/eldy/main_menu_fa_icons.inc.php b/htdocs/theme/eldy/main_menu_fa_icons.inc.php index 60c3746fe66..ada1ae23a12 100644 --- a/htdocs/theme/eldy/main_menu_fa_icons.inc.php +++ b/htdocs/theme/eldy/main_menu_fa_icons.inc.php @@ -10,12 +10,12 @@ font-style: normal; font-variant: normal; text-rendering: auto; - line-height: 23px; - font-size: ; + line-height: 28px; -webkit-font-smoothing: antialiased; text-align:center; text-decoration:none; color: var(--colortextbackhmenu); + /* font-size: ; */ } .fa-15x { diff --git a/htdocs/theme/md/dropdown.inc.php b/htdocs/theme/md/dropdown.inc.php index c56590d7bfa..615951bbbd9 100644 --- a/htdocs/theme/md/dropdown.inc.php +++ b/htdocs/theme/md/dropdown.inc.php @@ -26,7 +26,7 @@ button.dropdown-item.global-search-item { } div#topmenu-quickadd-dropdown { position: fixed; - : 65px; + : 55px; top: 0px; } div#topmenu-bookmark-dropdown { @@ -124,6 +124,15 @@ button.dropdown-item.global-search-item { } +/* CSS to hide the arrow to show open/close */ +div#topmenu-quickadd-dropdown, div#topmenu-bookmark-dropdown { + padding-right: 2px; +} +div#topmenu-quickadd-dropdown a::after, div#topmenu-bookmark-dropdown a::after { + display: none; +} + + .dropdown-toggle{ text-decoration: none !important; } diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 9e50dd2c47d..33ca6d0ec9c 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -297,7 +297,7 @@ class User extends CommonObject public $all_permissions_are_loaded; /** - * @var int Number of rights granted to the user + * @var int Number of rights granted to the user. Value loaded after a getrights(). */ public $nb_rights; @@ -883,15 +883,18 @@ class User extends CommonObject $i = 0; while ($i < $num) { $obj = $this->db->fetch_object($result); - $nid = $obj->id; - $sql = "DELETE FROM ".$this->db->prefix()."user_rights WHERE fk_user = ".((int) $this->id)." AND fk_id = ".((int) $nid)." AND entity = ".((int) $entity); - if (!$this->db->query($sql)) { - $error++; - } - $sql = "INSERT INTO ".$this->db->prefix()."user_rights (entity, fk_user, fk_id) VALUES (".((int) $entity).", ".((int) $this->id).", ".((int) $nid).")"; - if (!$this->db->query($sql)) { - $error++; + if ($obj) { + $nid = $obj->id; + + $sql = "DELETE FROM ".$this->db->prefix()."user_rights WHERE fk_user = ".((int) $this->id)." AND fk_id = ".((int) $nid)." AND entity = ".((int) $entity); + if (!$this->db->query($sql)) { + $error++; + } + $sql = "INSERT INTO ".$this->db->prefix()."user_rights (entity, fk_user, fk_id) VALUES (".((int) $entity).", ".((int) $this->id).", ".((int) $nid).")"; + if (!$this->db->query($sql)) { + $error++; + } } $i++; @@ -1096,6 +1099,14 @@ class User extends CommonObject } } + // For avoid error + if (!isset($this->rights) || !is_object($this->rights)) { + $this->rights = new stdClass(); // For avoid error + } + if (!isset($this->rights->user) || !is_object($this->rights->user)) { + $this->rights->user = new stdClass(); // For avoid error + } + // Get permission of users + Get permissions of groups // First user permissions @@ -1121,7 +1132,6 @@ class User extends CommonObject if ($resql) { $num = $this->db->num_rows($resql); $i = 0; - while ($i < $num) { $obj = $this->db->fetch_object($resql); @@ -1131,9 +1141,6 @@ class User extends CommonObject $subperms = $obj->subperms; if (!empty($perms)) { - if (!isset($this->rights) || !is_object($this->rights)) { - $this->rights = new stdClass(); // For avoid error - } if (!empty($module)) { if (!isset($this->rights->$module) || !is_object($this->rights->$module)) { $this->rights->$module = new stdClass(); @@ -1200,9 +1207,6 @@ class User extends CommonObject $subperms = $obj->subperms; if (!empty($perms)) { - if (!isset($this->rights) || !is_object($this->rights)) { - $this->rights = new stdClass(); // For avoid error - } if (!empty($module)) { if (!isset($this->rights->$module) || !is_object($this->rights->$module)) { $this->rights->$module = new stdClass(); @@ -1232,6 +1236,63 @@ class User extends CommonObject $this->db->free($resql); } + // Force permission on user for admin + if (!empty($this->admin)) { + if (empty($this->rights->user->user)) { + $this->rights->user->user = new stdClass(); + } + $listofpermtotest = array('lire', 'creer', 'password', 'supprimer', 'export'); + foreach ($listofpermtotest as $permtotest) { + if (empty($this->rights->user->user->$permtotest)) { + $this->rights->user->user->$permtotest = 1; + $this->nb_rights++; + } + } + if (empty($this->rights->user->self)) { + $this->rights->user->self = new stdClass(); + } + $listofpermtotest = array('creer', 'password'); + foreach ($listofpermtotest as $permtotest) { + if (empty($this->rights->user->self->$permtotest)) { + $this->rights->user->self->$permtotest = 1; + $this->nb_rights++; + } + } + // Add test on advanced permissions + if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { + if (empty($this->rights->user->user_advance)) { + $this->rights->user->user_advance = new stdClass(); + } + $listofpermtotest = array('readperms', 'write'); + foreach ($listofpermtotest as $permtotest) { + if (empty($this->rights->user->user_advance->$permtotest)) { + $this->rights->user->user_advance->$permtotest = 1; + $this->nb_rights++; + } + } + if (empty($this->rights->user->self_advance)) { + $this->rights->user->self_advance = new stdClass(); + } + $listofpermtotest = array('readperms', 'writeperms'); + foreach ($listofpermtotest as $permtotest) { + if (empty($this->rights->user->self_advance->$permtotest)) { + $this->rights->user->self_advance->$permtotest = 1; + $this->nb_rights++; + } + } + if (empty($this->rights->user->group_advance)) { + $this->rights->user->group_advance = new stdClass(); + } + $listofpermtotest = array('read', 'readperms', 'write', 'delete'); + foreach ($listofpermtotest as $permtotest) { + if (empty($this->rights->user) || empty($this->rights->user->group_advance->$permtotest)) { + $this->rights->user->group_advance->$permtotest = 1; + $this->nb_rights++; + } + } + } + } + // For backward compatibility if (isset($this->rights->propale) && !isset($this->rights->propal)) { $this->rights->propal = $this->rights->propale; diff --git a/htdocs/user/group/card.php b/htdocs/user/group/card.php index f698d1b5a07..b185ea4ce42 100644 --- a/htdocs/user/group/card.php +++ b/htdocs/user/group/card.php @@ -454,7 +454,7 @@ if ($action == 'create') { print ''.$useringroup->getLibStatut(5).''; if (!empty($user->admin)) { - print ''; + print ''; print img_picto($langs->trans("RemoveFromGroup"), 'unlink'); print ''; } else { @@ -483,7 +483,7 @@ if ($action == 'create') { $genallowed = $user->rights->user->user->creer; $delallowed = $user->rights->user->user->supprimer; - $somethingshown = $formfile->showdocuments('usergroup', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); + $somethingshown = $formfile->showdocuments('usergroup', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', 0, '', $mysoc->default_lang); // Show links to link elements $linktoelem = $form->showLinkToObjectBlock($object, null, null); diff --git a/htdocs/user/group/perms.php b/htdocs/user/group/perms.php index 478e345f2e3..34e181469cc 100644 --- a/htdocs/user/group/perms.php +++ b/htdocs/user/group/perms.php @@ -328,7 +328,7 @@ if ($object->id > 0) { //print img_object('', $picto, 'class="inline-block pictoobjectwidth"').' '.$objMod->getName(); print '