diff --git a/ChangeLog b/ChangeLog
index 0fe697ccb6c..06c6898993d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -24,216 +24,194 @@ For users:
---------------
NEW: Minimal PHP version is now PHP 7.0 instead of PHP 5.6
-NEW: #19680 Add option PRODUCT_ALLOW_EXTERNAL_DOWNLOAD to automatically have uploaded files shared publicly by a link
+NEW: #21780 Add pid field to Cronjob class and store PID on job execution
NEW: #20650 can move the checkbox column on left (experimental option MAIN_CHECKBOX_LEFT_COLUMN)
NEW: #21000 Added columns 'alias_name' on project, supplier invoice, supplier order, supplier proposals and task list
-NEW: #21780 Add pid field to Cronjob class and store PID on job execution
NEW: #21395 Added option for dark theme mode in display - color and theme
NEW: #21397 added option to auto define barcode numbers for third-parties in barcode module setup
-NEW: #21399 add image for event_array
+NEW: #21399
NEW: #21442 Enhancement of module builder init
NEW: #21654 add bank account number used on invoices for debit
-NEW: #22048 added notes to productlot module
+NEW: #22048 Added notes to productlot module
NEW: #22298 Bank - Add salaries & vat in the tab of planned entries of a bank account
-NEW: #22328 OAuth admin
-NEW: #22424 online signature for contracts
+NEW: #22328
+NEW: #22424
NEW: #22500 member module set up made easier
NEW: #22527 projects and thirdparties can be viewed as conversation ("Message" view), like events/agenda.
NEW: #22546 can now set user supervisors using mass action in htdocs/user
NEW: #22594 can chose if VAT ID is unique or not for third parties
NEW: #22622 all partnerships displayed on tab partnership of a thirdparty and member
NEW: #22676 massaction for updating product prices
-NEW: #22735 massaction to affect users on projects
-NEW: #25594 can chose if VAT ID is unique or not for third parties
+NEW: #22735 Massaction to assign users on projects
NEW: #4482 adding js to hide/show advanced option on the export data page
-
+NEW: Accountancy - Add a graphic option to enable lettering function - FPC21
+NEW: Accountancy - Add a way to clean some words when you generate thirdparty accounting account
+NEW: Accountancy - Added an option during export to export or not the lettering FPC21
+NEW: Accountancy - Manage supplier deposit with specific account
+NEW: Accountancy - Model Digitaria - Add a way to clean some words when you generate thirdparty accounting account FPC22
+NEW: Add a button "Test collect" in email collector
NEW: Add a constant to disallow modification of the product reference.
+NEW: Add a method doAutoRenewContracts that can be used as a cron task.
+NEW: Add " as enclosure by default for CSV export. Keep removing CR/LF.
NEW: add attached file in presend email form of thirdparty card
NEW: Add a way to enter LICENSE file content in property of website
+NEW: Add badge in admin extrafields setup
+NEW: add constant PROPAL_BYPASS_VALIDATED_STATUS
+NEW: Add date event (!= date project) and location on event organization
NEW: Add employment anniversary in birthday box
+NEW: Add extrafield type "IP" to store IP addresses
+NEW: Add fail2ban rules examples to limit access to /public pages
+NEW: Add filter "Product subject to lot/Serial" in stock per lot/serial
NEW: Add hidden option MAIN_EMAIL_SUPPORT_ACK to restore Email ack checkbox (feature abandonned by mailers)
+NEW: Add IMAP port setting on email collector module
+NEW: Adding JAPAN Chart-of-Account and regions/departments
+NEW: Adding NIF verification for Algeria
NEW: Add link to create an element from the category page
+NEW: add margin infos to takepos invoice lines
NEW: Add max size send for "backup and link to mail" option
NEW: Add method httponly_accessforbidden()
NEW: Add more advices into the Setup security page
-NEW: Add new global variable for keeping the previous signature information on proposale (case of reopen a proposale)
+NEW: Add new global variable for keeping the previous signature information on proposal (case of reopening a proposal)
+NEW: Add objectLink on shipment
NEW: Add option --force on CLI cron_run_jobs.php
NEW: Add option "Show price on the generated documents for receptions"
+NEW: Add performance index (name for company and contact) and llx_bank_url(url_id)
+NEW: Add picto property on sub-module for password generation
+NEW: add redirect on action confirm addconsumedline and addproduceline
+NEW: Add a new advanced permission "read price"
+NEW: Add substitution key __SENDEREMAIL_SIGNATURE__
+NEW: Add the referrer-policy to "same-origin" by default on all public pages.
+NEW: Add the SMTP header References on ticket email created by email
+NEW: Add the thirdparty column to the time list (projet/tasks/time.php)
+NEW: Add trigger to record the event of sending an email from a project #20912
+NEW: Allow download link option in module configuration (propal,invoice,supplier proposal, order)
+NEW: Bulk action to remove a category in list/search website pages
+NEW: Can copy/paste images into emails sent.
+NEW: Can edit label of an emailing even once sent
+NEW: Can edit property css, cssview, csslist on extrafields
+NEW: Can enter the unit price including the vat when adding new product lines on invoices, orders, proposals, ...
+NEW: Can invoice task time per different services
+NEW: Can join several files by default on email form
+NEW: Can send an email on scheduled job error
+NEW: Can set a commercial discount by entering amount including VAT
+NEW: Can set a monthly frequency (or multiple) in cron tasks.
+NEW: Can set start and end dates and comment on button "Activate all services"
+NEW: Can sort on preselected best supplier price
+NEW: Can use products categories to make inventory
+NEW: Change filter type on tickets list into a multiselect combo
+NEW: conf TIMESPENT_ALWAYS_UPDATE_THM, when it's on we always check current thm of user to update it in task time line
+NEW: constant PROPAL_NEW_AS_SIGNED
+NEW: show date delivery planned on orders linked to company and product
+NEW: Default doc template of contracts is not mandatory
+NEW: Default values in extrafields are no more limited to 255 char.
+NEW: display currency in takepos menu
+NEW: Enable online signature for interventions
+NEW: extrafield price with currency
+NEW: filter on reception dates (from / to) in cheque paiement card
+NEW: Members: default_lang for members
+NEW: Members: Table of membership types
+NEW: Members: add free membership amounts at the membership type level
+NEW: TakePOS: Header Scroll in TakePOS
+NEW: TakePOS: add price to product box in TakePOS
+NEW: TakePOS: add setup parameters, can setup terminal name
+NEW: TakePOS: support of Stripe Terminal with TakePOS
+NEW: TakePOS: Receipt preview in TakePOS setup
+NEW: TakePOS: different product list on smartphone
+NEW: Website: can delete a whole website if disabled
+NEW: Website: can remove a website template
+NEW: Website: can set header "Strict-Transport-Security" in web sites.
+NEW: Website: can switch status of website and page from the website toolbar
+NEW: Website: Templates of websites are now directories and not zip into core repo
+NEW: Website: add 4 other templates in website module
+NEW: Website: Add counters for public access of pages on a website
+NEW: If we select another view list mode, we keep it
+NEW: Init module bookcal
+NEW: Encrypt all sensitive constants in llx_const using dolEncrypt/dolDecrypt
+NEW: Invoice - Add french mention on pdf when vat debit option is on
+NEW: invoice export : add accounting affectation
+NEW: label on products categories filter
+NEW: The link "add to bookmark" is always on top in the bookmark popup
+NEW: MAIN_SEARCH_CATEGORY_PRODUCT_ON_LISTS const to show category customer filter
+NEW: Make module WebservicesClient deprecated. Use module WebHook instead.
+NEW: manage no email with thirdparties (better for GDPR)
+NEW: Manage Position (Rank) on Contract Lines
NEW: Manage VAT on all lines on purchases cycle
+NEW: Page to show virtual stock at a future date
+NEW: On a bank reconciled line, we can modify the bank receipt
+NEW: On a form to send an email, we show all emails of all contacts of object
+NEW: Option PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT showing wh on PDF
+NEW: Option PRODUIT_DESC_IN_FORM accept (desktop only or +smartphone)
+NEW: Page for mass stock transfer can be used with no source stock
NEW: parent company column and filter in invoice and order list
-NEW: private and public note columns on user, thirdparty and contact lists
-NEW: Public counters feature
+NEW: Add "Show Sales rep" option for PDF
+NEW: Picto for shared link is clickable
+NEW: possibility to select scopes with checkbox for Oauth tokens
+NEW: private and public note on user, thirdparty and contact list
+NEW: product categories filter on inventory list
+NEW: Product supplier price: autofill default supplier VAT
+NEW: Project - author field become an available column on lists
+NEW: Reception - Add a from/to on search on date field
+NEW: Start a simple support of recurrent events on agenda
+NEW: Resize parent company column in order list
+NEW: Saved token of OAUTH module are now encrypted into llx_oauth_token
NEW: Save one click to select on delivery ack, on emails.
NEW: scheduled job to send unpaid invoice reminder can now use the cc and bcc from email template
+NEW: set thirdparty type with company modify trigger
+NEW: Show also scheduled task never finished in scheduled task widget
+NEW: show badge with number of extrafields in setup
+NEW: show category tree in sellist and chkbxlst for common object
+NEW: Show picto and color into combo for selection of tags
+NEW: show product label on inventory
+NEW: show sell-by and eat-by dates only if not empty
+NEW: show SellBy/EatBy dates for each batch product in shipment card
+NEW: Can skip accept/refuse steps for proposals (option PROPAL_SKIP_ACCEPT_REFUSE)
+NEW: experimental SMTP using PhpImap allowing OAuth2 authentication (need to add option MAIN_IMAP_USE_PHPIMAP)
NEW: can substitue project title in mail template
+NEW: Supplier order list - Add column private and public note
NEW: The purge of files can purge only if older than a number of seconds
NEW: Update ActionComm type_code on email message ticket
+NEW: VAT - Admin - Add information on deadline day for submission of VAT declaration
+NEW: expand/collapse permissions on user permission page
+NEW: Show delivery mode on PDF for proposals
NEW: Add the target to select attendees of event for emailings
-NEW: add redirect on action confirm addconsumedline and addproduceline
-NEW: Add the referrer-policy to "same-origin" by default on all public pages.
-NEW: Add trigger to record the event of sending an email from a project #20912
-NEW: Allow download link option in module configuration (propal, order, invoice, supplier proposal)
-NEW: Can enter the unit price including the VAT
-NEW: Can invoice task time per different services
-NEW: Can set a commercial discount by entering amount including VAT
-NEW: Can set start and end dates and comment on button "Activate all services"
-NEW: show date delivery planned on orders linked to company and product
-NEW: filter on reception dates (from / to) in cheque paiement card
-
-NEW: Accountancy - add a graphic option to enable lettering function - FPC21
-NEW: Accountancy - add a way to clean some words when you generate thirdparty accounting account
-NEW: Accountancy - added an option during export to export or not the lettering FPC21
-NEW: Accountancy - Invoice export : add accounting affectation
-NEW: Accountancy - Manage supplier deposit with specific account
-NEW: Accountancy - Model Digitaria - Add a way to clean some words when you generate thirdparty accounting account FPC22
-NEW: Agenda - start a simple support of recurrent events on agenda
-NEW: Bank - add salaries & VAT in tab planned entries
-NEW: Bank - on a bank reconciled line, we can modify the bank receipt
-NEW: Contracts - add a method doAutoRenewContracts that can be used as a cron task
-NEW: Contracts - default template of contract is not mandatory
-NEW: Contracts - Manage Position (Rank) on Contract Lines
-NEW: EMail - can copy/paste images into emails sent
-NEW: EMail - can edit label of an emailing even once sent
-NEW: EMail - can join several files by default on email form
-NEW: EMail - can send an email on scheduled job error
-NEW: EMail - on a form to send an email, we show all emails of all contacts of object
-NEW: EMail - add the SMTP header References on ticket email created by email
-NEW: EMail - add substitution key __SENDEREMAIL_SIGNATURE__
-NEW: EMail - experimental SMTP using PhpImap allowing OAuth2 authentication (need to add option MAIN_IMAP_USE_PHPIMAP)
-NEW: EMail-Collector - add IMAP port setting
-NEW: EMail-Collector - add a button "Test collect"
-NEW: Event-Organization - add date event (!= date project) and location on event organization
-NEW: Expedition - add objectLink on expedition
-NEW: Export - Add " as enclosure by default for CSV export. Keep removing CR/LF.
-NEW: Extrafields - add badge in admin extrafields setup
-NEW: Extrafields - can edit property css, cssview, csslist on extrafields
-NEW: Extrafields - default values in extrafields are not more limited to 255 char.
-NEW: Extrafields - field price with currency
-NEW: Extrafields - support IP type to store IP addresses
-NEW: Finance - VAT - Admin - Add information on deadline day for submission of VAT declaration
-NEW: Interventions - enable online signature for interventions
-NEW: Invoice - add french mention on PDF when VAT debit option is on
-NEW: Members - default_lang for members
-NEW: Members - table of membership types
-NEW: Members - add free membership amounts at the membership type level
-NEW: OAuth - possibility to select scopes with checkbox for OAuth tokens
-NEW: OAuth - saved token of OAUTH module are now encrypted into llx_oauth_token
-NEW: Orders - resize parent company column in order list
-NEW: Products - Categories - label on products categories filter
-NEW: Products - Supplier price - autofill default supplier VAT
-NEW: Products - Supplier price - can sort and preselected best supplier price
-NEW: Projects - add author on list
-NEW: Projects - add thirdparty column to the time list (projet/tasks/time.php)
-NEW: Proposals - show delivery mode on PDF for proposals
-NEW: Proposals - skip accept/refuse process for proposals (option PROPAL_SKIP_ACCEPT_REFUSE)
-NEW: Reception - add a from/to on search on date field
-NEW: Stock - page for mass stock transfer can be used with no source stock
-NEW: Stock - product categories filter on inventory list
-NEW: Stock - show product label on inventory
-NEW: Stock - manage virtual stock at a future date
-NEW: Stock Inventory - add filter "Product subject to lot/Serial" in stock per lot/serial
-NEW: Stock Inventory - can use products categories to make inventory
-NEW: Supplier Order List - add column private and public note
-NEW: TakePOS - add margin infos to TakePOS invoice lines
-NEW: TakePOS - add price to product box in TakePOS
-NEW: TakePOS - add setup parameters, can setup terminal name
-NEW: TakePOS - different product list on smartphone
-NEW: TakePOS - display currency in TakePOS menu
-NEW: TakePOS - Header Scroll in TakePOS
-NEW: TakePOS - Receipt preview in TakePOS setup
-NEW: TakePOS - support of Stripe Terminal with TakePOS
-NEW: Thirdparty - manage no email with thirdparties (better for GDPR)
-NEW: Thirdparty - set thirdparty type with company modify trigger
-NEW: Tickets - change filter type on tickets list into a multiselect combo
-NEW: Tickets - add oldcopy to Ticket so triggers intercepting TICKET_MODIFY have access to old values of the updated properties
-NEW: Website - can delete a whole website if disabled
-NEW: Website - can remove a website template
-NEW: Website - can set header "Strict-Transport-Security" in web sites.
-NEW: Website - can switch status of website and page from the website toolbar
-NEW: Website - Templates of websites are now directories and not zip into core repo
-NEW: Website - add 4 other templates in website module
-
-General:
-NEW: Actions: Bulk action to remove a category in list/search website pages
-NEW: Cronjobs: can set a monthly frequency (or multiple) in cron tasks
-NEW: Database: Encrypt all sensitive constants in llx_const
-NEW: Database: Add performance index (name for company and contact) and llx_bank_url(url_id)
-NEW: Database: Introduce dolEncrypt and dolDecrypt to be able to encrypt data in db
-NEW: GUI: If we select another view list mode, we keep it
-NEW: GUI: the link "add to bookmark" is always on top in the bookmark popup
-NEW: GUI: Picto for shared link is clickable
-NEW: GUI: add picto property on sub-module for password generation
-NEW: GUI: show also scheduled task never finished in scheduled task widget
-NEW: GUI: show badge with number of extrafields in setup
-NEW: GUI: show category tree in sellist and chkbxlst for common object
-NEW: GUI: show picto and color into combo for selection of tags
-NEW: GUI: show sell-by and eat-by dates only if not empty
-NEW: GUI: show SellBy/EatBy dates for each batch product in shipment card
-NEW: GUI/Permissions: expand/collapse permissions on user permission page
-NEW: Permissions: add a new advanced permission "read price"
-NEW: Print: add show "Sales rep" option for PDF
-NEW: Security: add fail2ban rules examples to limit access to /public pages
-
- Option / Const for System:
-NEW: FICHINTER_ALLOW_EXTERNAL_DOWNLOAD
-NEW: MAIN_CHECKBOX_LEFT_COLUMN
-NEW: MAIN_EMAIL_SUPPORT_ACK
-NEW: MAIN_IMAP_USE_PHPIMAP
-NEW: MAIN_SEARCH_CATEGORY_PRODUCT_ON_LISTS - const to show category customer filter
-NEW: PRODUCT_ALLOW_EXTERNAL_DOWNLOAD
-NEW: PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT - showing warehouse on PDF
-NEW: PRODUIT_DESC_IN_FORM accept - desktop only or +smartphone
-NEW: PROPAL_BYPASS_VALIDATED_STATUS
-NEW: PROPAL_NEW_AS_SIGNED
-NEW: PROPAL_SKIP_ACCEPT_REFUSE
-NEW: TIMESPENT_ALWAYS_UPDATE_THM - when it's on we always check current thm of user to update it in task time line
-
- Localisation:
-NEW: adding JAPAN Chart-of-Account and regions/departments
-NEW: adding NIF verification for Algeria
+NEW: Can set background style with MAIN_LOGIN_BACKGROUND_STYLE
Modules
NEW: Experimental module Asset
-NEW: Init module bookcal
-NEW: Make module WebservicesClient deprecated. Use module WebHook instead.
-
For developers or integrators:
------------------------------
-NEW: ModuleBuilder can generate code of class from an existing SQL table
+NEW: ModuleBuilder can generate code for a class from an existing SQL table
+NEW: #22370 Modulebuilder supports 'alwayseditable' (like extrafields)
NEW: #20912 Add trigger to record the event of sending an email from a project
NEW: #21750 Added "Get lines and Post lines from BOM" at the REST Service
-NEW: #22370 Modulebuilder supports 'alwayseditable' (like extrafields)
+NEW: Removed completely the need for the library adodbtime
+NEW: hook on agenda pages
+NEW: hook to complete payment in TakePOS
+NEW: hook "changeHelpURL" to modify target of the help button
+NEW: hook formConfirm on action comm card
+NEW: hook to modify supplier product html select
+NEW: Add new hook for show virtual stock details on product stock card
+NEW: Add new hooks for actioncomm
NEW: conf->global->SYSLOG_FILE_ONEPERSESSION accept a string
-NEW: All ajax pages have now a top_httphead()
-
- API:
+NEW: translation for contact type API, setup/ticket API, shipping method API
+NEW: All ajax pages have now a header build with top_httphead()
+NEW: support multilang in Civilities API
NEW: Add API for the partnership module
NEW: Add "Get lines and Post lines from BOM" in the API
-NEW: translate for contact type API, setup/ticket API, shipping method API
-NEW: support multilang in Civilities API
-
- Hooks:
-NEW: Actioncomm - add new hooks for actioncomm
-NEW: Actioncomm - hook formConfirm on actioncomm card
-NEW: Agenda - hook on agenda pages
-NEW: Help - hook "changeHelpURL" to modify target of the help button
-NEW: Product - add hook to show virtual stock details on product stock card
-NEW: Product - add hook to modify supplier product html select
-NEW: TakePOS - add hook to complete payment in TakePOS
-
-
-NEW: Removed completely the need for the library adodbtime
-NEW: Replace fk_categories_product with categories_product in inventory
-NEW: Rewrite of SQL request. Removed the join on category (for filter on categ), replaced with a EXISTS/NOT
+NEW: Replace property fk_categories_product with categories_product in inventory class
+NEW: Rewrite of SQL request. Removed the join on category table (for filter on category), replaced with a EXISTS/NOT
+NEW: Add oldcopy to Ticket so triggers intercepting TICKET_MODIFY have access to old values of the updated properties
+NEW: #19680 Add option PRODUCT_ALLOW_EXTERNAL_DOWNLOAD to automatically have uploaded files shared publicly by a link
+NEW: Add option FICHINTER_ALLOW_EXTERNAL_DOWNLOAD
WARNING:
Following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
* Minimal PHP version is now PHP 7.0 instead of PHP 5.6
-* The signature of method getNomUrl() of class ProductFournisseur has been modified to match the signature of method Product
+* The signature of method getNomUrl() of class ProductFournisseur has been modified to match the signature of method Product->getNomUrl()
* Trigger ORDER_SUPPLIER_DISPATCH is removed, use ORDER_SUPPLIER_RECEIVE and/or LINEORDER_SUPPLIER_DISPATCH instead.
* All functions fetch_all() have been set to deprecated for naming consitency, use fetchAll() instead.
* Code standardization: '$user->rights->propale' is now '$user->rights->propal' everywhere.
@@ -243,7 +221,7 @@ Following changes may create regressions for some external modules, but were nec
* Rename the substitution for "project label" instead of "project title" in substitution variables
* You must use "$objectoffield" to manipulate the current object inside the formulare of computed custom extrafields instead of $obj/$object.
* Making a global search is sending the parameter using always the name search_all (instead of sometimes sall and search_all)
-
+* The property $url_last_version must be public if defined into module descriptor files;
***** ChangeLog for 16.0.4 compared to 16.0.3 *****
diff --git a/README.md b/README.md
index 826955aef92..e4b464d77b4 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@


-[](https://php.net/)
+[](https://php.net/)
[](https://github.com/Dolibarr/dolibarr)
[](https://bestpractices.coreinfrastructure.org/projects/5521)
diff --git a/build/generate_filelist_xml.php b/build/generate_filelist_xml.php
index b122f9b0305..45d649d90d9 100755
--- a/build/generate_filelist_xml.php
+++ b/build/generate_filelist_xml.php
@@ -46,6 +46,7 @@ require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
$includecustom=0;
$includeconstants=array();
+$buildzip=0;
if (empty($argv[1])) {
print "Usage: ".$script_file." release=autostable|auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value] [buildzip=1]\n";
@@ -69,6 +70,9 @@ while ($i < $argc) {
if (!empty($result["includeconstant"])) {
$includeconstants[$i] = $result["includeconstant"];
}
+ if (!empty($result["buildzip"])) {
+ $buildzip=1;
+ }
if (preg_match('/includeconstant=/', strval($argv[$i]))) {
$tmp=explode(':', $result['includeconstant'], 3); // $includeconstant has been set with previous parse_str()
if (count($tmp) != 3) {
diff --git a/dev/setup/fail2ban/jail.local b/dev/setup/fail2ban/jail.local
index 733987aa45c..bd1f7959f08 100644
--- a/dev/setup/fail2ban/jail.local
+++ b/dev/setup/fail2ban/jail.local
@@ -31,6 +31,7 @@ maxretry = 10
[web-dol-limitpublic]
; rule to add rate limit on some public pages
+; note you must keep enough for public access like agenda export, emailing trackers, stripe ipn access, ...
enabled = true
port = http,https
filter = web-dolibarr-limitpublic
@@ -38,5 +39,5 @@ logpath = /mypath/documents/documents/dolibarr.log
action = %(action_mw)s
bantime = 86400 ; 1 day
findtime = 86400 ; 1 day
-maxretry = 500
+maxretry = 1000
diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php
index 2aed109ce26..0fbb2764ae6 100644
--- a/htdocs/accountancy/bookkeeping/list.php
+++ b/htdocs/accountancy/bookkeeping/list.php
@@ -719,7 +719,7 @@ if (count($sqlwhere) > 0) {
// Export into a file with format defined into setup (FEC, CSV, ...)
// Must be after definition of $sql
if ($action == 'export_fileconfirm' && $user->hasRight('accounting', 'mouvements', 'export')) {
- // TODO Replace the fetchAll to get all ->line followed by call to ->export(). It consumes too much memory on large export.
+ // TODO Replace the fetchAll to get all ->line followed by call to ->export(). It currently consumes too much memory on large export.
// Replace this with the query($sql) and loop on each line to export them.
$result = $object->fetchAll($sortorder, $sortfield, 0, 0, $filter, 'AND', (empty($conf->global->ACCOUNTING_REEXPORT) ? 0 : 1));
@@ -729,6 +729,7 @@ if ($action == 'export_fileconfirm' && $user->hasRight('accounting', 'mouvements
// Export files then exit
$accountancyexport = new AccountancyExport($db);
+ $formatexport = GETPOST('formatexport', 'int');
$notexportlettering = GETPOST('notexportlettering', 'alpha');
if (!empty($notexportlettering)) {
@@ -745,7 +746,7 @@ if ($action == 'export_fileconfirm' && $user->hasRight('accounting', 'mouvements
$withAttachment = !empty(trim(GETPOST('notifiedexportfull', 'alphanohtml'))) ? 1 : 0;
// Output data on screen or download
- $result = $accountancyexport->export($object->lines, $formatexportset, $withAttachment);
+ $result = $accountancyexport->export($object->lines, $formatexport, $withAttachment);
$error = 0;
if ($result < 0) {
@@ -856,6 +857,17 @@ $formconfirm = '';
if ($action == 'export_file') {
$form_question = array();
+ $form_question['formatexport'] = array(
+ 'name' => 'formatexport',
+ 'type' => 'select',
+ 'label' => $langs->trans('Modelcsv'), // TODO Use Selectmodelcsv and show a select combo
+ 'values' => $listofformat,
+ 'default' => $formatexportset,
+ 'morecss' => 'minwidth200 maxwidth200'
+ );
+
+ $form_question['separator0'] = array('name'=>'separator0', 'type'=>'separator');
+
if (getDolGlobalInt("ACCOUNTING_ENABLE_LETTERING")) {
// If 1, we check by default.
$checked = !empty($conf->global->ACCOUNTING_DEFAULT_NOT_EXPORT_LETTERING) ? 'true' : 'false';
@@ -866,7 +878,7 @@ if ($action == 'export_file') {
'value' => $checked,
);
- $form_question['separator'] = array('name'=>'separator', 'type'=>'separator');
+ $form_question['separator1'] = array('name'=>'separator1', 'type'=>'separator');
}
// If 1 or not set, we check by default.
@@ -903,7 +915,7 @@ if ($action == 'export_file') {
);
}
- $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', $langs->trans('ConfirmExportFile'), 'export_fileconfirm', $form_question, '', 1, 400, 600);
+ $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans("ExportFilteredList").'...', $langs->trans('ConfirmExportFile'), 'export_fileconfirm', $form_question, '', 1, 420, 600);
}
//if ($action == 'delbookkeepingyear') {
@@ -1362,7 +1374,7 @@ while ($i < min($num, $limit)) {
$accountingjournal = new AccountingJournal($db);
$result = $accountingjournal->fetch('', $line->code_journal);
$journaltoshow = (($result > 0) ? $accountingjournal->getNomUrl(0, 0, 0, '', 0) : $line->code_journal);
- print '
'.$langs->trans('MailRecipients');
+ print ' '.$form->textwithpicto('', $langs->trans("TicketMessageRecipientsHelp"), 1, 'help');
+ print ' ';
if ($res) {
// Retrieve email of all contacts (internal and external)
- $contacts = $ticketstat->getInfosTicketInternalContact();
- $contacts = array_merge($contacts, $ticketstat->getInfosTicketExternalContact());
+ $contacts = $ticketstat->getInfosTicketInternalContact(1);
+ $contacts = array_merge($contacts, $ticketstat->getInfosTicketExternalContact(1));
$sendto = array();
@@ -1489,8 +1499,8 @@ class FormTicket
}
}
- if ($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS) {
- $sendto[] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO.' (generic email) ';
+ if (getDolGlobalInt('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS')) {
+ $sendto[] = getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO').' (generic email) ';
}
// Print recipient list
diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php
index b2b5e2c6e93..e9b2ac88039 100644
--- a/htdocs/core/class/ldap.class.php
+++ b/htdocs/core/class/ldap.class.php
@@ -339,17 +339,12 @@ class Ldap
* This method seems a duplicate/alias of unbind().
*
* @return boolean true or false
- * @deprecated ldap_close is an alias of ldap_unbind
+ * @deprecated ldap_close is an alias of ldap_unbind, so use unbind() instead.
* @see unbind()
*/
public function close()
{
- $r_type = get_resource_type($this->connection);
- if ($this->connection && ($r_type === "Unknown" || !@ldap_close($this->connection))) {
- return false;
- } else {
- return true;
- }
+ return $this->unbind();
}
/**
@@ -401,7 +396,7 @@ class Ldap
public function unbind()
{
$this->result = true;
- if ($this->connection) {
+ if (is_resource($this->connection) || is_object($this->connection)) {
$this->result = @ldap_unbind($this->connection);
}
if ($this->result) {
diff --git a/htdocs/core/class/menubase.class.php b/htdocs/core/class/menubase.class.php
index 9544e11e075..3630d137136 100644
--- a/htdocs/core/class/menubase.class.php
+++ b/htdocs/core/class/menubase.class.php
@@ -152,6 +152,10 @@ class Menubase
*/
public $tms;
+ /**
+ * @var Menu menu
+ */
+ public $newmenu;
/**
* Constructor
diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php
index fc562913c08..3a668d3c0c6 100644
--- a/htdocs/core/class/notify.class.php
+++ b/htdocs/core/class/notify.class.php
@@ -71,9 +71,7 @@ class Notify
'ORDER_VALIDATE',
'PROPAL_VALIDATE',
'PROPAL_CLOSE_SIGNED',
- 'PROPAL_CLOSE_SIGNED_WEB',
'PROPAL_CLOSE_REFUSED',
- 'PROPAL_CLOSE_REFUSED_WEB',
'FICHINTER_VALIDATE',
'FICHINTER_ADD_CONTACT',
'ORDER_SUPPLIER_VALIDATE',
@@ -359,6 +357,7 @@ class Notify
global $dolibarr_main_url_root;
global $action;
+ // Complete the array Notify::$arrayofnotifsupported
if (!is_object($hookmanager)) {
include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
$hookmanager = new HookManager($this->db);
@@ -373,13 +372,14 @@ class Notify
}
}
+ // If the trigger code is not managed by the Notification module
if (!in_array($notifcode, Notify::$arrayofnotifsupported)) {
return 0;
}
include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
- dol_syslog(get_class($this)."::send notifcode=".$notifcode.", object=".$object->id);
+ dol_syslog(get_class($this)."::send notifcode=".$notifcode.", object id=".$object->id);
$langs->load("other");
@@ -407,7 +407,7 @@ class Notify
// Check notification per third party
if (!empty($object->socid) && $object->socid > 0) {
$sql .= "SELECT 'tocontactid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.default_lang,";
- $sql .= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
+ $sql .= " a.rowid as adid, a.label, a.code, n.rowid, n.threshold, n.context, n.type";
$sql .= " FROM ".$this->db->prefix()."socpeople as c,";
$sql .= " ".$this->db->prefix()."c_action_trigger as a,";
$sql .= " ".$this->db->prefix()."notify_def as n,";
@@ -427,7 +427,7 @@ class Notify
// Check notification per user
$sql .= "SELECT 'touserid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.lang as default_lang,";
- $sql .= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
+ $sql .= " a.rowid as adid, a.label, a.code, n.rowid, n.threshold, n.context, n.type";
$sql .= " FROM ".$this->db->prefix()."user as c,";
$sql .= " ".$this->db->prefix()."c_action_trigger as a,";
$sql .= " ".$this->db->prefix()."notify_def as n";
@@ -439,6 +439,11 @@ class Notify
$sql .= " AND a.code = '".$this->db->escape($notifcode)."'"; // New usage
}
+ // Check notification fixed
+ // TODO Move part found after, into a sql here
+
+
+ // Loop on all notifications enabled
$result = $this->db->query($sql);
if ($result) {
$num = $this->db->num_rows($result);
@@ -511,13 +516,9 @@ class Notify
$object_type = 'propal';
$labeltouse = $conf->global->PROPAL_CLOSE_REFUSED_TEMPLATE;
$mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedRefused", $link);
- break;
- case 'PROPAL_CLOSE_REFUSED_WEB':
- $link = ''.$newref.' ';
- $dir_output = $conf->propal->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object, 'propal');
- $object_type = 'propal';
- $labeltouse = $conf->global->PROPAL_CLOSE_REFUSED_TEMPLATE;
- $mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedRefusedWeb", $link);
+ if (!empty($object->context['closedfromonlinesignature'])) {
+ $mesg .= ' - From online page';
+ }
break;
case 'PROPAL_CLOSE_SIGNED':
$link = ''.$newref.' ';
@@ -525,13 +526,9 @@ class Notify
$object_type = 'propal';
$labeltouse = $conf->global->PROPAL_CLOSE_SIGNED_TEMPLATE;
$mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedSigned", $link);
- break;
- case 'PROPAL_CLOSE_SIGNED_WEB':
- $link = ''.$newref.' ';
- $dir_output = $conf->propal->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object, 'propal');
- $object_type = 'propal';
- $labeltouse = $conf->global->PROPAL_CLOSE_SIGNED_TEMPLATE;
- $mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedSigned", $link);
+ if (!empty($object->context['closedfromonlinesignature'])) {
+ $mesg .= ' - From online page';
+ }
break;
case 'FICHINTER_ADD_CONTACT':
$link = ''.$newref.' ';
@@ -651,6 +648,23 @@ class Notify
$labeltouse = !empty($labeltouse) ? $labeltouse : '';
+ // Replace keyword __SUPERVISOREMAIL__
+ if (preg_match('/__SUPERVISOREMAIL__/', $sendto)) {
+ $newval = '';
+ if ($user->fk_user > 0) {
+ $supervisoruser = new User($this->db);
+ $supervisoruser->fetch($user->fk_user);
+ if ($supervisoruser->email) {
+ $newval = trim(dolGetFirstLastname($supervisoruser->firstname, $supervisoruser->lastname).' <'.$supervisoruser->email.'>');
+ }
+ }
+ dol_syslog("Replace the __SUPERVISOREMAIL__ key into recipient email string with ".$newval);
+ $sendto = preg_replace('/__SUPERVISOREMAIL__/', $newval, $sendto);
+ $sendto = preg_replace('/,\s*,/', ',', $sendto); // in some case you can have $sendto like "email, __SUPERVISOREMAIL__ , otheremail" then you have "email, , othermail" and it's not valid
+ $sendto = preg_replace('/^[\s,]+/', '', $sendto); // Clean start of string
+ $sendto = preg_replace('/[\s,]+$/', '', $sendto); // Clean end of string
+ }
+
$parameters = array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list, 'outputlangs'=>$outputlangs, 'labeltouse'=>$labeltouse);
if (!isset($action)) {
$action = '';
@@ -721,6 +735,7 @@ class Notify
}
// Check notification using fixed email
+ // TODO Move vars NOTIFICATION_FIXEDEMAIL into table llx_notify_def and inclulde the case into previous loop of sql result
if (!$error) {
foreach ($conf->global as $key => $val) {
$reg = array();
diff --git a/htdocs/core/class/rssparser.class.php b/htdocs/core/class/rssparser.class.php
index 6992612592d..6d83fd6d6da 100644
--- a/htdocs/core/class/rssparser.class.php
+++ b/htdocs/core/class/rssparser.class.php
@@ -36,6 +36,8 @@ class RssParser
*/
public $error = '';
+ public $feed_version;
+
private $_format = '';
private $_urlRSS;
private $_language;
@@ -446,7 +448,7 @@ class RssParser
$itemDescription = sanitizeVal((string) $item['description']);
$itemPubDate = sanitizeVal((string) $item['pubdate']);
$itemId = sanitizeVal((string) $item['guid']);
- $itemAuthor = sanitizeVal((string) $item['author']);
+ $itemAuthor = sanitizeVal((string) ($item['author'] ?? ''));
}
// Loop on each category
diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php
index 135d9d9e8de..46193e1efea 100644
--- a/htdocs/core/class/smtps.class.php
+++ b/htdocs/core/class/smtps.class.php
@@ -1862,6 +1862,7 @@ class SMTPs
} elseif ($type == 'alternative') {
return $this->_smtpsAlternativeBoundary;
}
+ return '';
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
diff --git a/htdocs/core/class/validate.class.php b/htdocs/core/class/validate.class.php
index 31cf6300aff..37bb37aec4f 100644
--- a/htdocs/core/class/validate.class.php
+++ b/htdocs/core/class/validate.class.php
@@ -27,7 +27,6 @@
*/
class Validate
{
-
/**
* @var DoliDb Database handler (result of a new DoliDB)
*/
@@ -62,7 +61,7 @@ class Validate
}
if (!is_object($this->outputLang) || !method_exists($this->outputLang, 'load')) {
- return false;
+ return;
}
$this->outputLang->loadLangs(array('validate', 'errors'));
@@ -72,7 +71,8 @@ class Validate
/**
* Use to clear errors msg or other ghost vars
- * @return null
+ *
+ * @return void
*/
protected function clear()
{
@@ -82,8 +82,8 @@ class Validate
/**
* Use to clear errors msg or other ghost vars
*
- * @param string $errMsg your error message
- * @return null
+ * @param string $errMsg your error message
+ * @return void
*/
protected function setError($errMsg)
{
@@ -93,9 +93,9 @@ class Validate
/**
* Check for e-mail validity
*
- * @param string $email e-mail address to validate
- * @param int $maxLength string max length
- * @return boolean Validity is ok or not
+ * @param string $email e-mail address to validate
+ * @param int $maxLength string max length
+ * @return boolean Validity is ok or not
*/
public function isEmail($email, $maxLength = false)
{
diff --git a/htdocs/core/customreports.php b/htdocs/core/customreports.php
index 7a1f68e5c6c..e54019a56b4 100644
--- a/htdocs/core/customreports.php
+++ b/htdocs/core/customreports.php
@@ -295,12 +295,7 @@ if (is_array($search_groupby) && count($search_groupby)) {
$sqlfilters = GETPOST('search_component_params_hidden', 'alphanohtml');
if ($sqlfilters) {
$errormessage = '';
- if (dolCheckFilters($sqlfilters, $errormessage)) {
- $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
- $sql .= " WHERE (".preg_replace_callback('/'.$regexstring.'/', 'dolForgeCriteriaCallback', $sqlfilters).")";
- } else {
- print $errormessage;
- }
+ $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
}*/
$sql .= " LIMIT ".((int) ($MAXUNIQUEVALFORGROUP + 1));
@@ -420,7 +415,7 @@ $viewmode = '';
$viewmode .= '';
$arrayofgraphs = array('bars' => 'Bars', 'lines' => 'Lines'); // also 'pies'
$viewmode .= '
'.$langs->trans("Graph").'
';
-$viewmode .= $form->selectarray('search_graph', $arrayofgraphs, $search_graph, 0, 0, 0, 'minwidth100', 1);
+$viewmode .= $form->selectarray('search_graph', $arrayofgraphs, $search_graph, 0, 0, 0, '', 1, 0, 0, '', 'graphtype width100');
$viewmode .= '
';
$num = 0;
@@ -684,11 +679,9 @@ if (!empty($search_measures) && !empty($search_xaxis)) {
$sqlfilters = $search_component_params_hidden;
if ($sqlfilters) {
$errormessage = '';
- if (dolCheckFilters($sqlfilters, $errormessage)) {
- $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
- $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'dolForgeCriteriaCallback', $sqlfilters).")";
- } else {
- print $errormessage;
+ $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
+ if ($errormessage) {
+ print dol_escape_htmltag($errormessage);
}
}
$sql .= " GROUP BY ";
diff --git a/htdocs/core/filemanagerdol/browser/default/browser.php b/htdocs/core/filemanagerdol/browser/default/browser.php
index 0c1b29d12b2..1cf6d8612c2 100644
--- a/htdocs/core/filemanagerdol/browser/default/browser.php
+++ b/htdocs/core/filemanagerdol/browser/default/browser.php
@@ -49,6 +49,7 @@ if (!empty($conf->modules_parts['theme'])) { // This slow down
}
//print 'themepath='.$themepath.' themeparam='.$themeparam;exit;
+$themeparam = '';
print ' '."\n";
?>
diff --git a/htdocs/core/filemanagerdol/connectors/php/config.inc.php b/htdocs/core/filemanagerdol/connectors/php/config.inc.php
index 848153d84fc..368b82c42e7 100644
--- a/htdocs/core/filemanagerdol/connectors/php/config.inc.php
+++ b/htdocs/core/filemanagerdol/connectors/php/config.inc.php
@@ -37,7 +37,7 @@ $pos = strstr($uri, '/'); // $pos contient alors url sans nom domaine
if ($pos == '/') {
$pos = ''; // si $pos vaut /, on le met a ''
}
-define('DOL_URL_ROOT', $pos);
+//define('DOL_URL_ROOT', $pos);
$entity = ((!empty($_SESSION['dol_entity']) && $_SESSION['dol_entity'] > 1) ? $_SESSION['dol_entity'] : null);
// SECURITY: You must explicitly enable this "connector". (Set it to "true").
diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php
index c29eec57698..60adcc64003 100644
--- a/htdocs/core/lib/files.lib.php
+++ b/htdocs/core/lib/files.lib.php
@@ -1003,8 +1003,8 @@ function dol_move($srcfile, $destfile, $newmask = 0, $overwriteifexists = 1, $te
* @param string $srcdir Source directory
* @param string $destdir Destination directory
* @param int $overwriteifexists Overwrite directory if exists (1 by default)
- * @param int $indexdatabase Index new file into database.
- * @param int $renamedircontent Rename contents inside srcdir.
+ * @param int $indexdatabase Index new name of files into database.
+ * @param int $renamedircontent Also rename contents inside srcdir after the move to match new destination name.
*
* @return boolean True if OK, false if KO
*/
@@ -1045,7 +1045,7 @@ function dol_move_dir($srcdir, $destdir, $overwriteifexists = 1, $indexdatabase
if ($file["type"] == "dir") {
$res = dol_move_dir($filepath.'/'.$oldname, $filepath.'/'.$newname, $overwriteifexists, $indexdatabase, $renamedircontent);
} else {
- $res = dol_move($filepath.'/'.$oldname, $filepath.'/'.$newname);
+ $res = dol_move($filepath.'/'.$oldname, $filepath.'/'.$newname, 0, $overwriteifexists, 0, $indexdatabase);
}
if (!$res) {
return $result;
@@ -2590,54 +2590,54 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
$original_file = $conf->adherent->dir_output.'/'.$original_file;
} elseif ($modulepart == 'apercufacture' && !empty($conf->facture->multidir_output[$entity])) {
// Wrapping for invoices (user need permission to read invoices)
- if ($fuser->rights->facture->{$lire}) {
+ if ($fuser->hasRight('facture', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->facture->multidir_output[$entity].'/'.$original_file;
} elseif ($modulepart == 'apercupropal' && !empty($conf->propal->multidir_output[$entity])) {
// Wrapping pour les apercu propal
- if ($fuser->rights->propal->{$lire}) {
+ if ($fuser->hasRight('propal', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->propal->multidir_output[$entity].'/'.$original_file;
} elseif ($modulepart == 'apercucommande' && !empty($conf->commande->multidir_output[$entity])) {
// Wrapping pour les apercu commande
- if ($fuser->rights->commande->{$lire}) {
+ if ($fuser->hasRight('commande', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->commande->multidir_output[$entity].'/'.$original_file;
} elseif (($modulepart == 'apercufichinter' || $modulepart == 'apercuficheinter') && !empty($conf->ficheinter->dir_output)) {
// Wrapping pour les apercu intervention
- if ($fuser->rights->ficheinter->{$lire}) {
+ if ($fuser->hasRight('ficheinter', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->ficheinter->dir_output.'/'.$original_file;
} elseif (($modulepart == 'apercucontract') && !empty($conf->contrat->multidir_output[$entity])) {
// Wrapping pour les apercu contrat
- if ($fuser->rights->contrat->{$lire}) {
+ if ($fuser->hasRight('contrat', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->contrat->multidir_output[$entity].'/'.$original_file;
} elseif (($modulepart == 'apercusupplier_proposal' || $modulepart == 'apercusupplier_proposal') && !empty($conf->supplier_proposal->dir_output)) {
// Wrapping pour les apercu supplier proposal
- if ($fuser->rights->supplier_proposal->{$lire}) {
+ if ($fuser->hasRight('supplier_proposal', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->supplier_proposal->dir_output.'/'.$original_file;
} elseif (($modulepart == 'apercusupplier_order' || $modulepart == 'apercusupplier_order') && !empty($conf->fournisseur->commande->dir_output)) {
// Wrapping pour les apercu supplier order
- if ($fuser->rights->fournisseur->commande->{$lire}) {
+ if ($fuser->hasRight('fournisseur', 'commande', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->fournisseur->commande->dir_output.'/'.$original_file;
} elseif (($modulepart == 'apercusupplier_invoice' || $modulepart == 'apercusupplier_invoice') && !empty($conf->fournisseur->facture->dir_output)) {
// Wrapping pour les apercu supplier invoice
- if ($fuser->rights->fournisseur->facture->{$lire}) {
+ if ($fuser->hasRight('fournisseur', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->fournisseur->facture->dir_output.'/'.$original_file;
} elseif (($modulepart == 'holiday') && !empty($conf->holiday->dir_output)) {
- if ($fuser->rights->holiday->{$read} || !empty($fuser->rights->holiday->readall) || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('holiday', $read) || !empty($fuser->rights->holiday->readall) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
// If we known $id of holiday, call checkUserAccessToObject to check permission on properties and hierarchy of leave request
if ($refname && empty($fuser->rights->holiday->readall) && !preg_match('/^specimen/i', $original_file)) {
@@ -2649,7 +2649,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
}
$original_file = $conf->holiday->dir_output.'/'.$original_file;
} elseif (($modulepart == 'expensereport') && !empty($conf->expensereport->dir_output)) {
- if ($fuser->rights->expensereport->{$lire} || !empty($fuser->rights->expensereport->readall) || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('expensereport', $lire) || !empty($fuser->rights->expensereport->readall) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
// If we known $id of expensereport, call checkUserAccessToObject to check permission on properties and hierarchy of expense report
if ($refname && empty($fuser->rights->expensereport->readall) && !preg_match('/^specimen/i', $original_file)) {
@@ -2662,72 +2662,72 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
$original_file = $conf->expensereport->dir_output.'/'.$original_file;
} elseif (($modulepart == 'apercuexpensereport') && !empty($conf->expensereport->dir_output)) {
// Wrapping pour les apercu expense report
- if ($fuser->rights->expensereport->{$lire}) {
+ if ($fuser->hasRight('expensereport', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->expensereport->dir_output.'/'.$original_file;
} elseif ($modulepart == 'propalstats' && !empty($conf->propal->multidir_temp[$entity])) {
// Wrapping pour les images des stats propales
- if ($fuser->rights->propal->{$lire}) {
+ if ($fuser->hasRight('propal', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->propal->multidir_temp[$entity].'/'.$original_file;
} elseif ($modulepart == 'orderstats' && !empty($conf->commande->dir_temp)) {
// Wrapping pour les images des stats commandes
- if ($fuser->rights->commande->{$lire}) {
+ if ($fuser->hasRight('commande', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->commande->dir_temp.'/'.$original_file;
} elseif ($modulepart == 'orderstatssupplier' && !empty($conf->fournisseur->dir_output)) {
- if ($fuser->rights->fournisseur->commande->{$lire}) {
+ if ($fuser->hasRight('fournisseur', 'commande', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->fournisseur->commande->dir_temp.'/'.$original_file;
} elseif ($modulepart == 'billstats' && !empty($conf->facture->dir_temp)) {
// Wrapping pour les images des stats factures
- if ($fuser->rights->facture->{$lire}) {
+ if ($fuser->hasRight('facture', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->facture->dir_temp.'/'.$original_file;
} elseif ($modulepart == 'billstatssupplier' && !empty($conf->fournisseur->dir_output)) {
- if ($fuser->rights->fournisseur->facture->{$lire}) {
+ if ($fuser->hasRight('fournisseur', 'facture', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->fournisseur->facture->dir_temp.'/'.$original_file;
} elseif ($modulepart == 'expeditionstats' && !empty($conf->expedition->dir_temp)) {
// Wrapping pour les images des stats expeditions
- if ($fuser->rights->expedition->{$lire}) {
+ if ($fuser->hasRight('expedition', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->expedition->dir_temp.'/'.$original_file;
} elseif ($modulepart == 'tripsexpensesstats' && !empty($conf->deplacement->dir_temp)) {
// Wrapping pour les images des stats expeditions
- if ($fuser->rights->deplacement->{$lire}) {
+ if ($fuser->hasRight('deplacement', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->deplacement->dir_temp.'/'.$original_file;
} elseif ($modulepart == 'memberstats' && !empty($conf->adherent->dir_temp)) {
// Wrapping pour les images des stats expeditions
- if ($fuser->rights->adherent->{$lire}) {
+ if ($fuser->hasRight('adherent', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->adherent->dir_temp.'/'.$original_file;
} elseif (preg_match('/^productstats_/i', $modulepart) && !empty($conf->product->dir_temp)) {
// Wrapping pour les images des stats produits
- if ($fuser->rights->produit->{$lire} || $fuser->rights->service->{$lire}) {
+ if ($fuser->hasRight('produit', $lire) || $fuser->hasRight('service', $lire)) {
$accessallowed = 1;
}
$original_file = (!empty($conf->product->multidir_temp[$entity]) ? $conf->product->multidir_temp[$entity] : $conf->service->multidir_temp[$entity]).'/'.$original_file;
} elseif (in_array($modulepart, array('tax', 'tax-vat', 'tva')) && !empty($conf->tax->dir_output)) {
// Wrapping for taxes
- if ($fuser->rights->tax->charges->{$lire}) {
+ if ($fuser->hasRight('tax', 'charges', $lire)) {
$accessallowed = 1;
}
$modulepartsuffix = str_replace('tax-', '', $modulepart);
$original_file = $conf->tax->dir_output.'/'.($modulepartsuffix != 'tax' ? $modulepartsuffix.'/' : '').$original_file;
} elseif ($modulepart == 'actions' && !empty($conf->agenda->dir_output)) {
// Wrapping for events
- if ($fuser->rights->agenda->myactions->{$read}) {
+ if ($fuser->hasRight('agenda', 'myactions', $read)) {
$accessallowed = 1;
// If we known $id of project, call checkUserAccessToObject to check permission on the given agenda event on properties and assigned users
if ($refname && !preg_match('/^specimen/i', $original_file)) {
@@ -2811,85 +2811,85 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
if (empty($entity) || empty($conf->societe->multidir_output[$entity])) {
return array('accessallowed'=>0, 'error'=>'Value entity must be provided');
}
- if ($fuser->rights->societe->{$lire}) {
+ if ($fuser->hasRight('societe', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->societe->multidir_output[$entity].'/contact/'.$original_file;
} elseif (($modulepart == 'facture' || $modulepart == 'invoice') && !empty($conf->facture->multidir_output[$entity])) {
// Wrapping for invoices
- if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('facture', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->facture->multidir_output[$entity].'/'.$original_file;
$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."facture WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('invoice').")";
} elseif ($modulepart == 'massfilesarea_proposals' && !empty($conf->propal->multidir_output[$entity])) {
// Wrapping for mass actions
- if ($fuser->rights->propal->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('propal', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->propal->multidir_output[$entity].'/temp/massgeneration/'.$user->id.'/'.$original_file;
} elseif ($modulepart == 'massfilesarea_orders') {
- if ($fuser->rights->commande->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('commande', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->commande->multidir_output[$entity].'/temp/massgeneration/'.$user->id.'/'.$original_file;
} elseif ($modulepart == 'massfilesarea_sendings') {
- if ($fuser->rights->expedition->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('expedition', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->expedition->dir_output.'/sending/temp/massgeneration/'.$user->id.'/'.$original_file;
} elseif ($modulepart == 'massfilesarea_invoices') {
- if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('facture', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->facture->multidir_output[$entity].'/temp/massgeneration/'.$user->id.'/'.$original_file;
} elseif ($modulepart == 'massfilesarea_expensereport') {
- if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('facture', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->expensereport->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
} elseif ($modulepart == 'massfilesarea_interventions') {
- if ($fuser->rights->ficheinter->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('ficheinter', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->ficheinter->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
} elseif ($modulepart == 'massfilesarea_supplier_proposal' && !empty($conf->supplier_proposal->dir_output)) {
- if ($fuser->rights->supplier_proposal->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('supplier_proposal', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->supplier_proposal->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
} elseif ($modulepart == 'massfilesarea_supplier_order') {
- if ($fuser->rights->fournisseur->commande->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('fournisseur', 'commande', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->fournisseur->commande->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
} elseif ($modulepart == 'massfilesarea_supplier_invoice') {
- if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('fournisseur', 'facture', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->fournisseur->facture->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
} elseif ($modulepart == 'massfilesarea_contract' && !empty($conf->contrat->dir_output)) {
- if ($fuser->rights->contrat->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('contrat', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->contrat->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
} elseif (($modulepart == 'fichinter' || $modulepart == 'ficheinter') && !empty($conf->ficheinter->dir_output)) {
// Wrapping for interventions
- if ($fuser->rights->ficheinter->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('ficheinter', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->ficheinter->dir_output.'/'.$original_file;
$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."fichinter WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
} elseif ($modulepart == 'deplacement' && !empty($conf->deplacement->dir_output)) {
// Wrapping pour les deplacements et notes de frais
- if ($fuser->rights->deplacement->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('deplacement', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->deplacement->dir_output.'/'.$original_file;
//$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."fichinter WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
- } elseif (($modulepart == 'propal' || $modulepart == 'propale') && !empty($conf->propal->multidir_output[$entity])) {
+ } elseif (($modulepart == 'propal' || $modulepart == 'propale') && isset($conf->propal->multidir_output[$entity])) {
// Wrapping pour les propales
- if ($fuser->rights->propal->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('propal', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->propal->multidir_output[$entity].'/'.$original_file;
@@ -2903,7 +2903,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."commande WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('order').")";
} elseif ($modulepart == 'project' && !empty($conf->project->dir_output)) {
// Wrapping pour les projets
- if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('projet', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
// If we known $id of project, call checkUserAccessToObject to check permission on properties and contact of project
if ($refname && !preg_match('/^specimen/i', $original_file)) {
@@ -2916,7 +2916,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
$original_file = $conf->project->dir_output.'/'.$original_file;
$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('project').")";
} elseif ($modulepart == 'project_task' && !empty($conf->project->dir_output)) {
- if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('projet', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
// If we known $id of project, call checkUserAccessToObject to check permission on properties and contact of project
if ($refname && !preg_match('/^specimen/i', $original_file)) {
@@ -2951,7 +2951,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."paiementfournisseur WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
} elseif ($modulepart == 'facture_paiement' && !empty($conf->facture->dir_output)) {
// Wrapping pour les rapport de paiements
- if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('facture', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
if ($fuser->socid > 0) {
@@ -2967,26 +2967,26 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
$original_file = $conf->accounting->dir_output.'/'.$original_file;
} elseif (($modulepart == 'expedition' || $modulepart == 'shipment') && !empty($conf->expedition->dir_output)) {
// Wrapping pour les expedition
- if ($fuser->rights->expedition->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('expedition', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->expedition->dir_output."/".(strpos('sending/', $original_file) === 0 ? '' : 'sending/').$original_file;
//$original_file = $conf->expedition->dir_output."/".$original_file;
} elseif (($modulepart == 'livraison' || $modulepart == 'delivery') && !empty($conf->expedition->dir_output)) {
// Delivery Note Wrapping
- if ($fuser->rights->expedition->delivery->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('expedition', 'delivery', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->expedition->dir_output."/".(strpos('receipt/', $original_file) === 0 ? '' : 'receipt/').$original_file;
} elseif ($modulepart == 'actions' && !empty($conf->agenda->dir_output)) {
// Wrapping pour les actions
- if ($fuser->rights->agenda->myactions->{$read} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('agenda', 'myactions', $read) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->agenda->dir_output.'/'.$original_file;
} elseif ($modulepart == 'actionsreport' && !empty($conf->agenda->dir_temp)) {
// Wrapping pour les actions
- if ($fuser->rights->agenda->allactions->{$read} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('agenda', 'allactions', $read) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->agenda->dir_temp."/".$original_file;
@@ -2995,7 +2995,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
if (empty($entity) || (empty($conf->product->multidir_output[$entity]) && empty($conf->service->multidir_output[$entity]))) {
return array('accessallowed'=>0, 'error'=>'Value entity must be provided');
}
- if (($fuser->rights->produit->{$lire} || $fuser->rights->service->{$lire}) || preg_match('/^specimen/i', $original_file)) {
+ if (($fuser->hasRight('produit', $lire) || $fuser->hasRight('service', $lire)) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
if (isModEnabled("product")) {
@@ -3008,7 +3008,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
if (empty($entity) || (empty($conf->productbatch->multidir_output[$entity]))) {
return array('accessallowed'=>0, 'error'=>'Value entity must be provided');
}
- if (($fuser->rights->produit->{$lire} ) || preg_match('/^specimen/i', $original_file)) {
+ if (($fuser->hasRight('produit', $lire)) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
if (isModEnabled('productbatch')) {
@@ -3019,7 +3019,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
if (empty($entity) || empty($conf->stock->multidir_output[$entity])) {
return array('accessallowed'=>0, 'error'=>'Value entity must be provided');
}
- if (($fuser->rights->stock->{$lire} || $fuser->rights->stock->movement->{$lire} || $fuser->rights->stock->mouvement->{$lire}) || preg_match('/^specimen/i', $original_file)) {
+ if (($fuser->hasRight('stock', $lire) || $fuser->hasRight('stock', 'movement', $lire) || $fuser->hasRight('stock', 'mouvement', $lire)) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
if (isModEnabled('stock')) {
@@ -3034,26 +3034,26 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."contrat WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('contract').")";
} elseif ($modulepart == 'donation' && !empty($conf->don->dir_output)) {
// Wrapping pour les dons
- if ($fuser->rights->don->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('don', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->don->dir_output.'/'.$original_file;
} elseif ($modulepart == 'dolresource' && !empty($conf->resource->dir_output)) {
// Wrapping pour les dons
- if ($fuser->rights->resource->{$read} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('resource', $read) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->resource->dir_output.'/'.$original_file;
} elseif (($modulepart == 'remisecheque' || $modulepart == 'chequereceipt') && !empty($conf->bank->dir_output)) {
// Wrapping pour les remises de cheques
- if ($fuser->rights->banque->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('banque', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->bank->dir_output.'/checkdeposits/'.$original_file; // original_file should contains relative path so include the get_exdir result
} elseif (($modulepart == 'banque' || $modulepart == 'bank') && !empty($conf->bank->dir_output)) {
// Wrapping for bank
- if ($fuser->rights->banque->{$lire}) {
+ if ($fuser->hasRight('banque', $lire)) {
$accessallowed = 1;
}
$original_file = $conf->bank->dir_output.'/'.$original_file;
@@ -3096,7 +3096,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
$original_file = $conf->bittorrent->dir_output.'/'.$dir.'/'.$original_file;
} elseif ($modulepart == 'member' && !empty($conf->adherent->dir_output)) {
// Wrapping pour Foundation module
- if ($fuser->rights->adherent->{$lire} || preg_match('/^specimen/i', $original_file)) {
+ if ($fuser->hasRight('adherent', $lire) || preg_match('/^specimen/i', $original_file)) {
$accessallowed = 1;
}
$original_file = $conf->adherent->dir_output.'/'.$original_file;
diff --git a/htdocs/core/lib/fourn.lib.php b/htdocs/core/lib/fourn.lib.php
index c658916e359..7093493dad9 100644
--- a/htdocs/core/lib/fourn.lib.php
+++ b/htdocs/core/lib/fourn.lib.php
@@ -3,7 +3,7 @@
* Copyright (C) 2005-2012 Regis Houssin
* Copyright (C) 2006 Marc Barilley
* Copyright (C) 2011-2013 Philippe Grand
- * Copyright (C) 2022 Frédéric France
+ * Copyright (C) 2022-2023 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,10 +29,10 @@
/**
* Prepare array with list of tabs
*
- * @param Object $object Object related to tabs
+ * @param FactureFournisseur $object Object related to tabs
* @return array Array of tabs to show
*/
-function facturefourn_prepare_head($object)
+function facturefourn_prepare_head(FactureFournisseur $object)
{
global $db, $langs, $conf;
@@ -56,7 +56,7 @@ function facturefourn_prepare_head($object)
}
//if ($fac->mode_reglement_code == 'PRE')
- if (!empty($conf->paymentbybanktransfer->enabled)) {
+ if (isModEnabled('paymentbybanktransfer')) {
$nbStandingOrders = 0;
$sql = "SELECT COUNT(pfd.rowid) as nb";
$sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pfd";
@@ -132,8 +132,8 @@ function facturefourn_prepare_head($object)
/**
* Prepare array with list of tabs
*
- * @param Object $object Object related to tabs
- * @return array Array of tabs to show
+ * @param CommandeFournisseur $object Object related to tabs
+ * @return array Array of tabs to show
*/
function ordersupplier_prepare_head(CommandeFournisseur $object)
{
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index e6ac7f2d9f2..887d14fd36a 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -1125,6 +1125,7 @@ function dol_buildpath($path, $type = 0, $returnemptyifnotfound = 0)
}
continue;
}
+ $regs = array();
preg_match('/^([^\?]+(\.css\.php|\.css|\.js\.php|\.js|\.png|\.jpg|\.php)?)/i', $path, $regs); // Take part before '?'
if (!empty($regs[1])) {
//print $key.'-'.$dirroot.'/'.$path.'-'.$conf->file->dol_url_root[$type].' '."\n";
@@ -1672,7 +1673,7 @@ function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename =
if (!array_key_exists($level, $logLevels)) {
throw new Exception('Incorrect log level');
}
- if ($level > $conf->global->SYSLOG_LEVEL) {
+ if ($level > getDolGlobalInt('SYSLOG_LEVEL')) {
return;
}
@@ -2324,14 +2325,12 @@ function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldi
}
$tmptxt = $object->getLibStatut(5);
$morehtmlstatus .= $tmptxt; // No status on task
- } else { // Generic case
- if (isset($object->status)) {
- $tmptxt = $object->getLibStatut(6);
- if (empty($tmptxt) || $tmptxt == $object->getLibStatut(3)) {
- $tmptxt = $object->getLibStatut(5);
- }
- $morehtmlstatus .= $tmptxt;
+ } elseif (method_exists($object, 'getLibStatut')) { // Generic case
+ $tmptxt = $object->getLibStatut(6);
+ if (empty($tmptxt) || $tmptxt == $object->getLibStatut(3)) {
+ $tmptxt = $object->getLibStatut(5);
}
+ $morehtmlstatus .= $tmptxt;
}
// Add if object was dispatched "into accountancy"
@@ -2648,7 +2647,7 @@ function dol_print_date($time, $format = '', $tzoutput = 'auto', $outputlangs =
$format = '%Y%m%d%H%M%S';
} elseif ($format == 'dayhourlogsmall') {
// Format not sensitive to language
- $format = '%Y%m%d%H%M';
+ $format = '%y%m%d%H%M';
} elseif ($format == 'dayhourldap') {
$format = '%Y%m%d%H%M%SZ';
} elseif ($format == 'dayhourxcard') {
@@ -2731,8 +2730,8 @@ function dol_print_date($time, $format = '', $tzoutput = 'auto', $outputlangs =
$dtts->setTimestamp($timetouse);
$dtts->setTimezone($tzo);
$newformat = str_replace(
- array('%Y', '%y', '%m', '%d', '%H', '%I', '%M', '%S', '%p', 'T', 'Z', '__a__', '__A__', '__b__', '__B__'),
- array('Y', 'y', 'm', 'd', 'H', 'h', 'i', 's', 'A', '__£__', '__$__', '__{__', '__}__', '__[__', '__]__'),
+ array('%Y', '%y', '%m', '%d', '%H', '%I', '%M', '%S', '%p', '%w', 'T', 'Z', '__a__', '__A__', '__b__', '__B__'),
+ array('Y', 'y', 'm', 'd', 'H', 'h', 'i', 's', 'A', 'w', '__£__', '__$__', '__{__', '__}__', '__[__', '__]__'),
$format);
$ret = $dtts->format($newformat);
$ret = str_replace(
@@ -3575,15 +3574,15 @@ function dol_print_phone($phone, $countrycode = '', $cid = 0, $socid = 0, $addli
$picto = '';
}
}
- if ($adddivfloat) {
+ if ($adddivfloat == 1) {
$rep .= '';
- } else {
+ } elseif (empty($adddivfloat)) {
$rep .= '';
}
$rep .= ($withpicto ?img_picto($titlealt, 'object_'.$picto.'.png').' ' : '').$newphone;
- if ($adddivfloat) {
+ if ($adddivfloat == 1) {
$rep .= '
';
- } else {
+ } elseif (empty($adddivfloat)) {
$rep .= '';
}
}
@@ -4008,8 +4007,9 @@ function dol_trunc($string, $size = 40, $trunc = 'right', $stringencoding = 'UTF
* Show picto whatever it's its name (generic function)
*
* @param string $titlealt Text on title tag for tooltip. Not used if param notitle is set to 1.
- * @param string $picto Name of image file to show ('filenew', ...)
- * If no extension provided, we use '.png'. Image must be stored into theme/xxx/img directory.
+ * @param string $picto Name of image file to show ('filenew', ...).
+ * For font awesome icon (example 'user'), you can use picto_nocolor to not have the color of picto forced.
+ * If no extension provided and it is not a font awesome icon, we use '.png'. Image must be stored into theme/xxx/img directory.
* Example: picto.png if picto.png is stored into htdocs/theme/mytheme/img
* Example: picto.png@mymodule if picto.png is stored into htdocs/mymodule/img
* Example: /mydir/mysubdir/picto.png if picto.png is stored into htdocs/mydir/mysubdir (pictoisfullpath must be set to 1)
@@ -4047,6 +4047,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
} else {
$pictowithouttext = preg_replace('/(\.png|\.gif|\.svg)$/', '', $picto);
$pictowithouttext = str_replace('object_', '', $pictowithouttext);
+ $pictowithouttext = str_replace('_nocolor', '', $pictowithouttext);
if (strpos($pictowithouttext, 'fontawesome_') !== false || preg_match('/^fa-/', $pictowithouttext)) {
// This is a font awesome image 'fonwtawesome_xxx' or 'fa-xxx'
@@ -4104,7 +4105,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
'edit', 'ellipsis-h', 'email', 'entity', 'envelope', 'eraser', 'establishment', 'expensereport', 'external-link-alt', 'external-link-square-alt', 'eye',
'filter', 'file-code', 'file-export', 'file-import', 'file-upload', 'autofill', 'folder', 'folder-open', 'folder-plus',
'gears', 'generate', 'globe', 'globe-americas', 'graph', 'grip', 'grip_title', 'group',
- 'help', 'holiday',
+ 'hands-helping', 'help', 'holiday',
'id-card', 'images', 'incoterm', 'info', 'intervention', 'inventory', 'intracommreport', 'jobprofile',
'knowledgemanagement',
'label', 'language', 'line', 'link', 'list', 'list-alt', 'listlight', 'loan', 'lock', 'lot', 'long-arrow-alt-right',
@@ -4256,7 +4257,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
//'title_setup'=>'infobox-action', 'tools'=>'infobox-action',
'list-alt'=>'imgforviewmode', 'calendar'=>'imgforviewmode', 'calendarweek'=>'imgforviewmode', 'calendarmonth'=>'imgforviewmode', 'calendarday'=>'imgforviewmode', 'calendarperuser'=>'imgforviewmode'
);
- if (!empty($arrayconvpictotomorcess[$pictowithouttext])) {
+ if (!empty($arrayconvpictotomorcess[$pictowithouttext]) && strpos($picto, '_nocolor') === false) {
$morecss .= ($morecss ? ' ' : '').$arrayconvpictotomorcess[$pictowithouttext];
}
@@ -4276,7 +4277,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
'uncheck'=>'#800', 'uparrow'=>'#555', 'user-cog'=>'#999', 'country'=>'#aaa', 'globe-americas'=>'#aaa', 'region'=>'#aaa', 'state'=>'#aaa',
'website'=>'#304', 'workstation'=>'#a69944'
);
- if (isset($arrayconvpictotocolor[$pictowithouttext])) {
+ if (isset($arrayconvpictotocolor[$pictowithouttext]) && strpos($picto, '_nocolor') === false) {
$facolor = $arrayconvpictotocolor[$pictowithouttext];
}
@@ -5175,7 +5176,7 @@ function dol_print_error_email($prefixcode, $errormessage = '', $errormessages =
* @param string $moreattrib Options of attribute td ("" by defaut)
* @param string $sortfield Current field used to sort
* @param string $sortorder Current sort order
- * @param string $prefix Prefix for css. Use space after prefix to add your own CSS tag.
+ * @param string $prefix Prefix for css. Use space after prefix to add your own CSS tag, for example 'mycss '.
* @param string $tooltip Tooltip
* @param string $forcenowrapcolumntitle No need for use 'wrapcolumntitle' css style
* @return void
@@ -7638,9 +7639,9 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null,
'__USER_ID__' => (string) $user->id,
'__USER_LOGIN__' => (string) $user->login,
'__USER_EMAIL__' => (string) $user->email,
- '__USER_PHONE__' => (string) dol_print_phone($user->office_phone),
- '__USER_PHONEPRO__' => (string) dol_print_phone($user->user_mobile),
- '__USER_PHONEMOBILE__' => (string) dol_print_phone($user->personal_mobile),
+ '__USER_PHONE__' => (string) dol_print_phone($user->office_phone, '', 0, 0, '', " ", '', '', -1),
+ '__USER_PHONEPRO__' => (string) dol_print_phone($user->user_mobile, '', 0, 0, '', " ", '', '', -1),
+ '__USER_PHONEMOBILE__' => (string) dol_print_phone($user->personal_mobile, '', 0, 0, '', " ", '', '', -1),
'__USER_FAX__' => (string) $user->office_fax,
'__USER_LASTNAME__' => (string) $user->lastname,
'__USER_FIRSTNAME__' => (string) $user->firstname,
@@ -7655,8 +7656,8 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null,
$substitutionarray = array_merge($substitutionarray, array(
'__MYCOMPANY_NAME__' => $mysoc->name,
'__MYCOMPANY_EMAIL__' => $mysoc->email,
- '__MYCOMPANY_PHONE__' => dol_print_phone($mysoc->phone),
- '__MYCOMPANY_FAX__' => dol_print_phone($mysoc->fax),
+ '__MYCOMPANY_PHONE__' => dol_print_phone($mysoc->phone, '', 0, 0, '', " ", '', '', -1),
+ '__MYCOMPANY_FAX__' => dol_print_phone($mysoc->fax, '', 0, 0, '', " ", '', '', -1),
'__MYCOMPANY_PROFID1__' => $mysoc->idprof1,
'__MYCOMPANY_PROFID2__' => $mysoc->idprof2,
'__MYCOMPANY_PROFID3__' => $mysoc->idprof3,
@@ -9093,11 +9094,9 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1'
}
}
} catch (Error $e) {
- $error = 'Caught error : ';
- $error .= $e->getMessage() . ', ';
- $error .= 'Trace : ';
- $error .= json_encode($e->getTrace());
- error_log($error, 1);
+ $error = 'dol_eval try/catch error : ';
+ $error .= $e->getMessage();
+ dol_syslog($error);
}
}
@@ -9593,7 +9592,7 @@ function printCommonFooter($zone = 'private')
}
// Management of focus and mandatory for fields
- if ($action == 'create' || $action == 'edit' || (empty($action) && (preg_match('/new\.php/', $_SERVER["PHP_SELF"])))) {
+ if ($action == 'create' || $action == 'edit' || (empty($action) && (preg_match('/new\.php/', $_SERVER["PHP_SELF"]))) || ((empty($action) || $action == 'addline') && (preg_match('/card\.php/', $_SERVER["PHP_SELF"])))) {
print '/* JS CODE TO ENABLE to manage focus and mandatory form fields */'."\n";
$relativepathstring = $_SERVER["PHP_SELF"];
// Clean $relativepathstring
@@ -11584,15 +11583,34 @@ function jsonOrUnserialize($stringtodecode)
/**
- * Return if a $sqlfilters parameter is valid and will pass the preg_replace_callback() to replace Generic filter string with SQL filter string
- * Example of usage:
- * if ($sqlfilters) {
- * $errormessage = '';
- * if (dolCheckFilters($sqlfilters, $errormessage)) {
- * $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
- * $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'dolForgeCriteriaCallback', $sqlfilters).")";
- * }
- * }
+ * forgeSQLFromUniversalSearchCriteria
+ *
+ * @param string $filter String with universal search string
+ * @param string $error Error message
+ * @return string Return forged SQL string
+ */
+function forgeSQLFromUniversalSearchCriteria($filter, &$error = '')
+{
+ $regexstring = '\(([a-zA-Z0-9_\.]+:[<>!=insotlke]+:[^\(\)]+)\)'; // Must be (aaa:bbb:...) with aaa is a field name (with alias or not) and bbb is one of this operator '=', '<', '>', '<=', '>=', '!=', 'in', 'notin', 'like', 'notlike', 'is', 'isnot'
+
+ if (!dolCheckFilters($filter, $error)) {
+ return '1 = 2'; // Bad balance of parenthesis, we force a SQL not found
+ }
+
+ // Test the filter syntax
+ $t = preg_replace_callback('/'.$regexstring.'/i', 'dolForgeDummyCriteriaCallback', $filter);
+ $t = str_replace(array('and','or','AND','OR',' '), '', $t); // Remove the only strings allowed between each () criteria
+ // If the string result contains something else than '()', the syntax was wrong
+ if (preg_match('/[^\(\)]/', $t)) {
+ $error = 'Bad syntax of the search string, filter criteria is inhalited';
+ return '1 = 3'; // Bad syntax of the search string, we force a SQL not found
+ }
+
+ return " AND (".preg_replace_callback('/'.$regexstring.'/i', 'dolForgeCriteriaCallback', $filter).")";
+}
+
+/**
+ * Return if a $sqlfilters parameter has a valid balance of parenthesis
*
* @param string $sqlfilters sqlfilter string
* @param string $error Error message
@@ -11613,7 +11631,7 @@ function dolCheckFilters($sqlfilters, &$error = '')
$counter--;
}
if ($counter < 0) {
- $error = "Bad sqlfilters=".$sqlfilters;
+ $error = "Wrond balance of parenthesis in sqlfilters=".$sqlfilters;
dol_syslog($error, LOG_WARNING);
return false;
}
@@ -11623,57 +11641,92 @@ function dolCheckFilters($sqlfilters, &$error = '')
}
/**
- * Function to forge a SQL criteria from a Generic filter string.
- * Example of usage:
- * if ($sqlfilters) {
- * $errormessage = '';
- * if (dolCheckFilters($sqlfilters, $errormessage)) {
- * $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
- * $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'dolForgeCriteriaCallback', $sqlfilters).")";
- * }
- * }
+ * Function to forge a SQL criteria from a Dolibarr filter syntax string.
+ * This method is called by forgeSQLFromUniversalSearchCriteria()
*
- * @param array $matches Array of found string by regex search.
- * Example: "t.ref:like:'SO-%'" or "t.date_creation:<:'20160101'" or "t.date_creation:<:'2016-01-01 12:30:00'" or "t.nature:is:NULL"
- * @return string Forged criteria. Example: "t.field like 'abc%'"
+ * @param array $matches Array of found string by regex search. Example: "t.ref:like:'SO-%'" or "t.date_creation:<:'20160101'" or "t.nature:is:NULL"
+ * @return string Forged criteria. Example: "t.field like 'abc%'"
+ */
+function dolForgeDummyCriteriaCallback($matches)
+{
+ //dol_syslog("Convert matches ".$matches[1]);
+ if (empty($matches[1])) {
+ return '';
+ }
+ $tmp = explode(':', $matches[1]);
+ if (count($tmp) < 3) {
+ return '';
+ }
+
+ return '()'; // An empty criteria
+}
+
+/**
+ * Function to forge a SQL criteria from a Dolibarr filter syntax string.
+ * This method is called by forgeSQLFromUniversalSearchCriteria()
+ *
+ * @param array $matches Array of found string by regex search.
+ * Example: "t.ref:like:'SO-%'" or "t.date_creation:<:'20160101'" or "t.date_creation:<:'2016-01-01 12:30:00'" or "t.nature:is:NULL"
+ * @return string Forged criteria. Example: "t.field like 'abc%'"
*/
function dolForgeCriteriaCallback($matches)
{
global $db;
- dol_syslog("Convert matches ".$matches[1]);
+ //dol_syslog("Convert matches ".$matches[1]);
if (empty($matches[1])) {
return '';
}
- $tmp = explode(':', $matches[1], 3);
-
+ $tmp = explode(':', $matches[1]);
if (count($tmp) < 3) {
return '';
}
- $operand = preg_replace('/[^a-z0-9\._]/i', '', trim($tmp[0]));
-
$operator = strtoupper(preg_replace('/[^a-z<>=]/i', '', trim($tmp[1])));
if ($operator == 'NOTLIKE') {
$operator = 'NOT LIKE';
}
+ if ($operator == 'ISNOT') {
+ $operator = 'IS NOT';
+ }
+ if ($operator == '!=') {
+ $operator = '<>';
+ }
- $tmpescaped = trim($tmp[2]);
+ $tmpescaped = $tmp[2];
$regbis = array();
- if ($operator == 'IN') {
- $tmpescaped = "(".$db->sanitize($tmpescaped, 1).")";
+
+ if ($operator == 'IN') { // IN is allowed for list of ID or code only
+ //if (!preg_match('/^\(.*\)$/', $tmpescaped)) {
+ $tmpescaped = '('.$db->escape($db->sanitize($tmpescaped, 1, 0)).')';
+ //} else {
+ // $tmpescaped = $db->escape($db->sanitize($tmpescaped, 1));
+ //}
+ } elseif ($operator == 'LIKE' || $operator == 'NOT LIKE') {
+ if (preg_match('/^\'(.*)\'$/', $tmpescaped, $regbis)) {
+ $tmpescaped = $regbis[1];
+ }
+ //$tmpescaped = "'".$db->escapeforlike($db->escape($regbis[1]))."'";
+ $tmpescaped = "'".$db->escape($tmpescaped)."'"; // We do not escape the _ and % so the like will works
} elseif (preg_match('/^\'(.*)\'$/', $tmpescaped, $regbis)) {
$tmpescaped = "'".$db->escape($regbis[1])."'";
} else {
- $tmpescaped = $db->sanitize($db->escape($tmpescaped));
+ if (strtoupper($tmpescaped) == 'NULL') {
+ $tmpescaped = 'NULL';
+ } elseif (is_int($tmpescaped)) {
+ $tmpescaped = (int) $tmpescaped;
+ } else {
+ $tmpescaped = (float) $tmpescaped;
+ }
}
- return $db->escape($operand).' '.$db->escape($operator)." ".$tmpescaped;
+ return $db->escape($tmp[0]).' '.strtoupper($operator).' '.$tmpescaped;
}
/**
* Get timeline icon
+ *
* @param ActionComm $actionstatic actioncomm
* @param array $histo histo
* @param int $key key
diff --git a/htdocs/core/lib/memory.lib.php b/htdocs/core/lib/memory.lib.php
index 5c4826a2dc5..3be5e902816 100644
--- a/htdocs/core/lib/memory.lib.php
+++ b/htdocs/core/lib/memory.lib.php
@@ -57,7 +57,7 @@ $shmoffset = 1000; // Max number of entries found into a language file. If too l
/**
- * Save data into a memory area shared by all users, all sessions on server
+ * Save data into a memory area shared by all users, all sessions on server. Note: MAIN_CACHE_COUNT must be set.
*
* @param string $memoryid Memory id of shared area
* @param mixed $data Data to save. It must not be a null value.
diff --git a/htdocs/core/lib/payments.lib.php b/htdocs/core/lib/payments.lib.php
index 29947dda57c..3dfccc88ea5 100644
--- a/htdocs/core/lib/payments.lib.php
+++ b/htdocs/core/lib/payments.lib.php
@@ -250,7 +250,9 @@ function getOnlinePaymentUrl($mode, $type, $ref = '', $amount = '9.99', $freetag
$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
- $urltouse = DOL_MAIN_URL_ROOT;
+ $urltouse = DOL_MAIN_URL_ROOT; // Should be "https://www.mydomain.com/mydolibarr" for example
+ //dol_syslog("getOnlinePaymentUrl DOL_MAIN_URL_ROOT=".DOL_MAIN_URL_ROOT);
+
if ($localorexternal) {
$urltouse = $urlwithroot;
}
diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php
index 4d9569a1cc4..7a5848adaf3 100644
--- a/htdocs/core/lib/pdf.lib.php
+++ b/htdocs/core/lib/pdf.lib.php
@@ -13,6 +13,7 @@
* Copyright (C) 2019 Lenin Rivas
* Copyright (C) 2020 Nicolas ZABOURI
* Copyright (C) 2021-2022 Anthony Berton
+ * Copyright (C) 2023 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1287,11 +1288,14 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_
}
}
// Show page nb only on iso languages (so default Helvetica font)
- if (strtolower(pdf_getPDFFont($outputlangs)) == 'helvetica') {
+ // if (strtolower(pdf_getPDFFont($outputlangs)) == 'helvetica') {
$pdf->SetXY($dims['wk'] - $dims['rm'] - 18, -$posy);
- //$pdf->MultiCell(18, 2, $pdf->getPageNumGroupAlias().' / '.$pdf->getPageGroupAlias(), 0, 'R', 0);
- $pdf->MultiCell(18, 2, $pdf->PageNo().' / '.$pdf->getAliasNbPages(), 0, 'R', 0);
- }
+ // $pdf->MultiCell(18, 2, $pdf->getPageNumGroupAlias().' / '.$pdf->getPageGroupAlias(), 0, 'R', 0);
+ // $pdf->MultiCell(18, 2, $pdf->PageNo().' / '.$pdf->getAliasNbPages(), 0, 'R', 0); // doesn't works with all fonts
+ // $pagination = $pdf->getAliasNumPage().' / '.$pdf->getAliasNbPages(); // works with $pdf->Cell
+ $pagination = $pdf->PageNo().' / '.$pdf->getNumPages();
+ $pdf->MultiCell(18, 2, $pagination, 0, 'R', 0);
+ // }
// Show Draft Watermark
if (!empty($watermark)) {
@@ -2471,10 +2475,12 @@ function pdf_getLinkedObjects(&$object, $outputlangs)
$linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefSending");
if (!empty($linkedobjects[$objecttype]['ref_value'])) $linkedobjects[$objecttype]['ref_value'] .= ' / ';
$linkedobjects[$objecttype]['ref_value'] .= $outputlangs->transnoentities($elementobject->ref);
+ $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
} else {
$linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending");
if (empty($linkedobjects[$objecttype]['ref_value'])) $linkedobjects[$objecttype]['ref_value'] = $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : '');
$linkedobjects[$objecttype]['ref_value'] .= ' / '.$outputlangs->transnoentities($elementobject->ref);
+ $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
}
}
}
@@ -2508,6 +2514,8 @@ function pdf_getSizeForImage($realpath)
$maxheight = (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_HEIGHT) ? 32 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_HEIGHT);
include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
$tmp = dol_getImageSize($realpath);
+ $width = 0;
+ $height = 0;
if ($tmp['height']) {
$width = (int) round($maxheight * $tmp['width'] / $tmp['height']); // I try to use maxheight
if ($width > $maxwidth) { // Pb with maxheight, so i use maxwidth
diff --git a/htdocs/core/lib/propal.lib.php b/htdocs/core/lib/propal.lib.php
index b5e459c8637..588418c7449 100644
--- a/htdocs/core/lib/propal.lib.php
+++ b/htdocs/core/lib/propal.lib.php
@@ -105,9 +105,39 @@ function propal_prepare_head($object)
$head[$h][2] = 'document';
$h++;
- $head[$h][0] = DOL_URL_ROOT.'/comm/propal/info.php?id='.$object->id;
- $head[$h][1] = $langs->trans('Info');
- $head[$h][2] = 'info';
+
+ $head[$h][0] = DOL_URL_ROOT.'/comm/propal/agenda.php?id='.$object->id;
+ $head[$h][1] = $langs->trans("Events");
+ if (isModEnabled('agenda')&& (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
+ $nbEvent = 0;
+ // Enable caching of thirdparty count actioncomm
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php';
+ $cachekey = 'count_events_propal_'.$object->id;
+ $dataretrieved = dol_getcache($cachekey);
+ if (!is_null($dataretrieved)) {
+ $nbEvent = $dataretrieved;
+ } else {
+ $sql = "SELECT COUNT(id) as nb";
+ $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm";
+ $sql .= " WHERE fk_element = ".((int) $object->id);
+ $sql .= " AND elementtype = 'propal'";
+ $resql = $db->query($sql);
+ if ($resql) {
+ $obj = $db->fetch_object($resql);
+ $nbEvent = $obj->nb;
+ } else {
+ dol_syslog('Failed to count actioncomm '.$db->lasterror(), LOG_ERR);
+ }
+ dol_setcache($cachekey, $nbEvent, 120); // If setting cache fails, this is not a problem, so we do not test result.
+ }
+
+ $head[$h][1] .= '/';
+ $head[$h][1] .= $langs->trans("Agenda");
+ if ($nbEvent > 0) {
+ $head[$h][1] .= ''.$nbEvent.' ';
+ }
+ }
+ $head[$h][2] = 'agenda';
$h++;
complete_head_from_modules($conf, $langs, $object, $head, $h, 'propal', 'add', 'external');
diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php
index 273e7285273..64747c1bbf6 100644
--- a/htdocs/core/lib/usergroups.lib.php
+++ b/htdocs/core/lib/usergroups.lib.php
@@ -366,7 +366,7 @@ function showSkins($fuser, $edit = 0, $foruserprofile = false)
print '';
print ''.$langs->trans("DefaultSkin").' ';
print ''.$conf->global->MAIN_THEME.' ';
- print ' '.$langs->trans("UsePersonalValue").' ';
+ print ' '.$langs->trans("UsePersonalValue").' ';
print ' ';
print ' ';
} else {
diff --git a/htdocs/core/menus/standard/auguria_menu.php b/htdocs/core/menus/standard/auguria_menu.php
index ae40ec170fc..168effd964d 100644
--- a/htdocs/core/menus/standard/auguria_menu.php
+++ b/htdocs/core/menus/standard/auguria_menu.php
@@ -37,6 +37,11 @@ class MenuManager
public $atarget = ""; // To store default target to use onto links
public $name = "auguria";
+ /**
+ * @var Menu
+ */
+ public $menu;
+
public $menu_array;
public $menu_array_after;
diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php
index 19136ba492f..59c49f7fc7f 100644
--- a/htdocs/core/menus/standard/eldy.lib.php
+++ b/htdocs/core/menus/standard/eldy.lib.php
@@ -1683,7 +1683,7 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef
// Multi journal
$sql = "SELECT rowid, code, label, nature";
$sql .= " FROM ".MAIN_DB_PREFIX."accounting_journal";
- $sql .= " WHERE entity = ".$conf->entity;
+ $sql .= " WHERE entity = ".((int) $conf->entity);
$sql .= " AND active = 1";
$sql .= " ORDER BY nature ASC, label DESC";
@@ -1734,11 +1734,12 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef
$langs->load('accountancy');
$journallabel = '';
if ($objp->label) {
+ $journallabelwithoutspan = $langs->transnoentities($objp->label);
$journallabel = '('.$langs->transnoentities($objp->label).') '; // Label of bank account in llx_accounting_journal
}
- $key = $langs->trans("AccountingJournalType".strtoupper($objp->nature));
- $transferlabel = ($objp->nature && $key != "AccountingJournalType".strtoupper($langs->trans($objp->nature)) ? $key.($journallabel != $key ? ' '.$journallabel : ''): $journallabel);
+ $key = $langs->trans("AccountingJournalType".$objp->nature); // $objp->nature is 1, 2, 3 ...
+ $transferlabel = (($objp->nature && $key != "AccountingJournalType".$objp->nature) ? $key.($journallabelwithoutspan != $key ? ' '.$journallabel : ''): $journallabel);
$newmenu->add('/accountancy/journal/'.$nature.'journal.php?mainmenu=accountancy&leftmenu=accountancy_journal&id_journal='.$objp->rowid, $transferlabel, 2, $user->hasRight('accounting', 'comptarapport', 'lire'));
}
diff --git a/htdocs/core/menus/standard/eldy_menu.php b/htdocs/core/menus/standard/eldy_menu.php
index 596e1e4cc3f..de33b209383 100644
--- a/htdocs/core/menus/standard/eldy_menu.php
+++ b/htdocs/core/menus/standard/eldy_menu.php
@@ -36,6 +36,11 @@ class MenuManager
public $atarget = ""; // To store default target to use onto links
public $name = "eldy";
+ /**
+ * @var Menu
+ */
+ public $menu;
+
public $menu_array;
public $menu_array_after;
diff --git a/htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php b/htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php
index 92af12427b2..afa3b56b4f5 100644
--- a/htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php
+++ b/htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php
@@ -689,7 +689,8 @@ class pdf_standard_asset extends ModelePDFAsset
$localtax1_type = $object->lines[$i]->localtax1_type;
$localtax2_type = $object->lines[$i]->localtax2_type;
- if ($object->remise_percent) {
+ // TODO remise_percent is an obsolete field for object parent
+ /*if ($object->remise_percent) {
$tvaligne -= ($tvaligne * $object->remise_percent) / 100;
}
if ($object->remise_percent) {
@@ -697,7 +698,7 @@ class pdf_standard_asset extends ModelePDFAsset
}
if ($object->remise_percent) {
$localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
- }
+ }*/
$vatrate = (string) $object->lines[$i]->tva_tx;
diff --git a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
index 533619ed055..1cf3864d333 100644
--- a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
+++ b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
@@ -542,7 +542,8 @@ class pdf_einstein extends ModelePDFCommandes
$localtax1_type = $object->lines[$i]->localtax1_type;
$localtax2_type = $object->lines[$i]->localtax2_type;
- if ($object->remise_percent) {
+ // TODO remise_percent is an obsolete field for object parent
+ /*if ($object->remise_percent) {
$tvaligne -= ($tvaligne * $object->remise_percent) / 100;
}
if ($object->remise_percent) {
@@ -550,7 +551,7 @@ class pdf_einstein extends ModelePDFCommandes
}
if ($object->remise_percent) {
$localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
- }
+ }*/
$vatrate = (string) $object->lines[$i]->tva_tx;
diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
index bae583ccf4c..78b3fa24a33 100644
--- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
+++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
@@ -767,7 +767,8 @@ class pdf_eratosthene extends ModelePDFCommandes
$localtax1_type = $object->lines[$i]->localtax1_type;
$localtax2_type = $object->lines[$i]->localtax2_type;
- if ($object->remise_percent) {
+ // TODO remise_percent is an obsolete field for object parent
+ /*if ($object->remise_percent) {
$tvaligne -= ($tvaligne * $object->remise_percent) / 100;
}
if ($object->remise_percent) {
@@ -775,7 +776,7 @@ class pdf_eratosthene extends ModelePDFCommandes
}
if ($object->remise_percent) {
$localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
- }
+ }*/
$vatrate = (string) $object->lines[$i]->tva_tx;
diff --git a/htdocs/core/modules/contract/doc/pdf_strato.modules.php b/htdocs/core/modules/contract/doc/pdf_strato.modules.php
index 69b7f193a70..59a4a549242 100644
--- a/htdocs/core/modules/contract/doc/pdf_strato.modules.php
+++ b/htdocs/core/modules/contract/doc/pdf_strato.modules.php
@@ -45,6 +45,11 @@ class pdf_strato extends ModelePDFContract
*/
public $db;
+ /**
+ * @var int The environment ID when using a multicompany module
+ */
+ public $entity;
+
/**
* @var string model name
*/
@@ -114,7 +119,7 @@ class pdf_strato extends ModelePDFContract
/**
* Issuer
- * @var Societe
+ * @var Societe Object that emits
*/
public $emetteur;
@@ -138,7 +143,7 @@ class pdf_strato extends ModelePDFContract
$this->description = $langs->trans("StandardContractsTemplate");
$this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
- // Page size for A4 format
+ // Dimension page
$this->type = 'pdf';
$formatarray = pdf_getFormat();
@@ -160,7 +165,7 @@ class pdf_strato extends ModelePDFContract
// Get source company
$this->emetteur = $mysoc;
if (empty($this->emetteur->country_code)) {
- $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if not defined
+ $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
}
// Define position of columns
@@ -182,7 +187,7 @@ class pdf_strato extends ModelePDFContract
public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
{
// phpcs:enable
- global $user, $langs, $conf, $hookmanager, $mysoc;
+ global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblines;
if (!is_object($outputlangs)) {
$outputlangs = $langs;
@@ -192,15 +197,30 @@ class pdf_strato extends ModelePDFContract
$outputlangs->charset_output = 'ISO-8859-1';
}
- // Load traductions files required by page
+ // Load translation files required by page
$outputlangs->loadLangs(array("main", "dict", "companies", "contracts"));
- if ($conf->contrat->dir_output) {
+ // Show Draft Watermark
+ if ($object->statut == $object::STATUS_DRAFT && (!empty($conf->global->CONTRACT_DRAFT_WATERMARK))) {
+ $this->watermark = $conf->global->CONTRACT_DRAFT_WATERMARK;
+ }
+
+ global $outputlangsbis;
+ $outputlangsbis = null;
+ if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
+ $outputlangsbis = new Translate('', $conf);
+ $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
+ $outputlangsbis->loadLangs(array("main", "dict", "companies", "bills", "products", "orders", "deliveries"));
+ }
+
+ $nblines = count($object->lines);
+
+ if ($conf->contract->multidir_output[$conf->entity]) {
$object->fetch_thirdparty();
// Definition of $dir and $file
if ($object->specimen) {
- $dir = $conf->contrat->dir_output;
+ $dir = $conf->contract->multidir_output[$conf->entity];
$file = $dir."/SPECIMEN.pdf";
} else {
$objectref = dol_sanitizeFileName($object->ref);
@@ -210,7 +230,7 @@ class pdf_strato extends ModelePDFContract
if (!file_exists($dir)) {
if (dol_mkdir($dir) < 0) {
- $this->error = $outputlangs->trans("ErrorCanNotCreateDir", $dir);
+ $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
return 0;
}
}
@@ -226,15 +246,20 @@ class pdf_strato extends ModelePDFContract
global $action;
$reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
+ // Set nblines with the new command lines content after hook
+ $nblines = count($object->lines);
+
+ // Create pdf instance
$pdf = pdf_getInstance($this->format);
$default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
+ $pdf->SetAutoPageBreak(1, 0);
+
$heightforinfotot = 50; // Height reserved to output the info and total part
$heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page
$heightforfooter = $this->marge_basse + 9; // Height reserved to output the footer (value include bottom margin)
if (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)) {
$heightforfooter += 6;
}
- $pdf->SetAutoPageBreak(1, 0);
if (class_exists('TCPDF')) {
$pdf->setPrintHeader(false);
@@ -243,7 +268,11 @@ class pdf_strato extends ModelePDFContract
$pdf->SetFont(pdf_getPDFFont($outputlangs));
// Set path to the background PDF File
if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) {
- $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
+ $logodir = $conf->mycompany->dir_output;
+ if (!empty($conf->mycompany->multidir_output[$object->entity])) {
+ $logodir = $conf->mycompany->multidir_output[$object->entity];
+ }
+ $pagecount = $pdf->setSourceFile($logodir.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
$tplidx = $pdf->importPage(1);
}
@@ -252,10 +281,10 @@ class pdf_strato extends ModelePDFContract
$pdf->SetDrawColor(128, 128, 128);
$pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
- $pdf->SetSubject($outputlangs->transnoentities("ContractCard"));
+ $pdf->SetSubject($outputlangs->transnoentities("Contract"));
$pdf->SetCreator("Dolibarr ".DOL_VERSION);
$pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
- $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("ContractCard")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
+ $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("Contract")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
$pdf->SetCompression(false);
}
@@ -268,7 +297,7 @@ class pdf_strato extends ModelePDFContract
$pdf->useTemplate($tplidx);
}
$pagenb++;
- $this->_pagehead($pdf, $object, 1, $outputlangs);
+ $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs, (is_object($outputlangsbis) ? $outputlangsbis : null));
$pdf->SetFont('', '', $default_font_size - 1);
$pdf->MultiCell(0, 3, ''); // Set interline to 3
$pdf->SetTextColor(0, 0, 0);
@@ -408,6 +437,7 @@ class pdf_strato extends ModelePDFContract
{
$pdf->commitTransaction();
}
+ $posYAfterDescription = $pdf->GetY();
$nexY = $pdf->GetY() + 2;
$pageposafter = $pdf->getPage();
@@ -417,7 +447,7 @@ class pdf_strato extends ModelePDFContract
$pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
// We suppose that a too long description is moved completely on next page
- if ($pageposafter > $pageposbefore) {
+ if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
$pdf->setPage($pageposafter);
$curY = $tab_top_newpage;
}
@@ -483,10 +513,6 @@ class pdf_strato extends ModelePDFContract
$pdf->Output($file, 'F');
// Add pdfgeneration hook
- if (!is_object($hookmanager)) {
- include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
- $hookmanager = new HookManager($this->db);
- }
$hookmanager->initHooks(array('pdfgeneration'));
$parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
global $action;
@@ -500,13 +526,13 @@ class pdf_strato extends ModelePDFContract
$this->result = array('fullpath'=>$file);
- return 1;
+ return 1; // No error
} else {
- $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
+ $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
return 0;
}
} else {
- $this->error = $langs->trans("ErrorConstantNotDefined", "CONTRACT_OUTPUTDIR");
+ $this->error = $langs->transnoentities("ErrorConstantNotDefined", "CONTRACT_OUTPUTDIR");
return 0;
}
}
@@ -534,7 +560,9 @@ class pdf_strato extends ModelePDFContract
$hidetop = -1;
}
+ $currency = !empty($currency) ? $currency : $conf->currency;
$default_font_size = pdf_getPDFFontSize($outputlangs);
+
/*
$pdf->SetXY($this->marge_gauche, $tab_top);
$pdf->MultiCell(190,8,$outputlangs->transnoentities("Description"),0,'L',0);
@@ -600,76 +628,97 @@ class pdf_strato extends ModelePDFContract
* @param Contrat $object Object to show
* @param int $showaddress 0=no, 1=yes
* @param Translate $outputlangs Object lang for output
- * @return void
+ * @param Translate $outputlangsbis Object lang for output bis
+ * @param string $titlekey Translation key to show as title of document
+ * @return int Return topshift value
*/
- protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
+ protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null, $titlekey = "Contract")
{
- global $conf, $langs;
+ // phpcs:enable
+ global $conf, $langs, $hookmanager;
- $default_font_size = pdf_getPDFFontSize($outputlangs);
+ $ltrdirection = 'L';
+ if ($outputlangs->trans("DIRECTION") == 'rtl') {
+ $ltrdirection = 'R';
+ }
// Load traductions files required by page
$outputlangs->loadLangs(array("main", "dict", "contract", "companies"));
+ $default_font_size = pdf_getPDFFontSize($outputlangs);
+
pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
- //Affiche le filigrane brouillon - Print Draft Watermark
- if ($object->statut == 0 && (!empty($conf->global->CONTRACT_DRAFT_WATERMARK))) {
- pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->CONTRACT_DRAFT_WATERMARK);
- }
-
- //Prepare next
$pdf->SetTextColor(0, 0, 60);
$pdf->SetFont('', 'B', $default_font_size + 3);
- $posx = $this->page_largeur - $this->marge_droite - 100;
+ $w = 100;
+
$posy = $this->marge_haute;
+ $posx = $this->page_largeur - $this->marge_droite - $w;
$pdf->SetXY($this->marge_gauche, $posy);
// Logo
- $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
- if ($this->emetteur->logo) {
- if (is_readable($logo)) {
- $height = pdf_getHeightForLogo($logo);
- $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
+ if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) {
+ if ($this->emetteur->logo) {
+ $logodir = $conf->mycompany->dir_output;
+ if (!empty($conf->mycompany->multidir_output[$object->entity])) {
+ $logodir = $conf->mycompany->multidir_output[$object->entity];
+ }
+ if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) {
+ $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small;
+ } else {
+ $logo = $logodir.'/logos/'.$this->emetteur->logo;
+ }
+ if (is_readable($logo)) {
+ $height = pdf_getHeightForLogo($logo);
+ $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
+ } else {
+ $pdf->SetTextColor(200, 0, 0);
+ $pdf->SetFont('', 'B', $default_font_size - 2);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
+ }
} else {
- $pdf->SetTextColor(200, 0, 0);
- $pdf->SetFont('', 'B', $default_font_size - 2);
- $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
- $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
+ $text = $this->emetteur->name;
+ $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection);
}
- } else {
- $text = $this->emetteur->name;
- $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
}
$pdf->SetFont('', 'B', $default_font_size + 3);
$pdf->SetXY($posx, $posy);
$pdf->SetTextColor(0, 0, 60);
- $title = $outputlangs->transnoentities("ContractCard");
- $pdf->MultiCell(100, 4, $title, '', 'R');
+ $title = $outputlangs->transnoentities($titlekey);
+ $title .= ' '.$outputlangs->convToOutputCharset($object->ref);
+ if ($object->statut == $object::STATUS_DRAFT) {
+ $pdf->SetTextColor(128, 0, 0);
+ $title .= ' - '.$outputlangs->transnoentities("NotValidated");
+ }
+ $pdf->MultiCell($w, 3, $title, '', 'R');
- $pdf->SetFont('', 'B', $default_font_size + 2);
+ $pdf->SetFont('', 'B', $default_font_size);
+ /*
$posy += 5;
$pdf->SetXY($posx, $posy);
$pdf->SetTextColor(0, 0, 60);
$pdf->MultiCell(100, 4, $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref), '', 'R');
+ */
- $posy += 1;
- $pdf->SetFont('', '', $default_font_size);
+ $posy += 3;
+ $pdf->SetFont('', '', $default_font_size - 1);
$posy += 4;
$pdf->SetXY($posx, $posy);
$pdf->SetTextColor(0, 0, 60);
- $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Date")." : ".dol_print_date($object->date_contrat, "day", false, $outputlangs, true), '', 'R');
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Date")." : ".dol_print_date($object->date_contrat, "day", false, $outputlangs, true), '', 'R');
if (empty($conf->global->MAIN_PDF_HIDE_CUSTOMER_CODE) && $object->thirdparty->code_client) {
$posy += 4;
$pdf->SetXY($posx, $posy);
$pdf->SetTextColor(0, 0, 60);
- $pdf->MultiCell(100, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
}
if ($showaddress) {
@@ -700,6 +749,7 @@ class pdf_strato extends ModelePDFContract
$pdf->SetXY($posx, $posy);
$pdf->SetFillColor(230, 230, 230);
$pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1);
+ $pdf->SetTextColor(0, 0, 60);
}
// Show sender name
@@ -707,13 +757,13 @@ class pdf_strato extends ModelePDFContract
$pdf->SetXY($posx + 2, $posy + 3);
$pdf->SetTextColor(0, 0, 60);
$pdf->SetFont('', 'B', $default_font_size);
- $pdf->MultiCell(80, 3, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
+ $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
$posy = $pdf->getY();
}
// Show sender information
- $pdf->SetFont('', '', $default_font_size - 1);
$pdf->SetXY($posx + 2, $posy);
+ $pdf->SetFont('', '', $default_font_size - 1);
$pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L');
@@ -736,14 +786,16 @@ class pdf_strato extends ModelePDFContract
$this->recipient->name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
- $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, (isset($object->contact) ? $object->contact : ''), $usecontact, 'target', $object);
+ $mode = 'target';
+ $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, (isset($object->contact) ? $object->contact : ''), $usecontact, $mode, $object);
// Show recipient
- $widthrecbox = 100;
+ $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100;
if ($this->page_largeur < 210) {
$widthrecbox = 84; // To work with US executive format
}
- $posy = 42;
+ $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
+ $posy += $top_shift;
$posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) {
$posx = $this->marge_gauche;
@@ -761,15 +813,18 @@ class pdf_strato extends ModelePDFContract
// Show recipient name
$pdf->SetXY($posx + 2, $posy + 3);
$pdf->SetFont('', 'B', $default_font_size);
- $pdf->MultiCell($widthrecbox, 4, $this->recipient->name, 0, 'L');
+ $pdf->MultiCell($widthrecbox, 4, $this->recipient->name, 0, $ltrdirection);
$posy = $pdf->getY();
// Show recipient information
$pdf->SetFont('', '', $default_font_size - 1);
$pdf->SetXY($posx + 2, $posy);
- $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L');
+ $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, $ltrdirection);
}
+
+ $pdf->SetTextColor(0, 0, 0);
+ return $top_shift;
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
@@ -785,6 +840,6 @@ class pdf_strato extends ModelePDFContract
protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
{
$showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
- return pdf_pagefoot($pdf, $outputlangs, 'CONTRACT_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
+ return pdf_pagefoot($pdf, $outputlangs, 'CONTRACT_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext, $this->page_largeur, $this->watermark);
}
}
diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
index 207514ca195..174648dfa8c 100644
--- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
+++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
@@ -761,7 +761,8 @@ class pdf_crabe extends ModelePDFFactures
$localtax1_type = $object->lines[$i]->localtax1_type;
$localtax2_type = $object->lines[$i]->localtax2_type;
- if ($object->remise_percent) {
+ // TODO remise_percent is an obsolete field for object parent
+ /*if ($object->remise_percent) {
$tvaligne -= ($tvaligne * $object->remise_percent) / 100;
}
if ($object->remise_percent) {
@@ -769,7 +770,7 @@ class pdf_crabe extends ModelePDFFactures
}
if ($object->remise_percent) {
$localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
- }
+ }*/
$vatrate = (string) $object->lines[$i]->tva_tx;
@@ -1232,7 +1233,7 @@ class pdf_crabe extends ModelePDFFactures
$bac = new CompanyBankAccount($this->db);
$bac->fetch(0, $object->thirdparty->id);
$iban= $bac->iban.(($bac->iban && $bac->bic) ? ' / ' : '').$bac->bic;
- $lib_mode_reg .= $outputlangs->trans("PaymentTypePREdetails", dol_trunc($iban, 6, 'right', 'UTF-8', 1));
+ $lib_mode_reg .= ' '.$outputlangs->trans("PaymentTypePREdetails", dol_trunc($iban, 6, 'right', 'UTF-8', 1));
}
$pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
index 98c2e4552bc..312115bb0c1 100644
--- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
+++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
@@ -925,7 +925,8 @@ class pdf_sponge extends ModelePDFFactures
$localtax1_type = $object->lines[$i]->localtax1_type;
$localtax2_type = $object->lines[$i]->localtax2_type;
- if ($object->remise_percent) {
+ // TODO remise_percent is an obsolete field for object parent
+ /*if ($object->remise_percent) {
$tvaligne -= ($tvaligne * $object->remise_percent) / 100;
}
if ($object->remise_percent) {
@@ -933,7 +934,7 @@ class pdf_sponge extends ModelePDFFactures
}
if ($object->remise_percent) {
$localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
- }
+ }*/
$vatrate = (string) $object->lines[$i]->tva_tx;
@@ -1325,7 +1326,7 @@ class pdf_sponge extends ModelePDFFactures
$bac = new CompanyBankAccount($this->db);
$bac->fetch(0, $object->thirdparty->id);
$iban= $bac->iban.(($bac->iban && $bac->bic) ? ' / ' : '').$bac->bic;
- $lib_mode_reg .= $outputlangs->trans("PaymentTypePREdetails", dol_trunc($iban, 6, 'right', 'UTF-8', 1));
+ $lib_mode_reg .= ' '.$outputlangs->trans("PaymentTypePREdetails", dol_trunc($iban, 6, 'right', 'UTF-8', 1));
}
$pdf->MultiCell($posxend - $posxval, 5, $lib_mode_reg, 0, 'L');
diff --git a/htdocs/core/modules/facture/mod_facture_mercure.php b/htdocs/core/modules/facture/mod_facture_mercure.php
index 36d64132e40..27d84246a2d 100644
--- a/htdocs/core/modules/facture/mod_facture_mercure.php
+++ b/htdocs/core/modules/facture/mod_facture_mercure.php
@@ -53,7 +53,7 @@ class mod_facture_mercure extends ModeleNumRefFactures
*/
public function info()
{
- global $db, $conf, $langs;
+ global $db, $langs;
$langs->load("bills");
@@ -137,35 +137,20 @@ class mod_facture_mercure extends ModeleNumRefFactures
*/
public function getNextValue($objsoc, $invoice, $mode = 'next')
{
- global $db, $conf;
+ global $db;
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
// Get Mask value
$mask = '';
if (is_object($invoice) && $invoice->type == 1) {
- if (isset($conf->global->FACTURE_MERCURE_MASK_REPLACEMENT)) {
- $mask = $conf->global->FACTURE_MERCURE_MASK_REPLACEMENT;
- }
- if (!$mask) {
- if (isset($conf->global->FACTURE_MERCURE_MASK_INVOICE)) {
- $mask = $conf->global->FACTURE_MERCURE_MASK_INVOICE;
- }
- }
+ $mask = getDolGlobalString('FACTURE_MERCURE_MASK_REPLACEMENT', getDolGlobalString('FACTURE_MERCURE_MASK_INVOICE'));
} elseif (is_object($invoice) && $invoice->type == 2) {
- if (isset($conf->global->FACTURE_MERCURE_MASK_CREDIT)) {
- $mask = $conf->global->FACTURE_MERCURE_MASK_CREDIT;
- }
+ $mask = getDolGlobalString('FACTURE_MERCURE_MASK_CREDIT');
} elseif (is_object($invoice) && $invoice->type == 3) {
- if (isset($conf->global->FACTURE_MERCURE_MASK_DEPOSIT)) {
- $mask = $conf->global->FACTURE_MERCURE_MASK_DEPOSIT;
- }
+ $mask = getDolGlobalString('FACTURE_MERCURE_MASK_DEPOSIT');
} else {
- if (isset($conf->global->FACTURE_MERCURE_MASK_INVOICE)) {
- $mask = $conf->global->FACTURE_MERCURE_MASK_INVOICE;
- } else {
- $mask = '';
- }
+ $mask = getDolGlobalString('FACTURE_MERCURE_MASK_INVOICE');
}
if (!$mask) {
$this->error = 'NotConfigured';
diff --git a/htdocs/core/modules/mailings/fraise.modules.php b/htdocs/core/modules/mailings/fraise.modules.php
index 9fe6a615f5d..8d55ac65864 100644
--- a/htdocs/core/modules/mailings/fraise.modules.php
+++ b/htdocs/core/modules/mailings/fraise.modules.php
@@ -201,11 +201,11 @@ class mailing_fraise extends MailingTargets
$s .= '';
- $s .= ' ';
+ $s .= '';
$s .= $langs->trans("DateEndSubscription").': ';
- $s .= $langs->trans("After").' > '.$form->selectDate(-1, 'subscriptionafter', 0, 0, 1, 'fraise', 1, 0, 0);
+ $s .= $langs->trans("After").' > '.$form->selectDate(-1, 'subscriptionafter', 0, 0, 1, 'fraise', 1, 0, 0);
$s .= ' ';
- $s .= $langs->trans("Before").' < '.$form->selectDate(-1, 'subscriptionbefore', 0, 0, 1, 'fraise', 1, 0, 0);
+ $s .= ''.$langs->trans("Before").' < '.$form->selectDate(-1, 'subscriptionbefore', 0, 0, 1, 'fraise', 1, 0, 0);
return $s;
}
diff --git a/htdocs/core/modules/mailings/modules_mailings.php b/htdocs/core/modules/mailings/modules_mailings.php
index 2064613d1e9..b745934d94d 100644
--- a/htdocs/core/modules/mailings/modules_mailings.php
+++ b/htdocs/core/modules/mailings/modules_mailings.php
@@ -48,6 +48,11 @@ class MailingTargets // This can't be abstract as it is used for some method
public $tooltip = '';
+ /**
+ * @var string The SQL string used to find the recipients
+ */
+ public $sql;
+
/**
* Constructor
diff --git a/htdocs/core/modules/mailings/pomme.modules.php b/htdocs/core/modules/mailings/pomme.modules.php
index 7fdcdeb0c60..907028ca881 100644
--- a/htdocs/core/modules/mailings/pomme.modules.php
+++ b/htdocs/core/modules/mailings/pomme.modules.php
@@ -118,7 +118,7 @@ class mailing_pomme extends MailingTargets
$langs->load("users");
$s = '';
- $s .= '';
+ $s .= '';
$s .= ''.$langs->trans("Status").' ';
$s .= ''.$langs->trans("Enabled").' ';
$s .= ''.$langs->trans("Disabled").' ';
@@ -126,7 +126,7 @@ class mailing_pomme extends MailingTargets
$s .= ajax_combobox("filter_pomme");
$s .= ' ';
- $s .= '';
+ $s .= '';
$s .= ''.$langs->trans("Employee").' ';
$s .= ''.$langs->trans("Yes").' ';
$s .= ''.$langs->trans("No").' ';
diff --git a/htdocs/core/modules/mailings/thirdparties.modules.php b/htdocs/core/modules/mailings/thirdparties.modules.php
index 2f8040d4b75..fd91e5e849f 100644
--- a/htdocs/core/modules/mailings/thirdparties.modules.php
+++ b/htdocs/core/modules/mailings/thirdparties.modules.php
@@ -73,55 +73,77 @@ class mailing_thirdparties extends MailingTargets
$cibles = array();
$addDescription = "";
+ $addFilter = "";
+ if (GETPOSTISSET("filter_client_thirdparties") && GETPOST("filter_client_thirdparties") <> '-1') {
+ $addFilter .= " AND s.client=".((int) GETPOST("filter_client_thirdparties", 'int'));
+ $addDescription = $langs->trans('ProspectCustomer')."=";
+ if (GETPOST("filter_client_thirdparties") == 0) {
+ $addDescription .= $langs->trans('NorProspectNorCustomer');
+ } elseif (GETPOST("filter_client_thirdparties") == 1) {
+ $addDescription .= $langs->trans('Customer');
+ } elseif (GETPOST("filter_client_thirdparties") == 2) {
+ $addDescription .= $langs->trans('Prospect');
+ } elseif (GETPOST("filter_client_thirdparties") == 3) {
+ $addDescription .= $langs->trans('ProspectCustomer');
+ } else {
+ $addDescription .= "Unknown status ".GETPOST("filter_client_thirdparties");
+ }
+ }
+ if (GETPOSTISSET("filter_supplier_thirdparties") && GETPOST("filter_supplier_thirdparties") <> '-1') {
+ $addFilter .= " AND s.fournisseur = ".((int) GETPOST("filter_supplier_thirdparties", 'int'));
+ $addDescription = $langs->trans('Supplier')."=";
+ if (GETPOST("filter_supplier_thirdparties") == 0) {
+ $addDescription .= $langs->trans('No');
+ } elseif (GETPOST("filter_supplier_thirdparties") == 1) {
+ $addDescription .= $langs->trans('Yes');
+ } else {
+ $addDescription .= "Unknown status ".GETPOST("filter_supplier_thirdparties");
+ }
+ }
+ if (GETPOSTISSET("filter_status")) {
+ if (strlen($addDescription) > 0) {
+ $addDescription .= ";";
+ }
+ $addDescription .= $langs->trans("Status")."=";
+ if (GETPOST("filter_status") == '1') {
+ $addFilter .= " AND s.status=1";
+ $addDescription .= $langs->trans("Enabled");
+ } elseif (GETPOST("filter_status") == '0') {
+ $addFilter .= " AND s.status=0";
+ $addDescription .= $langs->trans("Disabled");
+ }
+ }
+ if (GETPOSTISSET("filter_status")) {
+ if (strlen($addDescription) > 0) {
+ $addDescription .= ";";
+ }
+ $addDescription .= $langs->trans("Status")."=";
+ if (GETPOST("filter_status") == '1') {
+ $addFilter .= " AND s.status=1";
+ $addDescription .= $langs->trans("Enabled");
+ } elseif (GETPOST("filter_status") == '0') {
+ $addFilter .= " AND s.status=0";
+ $addDescription .= $langs->trans("Disabled");
+ }
+ }
+ if (GETPOST('default_lang', 'alpha')) {
+ $addFilter .= " AND s.default_lang LIKE '".$this->db->escape(GETPOST('default_lang', 'alpha'))."%'";
+ $addDescription = $langs->trans('DefaultLang')."=";
+ }
+ if (GETPOST('filter_lang_thirdparties', 'alpha')) {
+ $addFilter .= " AND s.default_lang LIKE '".$this->db->escape(GETPOST('filter_lang_thirdparties', 'alpha'))."%'";
+ $addDescription = $langs->trans('DefaultLang')."=";
+ }
+
// Select the third parties from category
- if (!GETPOST('filter')) {
+ if (!GETPOST('filter_thirdparties') || GETPOST('filter_thirdparties') == '-1') {
$sql = "SELECT s.rowid as id, s.email as email, s.nom as name, null as fk_contact, null as firstname, null as label";
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
$sql .= " WHERE s.email <> ''";
$sql .= " AND s.entity IN (".getEntity('societe').")";
$sql .= " AND s.email NOT IN (SELECT email FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE fk_mailing=".((int) $mailing_id).")";
- if (GETPOST('default_lang', 'alpha')) {
- $sql .= " AND s.default_lang LIKE '".$this->db->escape(GETPOST('default_lang', 'alpha'))."%'";
- }
+ $sql .= $addFilter;
} else {
- $addFilter = "";
- if (GETPOSTISSET("filter_client") && GETPOST("filter_client") <> '-1') {
- $addFilter .= " AND s.client=".((int) GETPOST("filter_client", 'int'));
- $addDescription = $langs->trans('ProspectCustomer')."=";
- if (GETPOST("filter_client") == 0) {
- $addDescription .= $langs->trans('NorProspectNorCustomer');
- } elseif (GETPOST("filter_client") == 1) {
- $addDescription .= $langs->trans('Customer');
- } elseif (GETPOST("filter_client") == 2) {
- $addDescription .= $langs->trans('Prospect');
- } elseif (GETPOST("filter_client") == 3) {
- $addDescription .= $langs->trans('ProspectCustomer');
- } else {
- $addDescription .= "Unknown status ".GETPOST("filter_client");
- }
- }
- if (GETPOSTISSET("filter_status")) {
- if (strlen($addDescription) > 0) {
- $addDescription .= ";";
- }
- $addDescription .= $langs->trans("Status")."=";
- if (GETPOST("filter_status") == '1') {
- $addFilter .= " AND s.status=1";
- $addDescription .= $langs->trans("Enabled");
- } else {
- $addFilter .= " AND s.status=0";
- $addDescription .= $langs->trans("Disabled");
- }
- }
- if (GETPOST('default_lang', 'alpha')) {
- $addFilter .= " AND s.default_lang LIKE '".$this->db->escape(GETPOST('default_lang', 'alpha'))."%'";
- $addDescription = $langs->trans('DefaultLang')."=";
- }
- if (GETPOST('filter_lang_thirdparties', 'alpha')) {
- $addFilter .= " AND s.default_lang LIKE '".$this->db->escape(GETPOST('filter_lang_thirdparties', 'alpha'))."%'";
- $addDescription = $langs->trans('DefaultLang')."=";
- }
-
$sql = "SELECT s.rowid as id, s.email as email, s.nom as name, null as fk_contact, null as firstname, c.label as label";
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."categorie_societe as cs, ".MAIN_DB_PREFIX."categorie as c";
$sql .= " WHERE s.email <> ''";
@@ -129,8 +151,8 @@ class mailing_thirdparties extends MailingTargets
$sql .= " AND s.email NOT IN (SELECT email FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE fk_mailing=".((int) $mailing_id).")";
$sql .= " AND cs.fk_soc = s.rowid";
$sql .= " AND c.rowid = cs.fk_categorie";
- if (GETPOST('filter', 'int') > 0) {
- $sql .= " AND c.rowid=".((int) GETPOST('filter', 'int'));
+ if (GETPOST('filter_thirdparties', 'int') > 0) {
+ $sql .= " AND c.rowid=".((int) GETPOST('filter_thirdparties', 'int'));
}
$sql .= $addFilter;
$sql .= " UNION ";
@@ -141,13 +163,15 @@ class mailing_thirdparties extends MailingTargets
$sql .= " AND s.email NOT IN (SELECT email FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE fk_mailing=".((int) $mailing_id).")";
$sql .= " AND cs.fk_soc = s.rowid";
$sql .= " AND c.rowid = cs.fk_categorie";
- if (GETPOST('filter', 'int') > 0) {
- $sql .= " AND c.rowid=".((int) GETPOST('filter', 'int'));
+ if (GETPOST('filter_thirdparties', 'int') > 0) {
+ $sql .= " AND c.rowid=".((int) GETPOST('filter_thirdparties', 'int'));
}
$sql .= $addFilter;
}
$sql .= " ORDER BY email";
+ //print $sql;exit;
+
// Stock recipients emails into targets table
$result = $this->db->query($sql);
if ($result) {
@@ -243,7 +267,8 @@ class mailing_thirdparties extends MailingTargets
$langs->load("companies");
- $s = '';
+ // filter
+ $s = '';
// Show categories
$sql = "SELECT rowid, label, type, visible";
@@ -293,7 +318,8 @@ class mailing_thirdparties extends MailingTargets
$s .= ' ';
- $s .= '';
+ // filter_client_thirdparties
+ $s .= '';
$s .= ''.$langs->trans('ProspectCustomer').' ';
if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) {
$s .= ''.$langs->trans('Prospect').' ';
@@ -309,6 +335,15 @@ class mailing_thirdparties extends MailingTargets
$s .= ' ';
$s .= ajax_combobox("filter_client_thirdparties");
+ // filter_supplier_thirdparties
+ $s .= ' ';
+ $s .= ''.$langs->trans("Supplier").' ';
+ $s .= ''.$langs->trans("Yes").' ';
+ $s .= ''.$langs->trans("No").' ';
+ $s .= ' ';
+ $s .= ajax_combobox("filter_supplier_thirdparties");
+
+ // filter_status_thirdparties
$s .= ' ';
$s .= ''.$langs->trans("Status").' ';
$s .= ''.$langs->trans("Enabled").' ';
@@ -316,6 +351,7 @@ class mailing_thirdparties extends MailingTargets
$s .= ' ';
$s .= ajax_combobox("filter_status_thirdparties");
+ // filter_lang_thirdparties
if (getDolGlobalInt('MAIN_MULTILANGS')) {
// Choose language
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
diff --git a/htdocs/core/modules/modPartnership.class.php b/htdocs/core/modules/modPartnership.class.php
index 8e8421540c7..44ef6b527db 100644
--- a/htdocs/core/modules/modPartnership.class.php
+++ b/htdocs/core/modules/modPartnership.class.php
@@ -212,7 +212,7 @@ class modPartnership extends DolibarrModules
// Dictionaries
$this->dictionaries=array(
- 'langs'=>'partnership@partnership',
+ 'langs'=>'partnership',
// List of tables we want to see into dictonnary editor
'tabname'=>array("c_partnership_type"),
// Label of tables
@@ -291,7 +291,7 @@ class modPartnership extends DolibarrModules
// 'leftmenu'=>'partnership',
// 'url'=>'/partnership/partnership_list.php',
// // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
- // 'langs'=>'partnership@partnership',
+ // 'langs'=>'partnership',
// 'position'=>1100+$r,
// // Define condition to show or hide menu entry. Use '$conf->partnership->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
// 'enabled'=>'$conf->partnership->enabled',
@@ -349,18 +349,18 @@ class modPartnership extends DolibarrModules
$r = 1;
/* BEGIN MODULEBUILDER EXPORT PARTNERSHIP */
/*
- $langs->load("partnership@partnership");
+ $langs->load("partnership");
$this->export_code[$r]=$this->rights_class.'_'.$r;
$this->export_label[$r]='PartnershipLines'; // Translation key (used only if key ExportDataset_xxx_z not found)
- $this->export_icon[$r]='partnership@partnership';
+ $this->export_icon[$r]='partnership';
// Define $this->export_fields_array, $this->export_TypeFields_array and $this->export_entities_array
- $keyforclass = 'Partnership'; $keyforclassfile='/partnership/class/partnership.class.php'; $keyforelement='partnership@partnership';
+ $keyforclass = 'Partnership'; $keyforclassfile='/partnership/class/partnership.class.php'; $keyforelement='partnership';
include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
//$this->export_fields_array[$r]['t.fieldtoadd']='FieldToAdd'; $this->export_TypeFields_array[$r]['t.fieldtoadd']='Text';
//unset($this->export_fields_array[$r]['t.fieldtoremove']);
//$keyforclass = 'PartnershipLine'; $keyforclassfile='/partnership/class/partnership.class.php'; $keyforelement='partnershipline@partnership'; $keyforalias='tl';
//include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
- $keyforselect='partnership'; $keyforaliasextra='extra'; $keyforelement='partnership@partnership';
+ $keyforselect='partnership'; $keyforaliasextra='extra'; $keyforelement='partnership';
include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
//$keyforselect='partnershipline'; $keyforaliasextra='extraline'; $keyforelement='partnershipline@partnership';
//include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
@@ -380,13 +380,13 @@ class modPartnership extends DolibarrModules
$r = 1;
/* BEGIN MODULEBUILDER IMPORT PARTNERSHIP */
/*
- $langs->load("partnership@partnership");
+ $langs->load("partnership");
$this->export_code[$r]=$this->rights_class.'_'.$r;
$this->export_label[$r]='PartnershipLines'; // Translation key (used only if key ExportDataset_xxx_z not found)
- $this->export_icon[$r]='partnership@partnership';
- $keyforclass = 'Partnership'; $keyforclassfile='/partnership/class/partnership.class.php'; $keyforelement='partnership@partnership';
+ $this->export_icon[$r]='partnership';
+ $keyforclass = 'Partnership'; $keyforclassfile='/partnership/class/partnership.class.php'; $keyforelement='partnership';
include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
- $keyforselect='partnership'; $keyforaliasextra='extra'; $keyforelement='partnership@partnership';
+ $keyforselect='partnership'; $keyforaliasextra='extra'; $keyforelement='partnership';
include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
//$this->export_dependencies_array[$r]=array('mysubobject'=>'ts.rowid', 't.myfield'=>array('t.myfield2','t.myfield3')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields)
$this->export_sql_start[$r]='SELECT DISTINCT ';
@@ -417,11 +417,11 @@ class modPartnership extends DolibarrModules
// Create extrafields during init
//include_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
//$extrafields = new ExtraFields($this->db);
- //$result1=$extrafields->addExtraField('partnership_myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty', 0, 0, '', '', 1, '', 0, 0, '', '', 'partnership@partnership', '$conf->partnership->enabled');
- //$result2=$extrafields->addExtraField('partnership_myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project', 0, 0, '', '', 1, '', 0, 0, '', '', 'partnership@partnership', '$conf->partnership->enabled');
- //$result3=$extrafields->addExtraField('partnership_myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account', 0, 0, '', '', 1, '', 0, 0, '', '', 'partnership@partnership', '$conf->partnership->enabled');
- //$result4=$extrafields->addExtraField('partnership_myattr4', "New Attr 4 label", 'select', 1, 3, 'thirdparty', 0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1,'', 0, 0, '', '', 'partnership@partnership', '$conf->partnership->enabled');
- //$result5=$extrafields->addExtraField('partnership_myattr5', "New Attr 5 label", 'text', 1, 10, 'user', 0, 0, '', '', 1, '', 0, 0, '', '', 'partnership@partnership', '$conf->partnership->enabled');
+ //$result1=$extrafields->addExtraField('partnership_myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty', 0, 0, '', '', 1, '', 0, 0, '', '', 'partnership', '$conf->partnership->enabled');
+ //$result2=$extrafields->addExtraField('partnership_myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project', 0, 0, '', '', 1, '', 0, 0, '', '', 'partnership', '$conf->partnership->enabled');
+ //$result3=$extrafields->addExtraField('partnership_myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account', 0, 0, '', '', 1, '', 0, 0, '', '', 'partnership', '$conf->partnership->enabled');
+ //$result4=$extrafields->addExtraField('partnership_myattr4', "New Attr 4 label", 'select', 1, 3, 'thirdparty', 0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1,'', 0, 0, '', '', 'partnership', '$conf->partnership->enabled');
+ //$result5=$extrafields->addExtraField('partnership_myattr5', "New Attr 5 label", 'text', 1, 10, 'user', 0, 0, '', '', 1, '', 0, 0, '', '', 'partnership', '$conf->partnership->enabled');
// Permissions
$this->remove($options);
diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php
index 16906c95f86..96fdb779b0b 100644
--- a/htdocs/core/modules/modProduct.class.php
+++ b/htdocs/core/modules/modProduct.class.php
@@ -104,7 +104,7 @@ class modProduct extends DolibarrModules
// Boxes
$this->boxes = array(
0=>array('file'=>'box_produits.php', 'enabledbydefaulton'=>'Home'),
- 1=>array('file'=>'box_produits_alerte_stock.php', 'enabledbydefaulton'=>''),
+ 1=>array('file'=>'box_produits_alerte_stock.php', 'enabledbydefaulton'=>'Home'),
2=>array('file'=>'box_graph_product_distribution.php', 'enabledbydefaulton'=>'Home')
);
diff --git a/htdocs/core/modules/modStripe.class.php b/htdocs/core/modules/modStripe.class.php
index 4c5d3deea44..e691e8e3b29 100644
--- a/htdocs/core/modules/modStripe.class.php
+++ b/htdocs/core/modules/modStripe.class.php
@@ -118,7 +118,7 @@ class modStripe extends DolibarrModules
'url' => '',
'langs' => 'stripe',
'position' => 100,
- 'enabled' => '$conf->stripe->enabled && $conf->banque->enabled && $conf->global->MAIN_FEATURES_LEVEL >= 1',
+ 'enabled' => 'isModEnabled("stripe") && isModenabled("banque")',
'perms' => '$user->rights->banque->lire',
'target' => '',
'user' => 0
@@ -132,7 +132,7 @@ class modStripe extends DolibarrModules
'url' => '/stripe/charge.php',
'langs' => 'stripe',
'position' => 102,
- 'enabled' => '$conf->stripe->enabled && $conf->banque->enabled && $conf->global->MAIN_FEATURES_LEVEL >= 1',
+ 'enabled' => 'isModEnabled("stripe") && isModenabled("banque") && getDolGlobalInt("MAIN_FEATURES_LEVEL") >= 1',
'perms' => '$user->rights->banque->lire',
'target' => '',
'user' => 0
@@ -146,7 +146,7 @@ class modStripe extends DolibarrModules
'url' => '/stripe/transaction.php',
'langs' => 'stripe',
'position' => 102,
- 'enabled' => '$conf->stripe->enabled && $conf->banque->enabled && $conf->global->MAIN_FEATURES_LEVEL >= 1',
+ 'enabled' => 'isModEnabled("stripe") && isModenabled("banque") && getDolGlobalInt("MAIN_FEATURES_LEVEL") >= 2',
'perms' => '$user->rights->banque->lire',
'target' => '',
'user' => 0
@@ -160,7 +160,7 @@ class modStripe extends DolibarrModules
'url' => '/stripe/payout.php',
'langs' => 'stripe',
'position' => 103,
- 'enabled' => '$conf->stripe->enabled && $conf->banque->enabled && $conf->global->MAIN_FEATURES_LEVEL >= 1',
+ 'enabled' => 'isModEnabled("stripe") && isModenabled("banque")',
'perms' => '$user->rights->banque->lire',
'target' => '',
'user' => 0
diff --git a/htdocs/core/modules/payment/mod_payment_ant.php b/htdocs/core/modules/payment/mod_payment_ant.php
index 03a6109bd67..6125053cbb4 100644
--- a/htdocs/core/modules/payment/mod_payment_ant.php
+++ b/htdocs/core/modules/payment/mod_payment_ant.php
@@ -61,7 +61,7 @@ class mod_payment_ant extends ModeleNumRefPayments
*/
public function info()
{
- global $db, $conf, $langs;
+ global $db, $langs;
$langs->load("bills");
@@ -82,7 +82,7 @@ class mod_payment_ant extends ModeleNumRefPayments
// Parametrage du prefix
$texte .= ''.$langs->trans("Mask").': ';
- $texte .= ''.$form->textwithpicto(' ', $tooltip, 1, 1).' ';
+ $texte .= ''.$form->textwithpicto(' ', $tooltip, 1, 1).' ';
$texte .= ' ';
@@ -128,7 +128,7 @@ class mod_payment_ant extends ModeleNumRefPayments
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
// We get cursor rule
- $mask = $conf->global->PAYMENT_ANT_MASK;
+ $mask = getDolGlobalString('PAYMENT_ANT_MASK');
if (!$mask) {
$this->error = 'NotConfigured';
diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
index d1a64bcf039..8a35edc7968 100644
--- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
+++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
@@ -117,13 +117,16 @@ class doc_generic_proposal_odt extends ModelePDFPropales
$form = new Form($this->db);
+ $odtChosen = getDolGlobalInt('MAIN_PROPAL_CHOOSE_ODT_DOCUMENT') > 0;
+ $odtPath = trim(getDolGlobalString('PROPALE_ADDON_PDF_ODT_PATH'));
+
$texte = $this->description.". \n";
$texte .= '