diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 432f30f2332..00000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: Bug report -about: Create a report to help us fix something that is broken -title: '' -labels: Bug -assignees: '' - ---- - -# Instructions -*This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report.* -*Please:* -- *replace the bracket enclosed texts with meaningful information* -- *remove any unused sub-section* - - -# Bug -[*Short description*] - -## Environment -- **Version**: [*Affected Dolibarr version(s)*] -- **OS**: [*Server OS type and version*] -- **Web server**: [*Webserver type and version*] -- **PHP**: [*PHP version*] -- **Database**: [*Database type and version*] -- **URL(s)**: [*Affected URL(s)*] - -## Expected and actual behavior -[*Verbose description*] - -## Steps to reproduce the behavior -[*Verbose description*] - -## [Attached files](https://help.github.com/articles/issue-attachments) (Screenshots, screencasts, dolibarr.log, debugging informations…) -[*Files*] diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000000..d7dc3d584e3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,71 @@ +name: Bug report +description: Create a report to help us fix something that is broken +labels: ["Bug"] + +body: + - type: markdown + attributes: + value: | + This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report. + + - type: textarea + id: bug + attributes: + label: Bug + description: Please give a short description of the bug + validations: + required: true + + - type: input + id: environment-version + attributes: + label: Environment Version + description: Affected Dolibarr version(s) + + - type: input + id: environment-os + attributes: + label: Environment OS + description: Server OS type and version + + - type: input + id: environment-webserver + attributes: + label: Environment Web server + description: Webserver type and version + + - type: input + id: environment-php + attributes: + label: Environment PHP + description: PHP version + + - type: input + id: environment-database + attributes: + label: Environment Database + description: Database type and version + + - type: input + id: environment-urls + attributes: + label: Environment URL(s) + description: Affected URL(s) + + - type: textarea + id: expected-behaviour + attributes: + label: Expected and actual behavior + description: Verbose description + + - type: textarea + id: reproduce + attributes: + label: Steps to reproduce the behavior + description: Verbose description + + - type: textarea + id: files + attributes: + label: Attached files + description: Screenshots, screencasts, dolibarr.log, debugging informations diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 32e2deff2c1..00000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: Feature request -about: Suggest a new idea for this project -title: '' -labels: Feature request -assignees: '' - ---- - -# Instructions -*This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report.* -*Please:* -- *replace the bracket enclosed texts with meaningful information* -- *remove any unused sub-section* - - -# Feature Request -[*Short description*] - -## Use case -[*Verbose description*] - -## Suggested implementation -[*Verbose description*] - -## Suggested steps -[*List of tasks to achieve goal*] diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000000..885f3472d18 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,35 @@ +name: Feature request +description: Suggest a new idea for this project +labels: ["Feature request"] + +body: + - type: markdown + attributes: + value: | + This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report. + + - type: textarea + id: feature-request + attributes: + label: Feature Request + description: Short description + validations: + required: true + + - type: textarea + id: use-case + attributes: + label: Use case + description: Verbose description + + - type: textarea + id: suggested-implementation + attributes: + label: Suggested implementation + description: Verbose description + + - type: textarea + id: suggested-steps + attributes: + label: Suggested steps + description: List of tasks to achieve goal diff --git a/.travis.yml b/.travis.yml index ddeefaab256..5d7eb7a1678 100644 --- a/.travis.yml +++ b/.travis.yml @@ -414,6 +414,9 @@ script: php upgrade.php 14.0.0 15.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade14001500.log php upgrade2.php 14.0.0 15.0.0 > $TRAVIS_BUILD_DIR/upgrade14001500-2.log php step5.php 14.0.0 15.0.0 > $TRAVIS_BUILD_DIR/upgrade14001500-3.log + php upgrade.php 15.0.0 16.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade15001600.log + php upgrade2.php 15.0.0 16.0.0 > $TRAVIS_BUILD_DIR/upgrade15001600-2.log + php step5.php 15.0.0 16.0.0 > $TRAVIS_BUILD_DIR/upgrade15001600-3.log ls -alrt $TRAVIS_BUILD_DIR/ - | diff --git a/SECURITY.md b/SECURITY.md index 4e7e5fa933a..cadd4a23791 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -67,7 +67,7 @@ Scope is the web application (back office) and the APIs. * Remote code execution (RCE) * Local files access and manipulation (LFI, RFI, XXE, SSRF, XSPA) * Code injections (HTML, JS, SQL, PHP, ...) -* Cross-Site Scripting (XSS), except from setup page of module "External web site" (allowing any content here, editable by admin user only, is accepted on purpose or into module "Web site" when permission to edit website content is allowed). +* Cross-Site Scripting (XSS), except from setup page of module "External web site" (allowing any content here, editable by admin user only, is accepted on purpose) and except into module "Web site" when permission to edit website content is allowed (injecting any data in this case is allowed too). * Cross-Site Requests Forgery (CSRF) with real security impact (when using GET URLs, CSRF are qualified only for creating, updating or deleting data from pages restricted to admin users) * Open redirect * Broken authentication & session management diff --git a/build/pad/README b/build/pad/README index 3cbc171686c..241d27d01c2 100644 --- a/build/pad/README +++ b/build/pad/README @@ -1,6 +1,7 @@ README (English) ################################################## Building PAD files +http://pad.asp-software.org/padgen.php ################################################## This directory contains files and docs used to build diff --git a/build/perl/virtualmin/dolibarr.pl b/build/perl/virtualmin/dolibarr.pl index 8b6a9888db0..b5bacf59356 100644 --- a/build/perl/virtualmin/dolibarr.pl +++ b/build/perl/virtualmin/dolibarr.pl @@ -30,7 +30,7 @@ return "Regis Houssin"; # script_dolibarr_versions() sub script_dolibarr_versions { -return ( "12.0.3", "11.0.5", "10.0.7", "9.0.4", "8.0.6", "7.0.5" ); +return ( "14.0.5", "13.0.5", "12.0.5", "11.0.5", "10.0.7", "9.0.4", "8.0.6", "7.0.5" ); } sub script_dolibarr_release @@ -400,6 +400,8 @@ sub script_dolibarr_check_latest { local ($ver) = @_; local @vers = &osdn_package_versions("dolibarr", + $ver >= 14.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" : + $ver >= 13.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" : $ver >= 12.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" : $ver >= 11.0 ? "dolibarr\\-(11\\.0\\.[0-9\\.]+)\\.tgz" : $ver >= 10.0 ? "dolibarr\\-(10\\.0\\.[0-9\\.]+)\\.tgz" : diff --git a/dev/examples/code/README b/dev/examples/code/README index b7c31558de5..bf3dd3f4969 100644 --- a/dev/examples/code/README +++ b/dev/examples/code/README @@ -5,4 +5,4 @@ This directory contains samples of code to use Dolibarr business classes to buil external interfaces that need to read/update data from/into Dolibarr. You can also have a look at the Dolibarr doxygen doc that describes all files and classes: -http://www.dolibarr.org/html_doxygen/index.html +https://doxygen.dolibarr.org/ diff --git a/dev/setup/apache/virtualhost b/dev/setup/apache/virtualhost index c3a2dff3e43..8c7682fe3d9 100644 --- a/dev/setup/apache/virtualhost +++ b/dev/setup/apache/virtualhost @@ -1,62 +1,93 @@ -#php_admin_value sendmail_path "/usr/sbin/sendmail -t -i" -#php_admin_value mail.force_extra_parameters "-f postmaster@mydomain.com" -php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f postmaster@mydomain.com" -php_admin_value open_basedir /tmp/:/home/../htdocs + #php_admin_value sendmail_path "/usr/sbin/sendmail -t -i" + #php_admin_value mail.force_extra_parameters "-f postmaster@mydomain.com" + php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f postmaster@mydomain.com" + php_admin_value open_basedir /tmp/:/home/.../htdocs:/home/.../dolibarr_documents: + + ServerName myvirtualalias + ServerAlias myvirtualalias + + UseCanonicalName On + + KeepAlive On + KeepAliveTimeout 5 + MaxKeepAliveRequests 20 + + AddDefaultCharset UTF-8 + + DocumentRoot "/home/.../htdocs" + + + AllowOverride None + Options -Indexes -MultiViews +FollowSymLinks -ExecCGI + Require all granted -ServerName myvirtualalias -ServerAlias myvirtualalias + # To restrict access by a HTTP basic auth + #AuthType Basic + #AuthName "Authenticate to backoffice" + #AuthUserFile /etc/apache2/.htpasswd + #require valid-user + + + # Leaving /public and /api, /dav, .well_known but also wrappers for document and viewimage accessible to everyone + + AuthType None + Require all granted + Satisfy any + + + AuthType None + Require all granted + Satisfy any + + + AuthType None + Require all granted + Satisfy any + + + AuthType None + Require all granted + Satisfy any + + + AuthType None + Require all granted + Satisfy any + -UseCanonicalName On - -AddDefaultCharset UTF-8 - -DocumentRoot "/home/.../htdocs" - - - AllowOverride None - Options -Indexes -MultiViews +FollowSymLinks -ExecCGI - Require all granted - - - - Deny from all - RemoveHandler .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml - AddType application/x-httpd-php-source .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml - - - -ErrorLog /var/log/apache2/myvirtualalias_error_log -TransferLog /var/log/apache2/myvirtualalias_access_log - -# Compress returned resources of type php pages, text file export, css and javascript -AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/x-javascript - -AddType text/javascript .jgz -AddEncoding gzip .jgz -ExpiresActive On -ExpiresByType image/x-icon A2592000 -ExpiresByType image/gif A2592000 -ExpiresByType image/png A2592000 -ExpiresByType image/jpeg A2592000 -ExpiresByType text/css A2592000 -ExpiresByType text/javascript A2592000 -ExpiresByType application/x-javascript A2592000 -ExpiresByType application/javascript A2592000 - -SSLEngine On - -# A self-signed (snakeoil) certificate can be created by installing -# the ssl-cert package. See -# /usr/share/doc/apache2.2-common/README.Debian.gz for more info. -# If both key and certificate are stored in the same file, only the -# SSLCertificateFile directive is needed. -SSLCertificateFile /etc/letsencrypt/live/www.mydomain.com/cert.pem -SSLCertificateKeyFile /etc/letsencrypt/live/www.mydomain.com/privkey.pem -SSLCertificateChainFile /etc/letsencrypt/live/www.mydomain.com/chain.pem - -#RewriteEngine on -#RewriteCond %{SERVER_PORT} ^80$ -#RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [L,R] + + ErrorLog /var/log/apache2/myvirtualalias_error_log + TransferLog /var/log/apache2/myvirtualalias_access_log + + # Compress returned resources of type php pages, text file export, css and javascript + AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/x-javascript + + AddType text/javascript .jgz + AddEncoding gzip .jgz + ExpiresActive On + ExpiresByType image/x-icon A2592000 + ExpiresByType image/gif A2592000 + ExpiresByType image/png A2592000 + ExpiresByType image/jpeg A2592000 + ExpiresByType text/css A2592000 + ExpiresByType text/javascript A2592000 + ExpiresByType application/x-javascript A2592000 + ExpiresByType application/javascript A2592000 + + SSLEngine On + + # A self-signed (snakeoil) certificate can be created by installing + # the ssl-cert package. See + # /usr/share/doc/apache2.2-common/README.Debian.gz for more info. + # If both key and certificate are stored in the same file, only the + # SSLCertificateFile directive is needed. + SSLCertificateFile /etc/letsencrypt/live/www.mydomain.com/cert.pem + SSLCertificateKeyFile /etc/letsencrypt/live/www.mydomain.com/privkey.pem + SSLCertificateChainFile /etc/letsencrypt/live/www.mydomain.com/chain.pem + + #RewriteEngine on + #RewriteCond %{SERVER_PORT} ^80$ + #RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [L,R] diff --git a/htdocs/accountancy/admin/accountmodel.php b/htdocs/accountancy/admin/accountmodel.php index 29c2b7d5510..fd0ff2e72da 100644 --- a/htdocs/accountancy/admin/accountmodel.php +++ b/htdocs/accountancy/admin/accountmodel.php @@ -185,11 +185,6 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { $ok = 0; setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors'); } - /*if (!is_numeric($_POST['code'])) // disabled, code may not be in numeric base - { - $ok = 0; - $msg .= $langs->transnoentities('ErrorFieldFormat', $langs->transnoentities('Code')).'
'; - }*/ } if (GETPOSTISSET("country") && (GETPOST("country") == '0') && ($id != 2)) { $ok = 0; @@ -228,17 +223,17 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { $i = 0; foreach ($listfieldinsert as $f => $value) { if ($value == 'price' || preg_match('/^amount/i', $value) || $value == 'taux') { - $_POST[$listfieldvalue[$i]] = price2num($_POST[$listfieldvalue[$i]], 'MU'); + $_POST[$listfieldvalue[$i]] = price2num(GETPOST($listfieldvalue[$i]), 'MU'); } elseif ($value == 'entity') { $_POST[$listfieldvalue[$i]] = $conf->entity; } if ($i) { $sql .= ","; } - if ($_POST[$listfieldvalue[$i]] == '') { + if (GETPOST($listfieldvalue[$i]) == '') { $sql .= "null"; } else { - $sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'"; } $i++; } @@ -276,7 +271,7 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { $i = 0; foreach ($listfieldmodify as $field) { if ($field == 'price' || preg_match('/^amount/i', $field) || $field == 'taux') { - $_POST[$listfieldvalue[$i]] = price2num($_POST[$listfieldvalue[$i]], 'MU'); + $_POST[$listfieldvalue[$i]] = price2num(GETPOST($listfieldvalue[$i]), 'MU'); } elseif ($field == 'entity') { $_POST[$listfieldvalue[$i]] = $conf->entity; } @@ -284,10 +279,10 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { $sql .= ","; } $sql .= $field."="; - if ($_POST[$listfieldvalue[$i]] == '') { + if (GETPOST($listfieldvalue[$i]) == '') { $sql .= "null"; } else { - $sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'"; } $i++; } diff --git a/htdocs/accountancy/admin/categories_list.php b/htdocs/accountancy/admin/categories_list.php index bb629577ab6..c0439445261 100644 --- a/htdocs/accountancy/admin/categories_list.php +++ b/htdocs/accountancy/admin/categories_list.php @@ -148,10 +148,10 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { if ($value == 'formula' && !GETPOST('formula')) { continue; } - if ($value == 'range_account' && empty($_POST['range_account'])) { + if ($value == 'range_account' && !GETPOST('range_account')) { continue; } - if (($value == 'country' || $value == 'country_id') && (!empty($_POST['country_id']))) { + if (($value == 'country' || $value == 'country_id') && GETPOST('country_id')) { continue; } if (!GETPOSTISSET($value) || GETPOST($value) == '') { @@ -195,17 +195,6 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { setEventMessages($langs->transnoentities('ErrorFieldMustBeANumeric', $langs->transnoentities("Position")), null, 'errors'); } - // Clean some parameters - if ($_POST["accountancy_code"] <= 0) { - $_POST["accountancy_code"] = ''; // If empty, we force to null - } - if ($_POST["accountancy_code_sell"] <= 0) { - $_POST["accountancy_code_sell"] = ''; // If empty, we force to null - } - if ($_POST["accountancy_code_buy"] <= 0) { - $_POST["accountancy_code_buy"] = ''; // If empty, we force to null - } - // Si verif ok et action add, on ajoute la ligne if ($ok && GETPOST('actionadd', 'alpha')) { if ($tabrowid[$id]) { @@ -243,7 +232,7 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { if ($i) { $sql .= ","; } - if ($_POST[$listfieldvalue[$i]] == '' && !$listfieldvalue[$i] == 'formula') { + if (GETPOST($listfieldvalue[$i]) == '' && !$listfieldvalue[$i] == 'formula') { $sql .= "null"; // For vat, we want/accept code = '' } else { $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'"; @@ -283,8 +272,8 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { } $i = 0; foreach ($listfieldmodify as $field) { - if ($field == 'fk_country' && $_POST['country'] > 0) { - $_POST[$listfieldvalue[$i]] = $_POST['country']; + if ($field == 'fk_country' && GETPOST('country') > 0) { + $_POST[$listfieldvalue[$i]] = GETPOST('country'); } elseif ($field == 'entity') { $_POST[$listfieldvalue[$i]] = $conf->entity; } @@ -292,10 +281,10 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { $sql .= ","; } $sql .= $field."="; - if ($_POST[$listfieldvalue[$i]] == '' && !$listfieldvalue[$i] == 'range_account') { + if (GETPOST($listfieldvalue[$i]) == '' && !$listfieldvalue[$i] == 'range_account') { $sql .= "null"; // For range_account, we want/accept code = '' } else { - $sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'"; } $i++; } diff --git a/htdocs/accountancy/admin/journals_list.php b/htdocs/accountancy/admin/journals_list.php index 7f000290e1c..de6b8374c2a 100644 --- a/htdocs/accountancy/admin/journals_list.php +++ b/htdocs/accountancy/admin/journals_list.php @@ -165,45 +165,19 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { // Check that all fields are filled $ok = 1; - foreach ($listfield as $f => $value) { - if ($fieldnamekey == 'libelle' || ($fieldnamekey == 'label')) { - $fieldnamekey = 'Label'; - } - if ($fieldnamekey == 'code') { - $fieldnamekey = 'Code'; - } - if ($fieldnamekey == 'nature') { - $fieldnamekey = 'NatureOfJournal'; - } - } + // Other checks if (GETPOSTISSET("code")) { if (GETPOST("code") == '0') { $ok = 0; setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors'); } - /*if (!is_numeric($_POST['code'])) // disabled, code may not be in numeric base - { - $ok = 0; - $msg .= $langs->transnoentities('ErrorFieldFormat', $langs->transnoentities('Code')).'
'; - }*/ } if (!GETPOST('label', 'alpha')) { setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label")), null, 'errors'); $ok = 0; } - // Clean some parameters - if ($_POST["accountancy_code"] <= 0) { - $_POST["accountancy_code"] = ''; // If empty, we force to null - } - if ($_POST["accountancy_code_sell"] <= 0) { - $_POST["accountancy_code_sell"] = ''; // If empty, we force to null - } - if ($_POST["accountancy_code_buy"] <= 0) { - $_POST["accountancy_code_buy"] = ''; // If empty, we force to null - } - // Si verif ok et action add, on ajoute la ligne if ($ok && GETPOST('actionadd', 'alpha')) { if ($tabrowid[$id]) { @@ -235,16 +209,13 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { } $i = 0; foreach ($listfieldinsert as $f => $value) { - if ($value == 'entity') { - $_POST[$listfieldvalue[$i]] = $conf->entity; - } if ($i) { $sql .= ","; } - if ($_POST[$listfieldvalue[$i]] == '') { + if (GETPOST($listfieldvalue[$i]) == '') { $sql .= "null"; // For vat, we want/accept code = '' } else { - $sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'"; } $i++; } @@ -254,7 +225,7 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { $result = $db->query($sql); if ($result) { // Add is ok setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs'); - $_POST = array('id'=>$id); // Clean $_POST array, we keep only + $_POST = array('id'=>$id); // Clean $_POST array, we keep only id } else { if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors'); @@ -281,24 +252,15 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { } $i = 0; foreach ($listfieldmodify as $field) { - if ($field == 'price' || preg_match('/^amount/i', $field) || $field == 'taux') { - $_POST[$listfieldvalue[$i]] = price2num($_POST[$listfieldvalue[$i]], 'MU'); - } elseif ($field == 'entity') { - $_POST[$listfieldvalue[$i]] = $conf->entity; - } if ($i) { $sql .= ","; } - $sql .= $field."="; - if ($_POST[$listfieldvalue[$i]] == '' && !($listfieldvalue[$i] == 'code' && $id == 10)) { - $sql .= "null"; // For vat, we want/accept code = '' - } else { - $sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; - } + $sql .= $field." = "; + $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'"; $i++; } $sql .= " WHERE ".$rowidcol." = ".((int) $rowid); - $sql .= " AND entity = ".$conf->entity; + $sql .= " AND entity = ".((int) $conf->entity); dol_syslog("actionmodify", LOG_DEBUG); //print $sql; @@ -323,7 +285,7 @@ if ($action == 'confirm_delete' && $confirm == 'yes') { // delete } $sql = "DELETE from ".$tabname[$id]." WHERE ".$rowidcol." = ".((int) $rowid); - $sql .= " AND entity = ".$conf->entity; + $sql .= " AND entity = ".((int) $conf->entity); dol_syslog("delete", LOG_DEBUG); $result = $db->query($sql); @@ -410,7 +372,7 @@ if ($action == 'delete') { if ($id) { // Complete requete recherche valeurs avec critere de tri $sql = $tabsql[$id]; - $sql .= " WHERE a.entity = ".$conf->entity; + $sql .= " WHERE a.entity = ".((int) $conf->entity); // If sort order is "country", we use country_code instead if ($sortfield == 'country') { @@ -510,7 +472,7 @@ if ($id) { $num = $db->num_rows($resql); $i = 0; - $param = '&id='.$id; + $param = '&id='.((int) $id); if ($search_country_id > 0) { $param .= '&search_country_id='.urlencode($search_country_id); } @@ -635,7 +597,7 @@ if ($id) { $class = 'tddict'; // Show value for field if ($showfield) { - print ''.$valuetoshow.''; + print ''.dol_escape_htmltag($valuetoshow).''; } } } diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index 0b67327b11c..3c2e8763fe1 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -237,7 +237,7 @@ if ($action != 'export_csv') { print ''; $parameters = array(); - $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + $reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { $button = 'global->ACCOUNTING_EXPORT_FORMAT.')" />'; diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index b67b134e3e1..67f521806cb 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -769,7 +769,7 @@ if (count($filter)) { } $parameters = array(); -$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { // Button re-export if (!empty($conf->global->ACCOUNTING_REEXPORT)) { diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index d73f4228f97..837a372a32d 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -473,7 +473,7 @@ print ''; print ''; $parameters = array(); -$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { $newcardbutton = dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param); $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); diff --git a/htdocs/accountancy/bookkeeping/listbysubaccount.php b/htdocs/accountancy/bookkeeping/listbysubaccount.php index e529126d8ce..c6fb95d5ab7 100644 --- a/htdocs/accountancy/bookkeeping/listbysubaccount.php +++ b/htdocs/accountancy/bookkeeping/listbysubaccount.php @@ -473,7 +473,7 @@ print ''; print ''; $parameters = array(); -$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { $newcardbutton = dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param); $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly')); diff --git a/htdocs/accountancy/class/accountancyimport.class.php b/htdocs/accountancy/class/accountancyimport.class.php index ece843515e2..ea88534b6ed 100644 --- a/htdocs/accountancy/class/accountancyimport.class.php +++ b/htdocs/accountancy/class/accountancyimport.class.php @@ -55,8 +55,8 @@ class AccountancyImport $fieldname = $fieldArr[1]; } - $debit = trim($arrayrecord[11]['val']); - $credit = trim($arrayrecord[12]['val']); + $debit = floatval(trim($arrayrecord[11]['val'])); + $credit = floatval(trim($arrayrecord[12]['val'])); if (!empty($debit)) { $amount = $debit; } else { @@ -86,7 +86,7 @@ class AccountancyImport $fieldname = $fieldArr[1]; } - $debit = trim($arrayrecord[11]['val']); + $debit = floatval(trim($arrayrecord[11]['val'])); if (!empty($debit)) { $sens = 'D'; } else { diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index a4dcac8c1ad..ac943180b58 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -476,7 +476,7 @@ class AccountingAccount extends CommonObject */ public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0, $save_lastsearch_value = -1, $withcompletelabel = 0, $option = '') { - global $langs, $conf; + global $langs, $conf, $hookmanager; require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php'; if (!empty($conf->dol_no_mouse_hover)) { @@ -561,6 +561,15 @@ class AccountingAccount extends CommonObject if ($withpicto != 2) { $result .= $linkstart . $label_link . $linkend; } + global $action; + $hookmanager->initHooks(array($this->element . 'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } diff --git a/htdocs/accountancy/class/accountingjournal.class.php b/htdocs/accountancy/class/accountingjournal.class.php index 376178b45ba..24e42c367aa 100644 --- a/htdocs/accountancy/class/accountingjournal.class.php +++ b/htdocs/accountancy/class/accountingjournal.class.php @@ -221,7 +221,7 @@ class AccountingJournal extends CommonObject */ public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0) { - global $langs, $conf, $user; + global $langs, $conf, $user, $hookmanager; if (!empty($conf->dol_no_mouse_hover)) { $notooltip = 1; // Force disable tooltips @@ -276,6 +276,15 @@ class AccountingJournal extends CommonObject } $result .= $linkend; + global $action; + $hookmanager->initHooks(array('accountingjournaldao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index e96cf9e0997..a83a311010d 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -331,7 +331,7 @@ class BookKeeping extends CommonObject if (empty($this->piece_num)) { $sqlnum = "SELECT MAX(piece_num)+1 as maxpiecenum"; $sqlnum .= " FROM ".MAIN_DB_PREFIX.$this->table_element; - $sqlnum .= " WHERE entity = ".$conf->entity; // Do not use getEntity for accounting features + $sqlnum .= " WHERE entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features $resqlnum = $this->db->query($sqlnum); if ($resqlnum) { @@ -460,7 +460,7 @@ class BookKeeping extends CommonObject { global $db, $conf, $langs; global $dolibarr_main_authentication, $dolibarr_main_demo; - global $menumanager; + global $menumanager, $hookmanager; if (!empty($conf->dol_no_mouse_hover)) { $notooltip = 1; // Force disable tooltips @@ -512,6 +512,15 @@ class BookKeeping extends CommonObject $result .= $linkend; //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + global $action; + $hookmanager->initHooks(array($this->element . 'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } @@ -736,7 +745,7 @@ class BookKeeping extends CommonObject $sql .= " t.date_validated as date_validation"; $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.$mode.' as t'; $sql .= ' WHERE 1 = 1'; - $sql .= " AND entity IN (".getEntity('accountancy').")"; + $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features if (null !== $ref) { $sql .= " AND t.ref = '".$this->db->escape($ref)."'"; } else { @@ -881,7 +890,7 @@ class BookKeeping extends CommonObject } $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; $sql .= ' WHERE 1 = 1'; - $sql .= " AND entity IN (".getEntity('accountancy').")"; + $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features if (count($sqlwhere) > 0) { $sql .= " AND ".implode(" ".$filtermode." ", $sqlwhere); } @@ -1037,7 +1046,7 @@ class BookKeeping extends CommonObject } } } - $sql .= ' WHERE t.entity IN ('.getEntity('accountancy').')'; + $sql .= ' WHERE t.entity = ' . ((int) $conf->entity); // Do not use getEntity for accounting features if ($showAlreadyExportMovements == 0) { $sql .= " AND t.date_export IS NULL"; } @@ -1157,7 +1166,7 @@ class BookKeeping extends CommonObject } } } - $sql .= ' WHERE entity IN ('.getEntity('accountancy').')'; + $sql .= ' WHERE entity = ' . ((int) $conf->entity); // Do not use getEntity for accounting features if (count($sqlwhere) > 0) { $sql .= " AND ".implode(" ".$filtermode." ", $sqlwhere); } @@ -1455,7 +1464,7 @@ class BookKeeping extends CommonObject */ public function deleteByYearAndJournal($delyear = 0, $journal = '', $mode = '', $delmonth = 0) { - global $langs; + global $conf, $langs; if (empty($delyear) && empty($journal)) { $this->error = 'ErrorOneFieldRequired'; @@ -1476,7 +1485,7 @@ class BookKeeping extends CommonObject if (!empty($journal)) { $sql .= " AND code_journal = '".$this->db->escape($journal)."'"; } - $sql .= " AND entity IN (".getEntity('accountancy').")"; + $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features // Exclusion of validated entries at the time of deletion $sql .= " AND date_validated IS NULL"; @@ -1515,7 +1524,7 @@ class BookKeeping extends CommonObject $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element; $sql .= " WHERE piece_num = ".(int) $piecenum; $sql .= " AND date_validated IS NULL"; // For security, exclusion of validated entries at the time of deletion - $sql .= " AND entity IN (".getEntity('accountancy').")"; + $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features $resql = $this->db->query($sql); @@ -1637,7 +1646,7 @@ class BookKeeping extends CommonObject } $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element.$mode; $sql .= " WHERE piece_num = ".((int) $piecenum); - $sql .= " AND entity IN (".getEntity('accountancy').")"; + $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features dol_syslog(__METHOD__, LOG_DEBUG); $result = $this->db->query($sql); @@ -1675,9 +1684,10 @@ class BookKeeping extends CommonObject global $conf; $sql = "SELECT MAX(piece_num)+1 as max FROM ".MAIN_DB_PREFIX.$this->table_element.$mode; - $sql .= " WHERE entity IN (".getEntity('accountancy').")"; + $sql .= " WHERE entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features + + dol_syslog(get_class($this)."::getNextNumMvt", LOG_DEBUG); - dol_syslog(get_class($this)."getNextNumMvt", LOG_DEBUG); $result = $this->db->query($sql); if ($result) { @@ -1718,7 +1728,7 @@ class BookKeeping extends CommonObject } $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element.$mode; $sql .= " WHERE piece_num = ".((int) $piecenum); - $sql .= " AND entity IN (".getEntity('accountancy').")"; + $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features dol_syslog(__METHOD__, LOG_DEBUG); $result = $this->db->query($sql); @@ -1781,7 +1791,7 @@ class BookKeeping extends CommonObject $sql .= " montant as amount, sens, fk_user_author, import_key, code_journal, piece_num,"; $sql .= " date_validated as date_validation"; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element; - $sql .= " WHERE entity IN (".getEntity('accountancy').")"; + $sql .= " WHERE entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features dol_syslog(get_class($this)."::export_bookkeeping", LOG_DEBUG); @@ -1837,6 +1847,8 @@ class BookKeeping extends CommonObject */ public function transformTransaction($direction = 0, $piece_num = '') { + global $conf; + $error = 0; $this->db->begin(); @@ -1856,14 +1868,14 @@ class BookKeeping extends CommonObject $sql .= ' doc_ref, fk_doc, fk_docdet, entity, thirdparty_code, subledger_account, subledger_label,'; $sql .= ' numero_compte, label_compte, label_operation, debit, credit,'; $sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, '.((int) $next_piecenum).", '".$this->db->idate($now)."'"; - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num); + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; $this->errors[] = 'Error '.$this->db->lasterror(); dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); } - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num); + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; @@ -1871,7 +1883,7 @@ class BookKeeping extends CommonObject dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); } } elseif ($direction == 1) { - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num); + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; @@ -1886,14 +1898,14 @@ class BookKeeping extends CommonObject $sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,'; $sql .= ' numero_compte, label_compte, label_operation, debit, credit,'; $sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num'; - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE piece_num = '.((int) $piece_num); + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; $this->errors[] = 'Error '.$this->db->lasterror(); dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); } - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num); + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); $resql = $this->db->query($sql); if (!$resql) { $error++; @@ -1948,7 +1960,7 @@ class BookKeeping extends CommonObject $sql .= " AND aa.active = 1"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version"; $sql .= " AND asy.rowid = ".((int) $pcgver); - $sql .= " AND ab.entity IN (".getEntity('accountancy').")"; + $sql .= " AND ab.entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features $sql .= " ORDER BY account_number ASC"; dol_syslog(get_class($this)."::select_account", LOG_DEBUG); @@ -2012,7 +2024,7 @@ class BookKeeping extends CommonObject $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as parent ON aa.account_parent = parent.rowid AND parent.active = 1"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as root ON parent.account_parent = root.rowid AND root.active = 1"; $sql .= " WHERE aa.account_number = '".$this->db->escape($account)."'"; - $sql .= " AND aa.entity IN (".getEntity('accountancy').")"; + $sql .= " AND aa.entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features dol_syslog(get_class($this)."::select_account", LOG_DEBUG); $resql = $this->db->query($sql); @@ -2052,7 +2064,7 @@ class BookKeeping extends CommonObject $sql .= " AND asy.rowid = ".((int) $pcgver); $sql .= " AND aa.active = 1"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_accounting_category as cat ON aa.fk_accounting_category = cat.rowid"; - $sql .= " WHERE aa.entity IN (".getEntity('accountancy').")"; + $sql .= " WHERE aa.entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features dol_syslog(get_class($this)."::select_account", LOG_DEBUG); $resql = $this->db->query($sql); diff --git a/htdocs/adherents/agenda.php b/htdocs/adherents/agenda.php index cb942ba3176..9132dae5802 100644 --- a/htdocs/adherents/agenda.php +++ b/htdocs/adherents/agenda.php @@ -65,6 +65,9 @@ if (GETPOST('actioncode', 'array')) { } $search_agenda_label = GETPOST('search_agenda_label'); +// Get object canvas (By default, this is not defined, so standard usage of dolibarr) +$objcanvas = null; + // Security check $result = restrictedArea($user, 'adherent', $id); diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index a2e3779d52b..caf2bbe61d6 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -55,6 +55,7 @@ $id = GETPOST('id') ?GETPOST('id', 'int') : $rowid; $typeid = GETPOST('typeid', 'int'); $userid = GETPOST('userid', 'int'); $socid = GETPOST('socid', 'int'); +$ref = GETPOST('ref', 'alpha'); if (!empty($conf->mailmanspip->enabled)) { include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php'; diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 1d12ad16194..dbe882d2cd1 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -7,7 +7,7 @@ * Copyright (C) 2009-2017 Regis Houssin * Copyright (C) 2014-2018 Alexandre Spangaro * Copyright (C) 2015 Marcos García - * Copyright (C) 2015-2020 Frédéric France + * Copyright (C) 2015-2022 Frédéric France * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2016 Juanjo Menent * Copyright (C) 2018-2019 Thibault FOUCART @@ -1805,6 +1805,7 @@ class Adherent extends CommonObject $paiement = new Paiement($this->db); $paiement->datepaye = $paymentdate; $paiement->amounts = $amounts; + $paiement->paiementcode = $operation; $paiement->paiementid = dol_getIdFromCode($this->db, $operation, 'c_paiement', 'code', 'id', 1); $paiement->num_payment = $num_chq; $paiement->note_public = $label; @@ -2164,7 +2165,7 @@ class Adherent extends CommonObject */ public function getNomUrl($withpictoimg = 0, $maxlen = 0, $option = 'card', $mode = '', $morecss = '', $save_lastsearch_value = -1, $notooltip = 0, $addlinktonotes = 0) { - global $conf, $langs; + global $conf, $langs, $hookmanager; if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) { $withpictoimg = 0; @@ -2282,7 +2283,15 @@ class Adherent extends CommonObject $result .= ''; } } - + global $action; + $hookmanager->initHooks(array($this->element . 'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index e26db90c4ff..5f578869e6e 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -40,6 +40,8 @@ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; $langs->loadLangs(array("companies", "bills", "members", "users", "mails", 'other')); +$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') + $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); $id = GETPOST('rowid', 'int') ?GETPOST('rowid', 'int') : GETPOST('id', 'int'); @@ -1163,9 +1165,13 @@ if ($rowid > 0) { print dol_get_fiche_end(); print '
'; - print ''; - print '     '; - print ''; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); + if (empty($reshook)) { + print ''; + print '     '; + print ''; + } print '
'; print ''; diff --git a/htdocs/adherents/subscription/card.php b/htdocs/adherents/subscription/card.php index 5967d670856..a18259fefe4 100644 --- a/htdocs/adherents/subscription/card.php +++ b/htdocs/adherents/subscription/card.php @@ -93,8 +93,8 @@ if ($user->rights->adherent->cotisation->creer && $action == 'update' && !$cance if ($accountline->rappro) { $errmsg = $langs->trans("SubscriptionLinkedToConciliatedTransaction"); } else { - $accountline->datev = dol_mktime($_POST['datesubhour'], $_POST['datesubmin'], 0, $_POST['datesubmonth'], $_POST['datesubday'], $_POST['datesubyear']); - $accountline->dateo = dol_mktime($_POST['datesubhour'], $_POST['datesubmin'], 0, $_POST['datesubmonth'], $_POST['datesubday'], $_POST['datesubyear']); + $accountline->datev = dol_mktime(GETPOST('datesubhour', 'int'), GETPOST('datesubmin', 'int'), 0, GETPOST('datesubmonth', 'int'), GETPOST('datesubday', 'int'), GETPOST('datesubyear', 'int')); + $accountline->dateo = dol_mktime(GETPOST('datesubhour', 'int'), GETPOST('datesubmin', 'int'), 0, GETPOST('datesubmonth', 'int'), GETPOST('datesubday', 'int'), GETPOST('datesubyear', 'int')); $accountline->amount = $amount; $result = $accountline->update($user); if ($result < 0) { @@ -105,12 +105,12 @@ if ($user->rights->adherent->cotisation->creer && $action == 'update' && !$cance if (!$errmsg) { // Modify values - $object->dateh = dol_mktime($_POST['datesubhour'], $_POST['datesubmin'], 0, $_POST['datesubmonth'], $_POST['datesubday'], $_POST['datesubyear']); - $object->datef = dol_mktime($_POST['datesubendhour'], $_POST['datesubendmin'], 0, $_POST['datesubendmonth'], $_POST['datesubendday'], $_POST['datesubendyear']); + $object->dateh = dol_mktime(GETPOST('datesubhour', 'int'), GETPOST('datesubmin', 'int'), 0, GETPOST('datesubmonth', 'int'), GETPOST('datesubday', 'int'), GETPOST('datesubyear', 'int')); + $object->datef = dol_mktime(GETPOST('datesubendhour', 'int'), GETPOST('datesubendmin', 'int'), 0, GETPOST('datesubendmonth', 'int'), GETPOST('datesubendday', 'int'), GETPOST('datesubendyear', 'int')); $object->fk_type = $typeid; $object->note = $note; + $object->note_private = $note; $object->amount = $amount; - //print 'datef='.$object->datef.' '.$_POST['datesubendday']; $result = $object->update($user); if ($result >= 0 && !count($object->errors)) { diff --git a/htdocs/admin/agenda.php b/htdocs/admin/agenda.php index 730983ad090..af09d32bc73 100644 --- a/htdocs/admin/agenda.php +++ b/htdocs/admin/agenda.php @@ -88,7 +88,6 @@ if ($action == "save" && empty($cancel)) { foreach ($triggers as $trigger) { $keyparam = 'MAIN_AGENDA_ACTIONAUTO_'.$trigger['code']; - //print "param=".$param." - ".$_POST[$param]; if ($search_event === '' || preg_match('/'.preg_quote($search_event, '/').'/i', $keyparam)) { $res = dolibarr_set_const($db, $keyparam, (GETPOST($keyparam, 'alpha') ?GETPOST($keyparam, 'alpha') : ''), 'chaine', 0, '', $conf->entity); if (!($res > 0)) { @@ -192,6 +191,7 @@ if (!empty($triggers)) { } if ($search_event === '' || preg_match('/'.preg_quote($search_event, '/').'/i', $trigger['code'])) { + print ''; print ''; print ''.$trigger['code'].''; print ''.$trigger['label'].''; diff --git a/htdocs/admin/agenda_other.php b/htdocs/admin/agenda_other.php index 8e50380e2ae..1014d40de50 100644 --- a/htdocs/admin/agenda_other.php +++ b/htdocs/admin/agenda_other.php @@ -41,6 +41,8 @@ $langs->loadLangs(array('admin', 'other', 'agenda', 'users')); $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $param = GETPOST('param', 'alpha'); $cancel = GETPOST('cancel', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); diff --git a/htdocs/admin/agenda_reminder.php b/htdocs/admin/agenda_reminder.php index 1d8cd8f723c..79aa081ddef 100644 --- a/htdocs/admin/agenda_reminder.php +++ b/htdocs/admin/agenda_reminder.php @@ -36,6 +36,8 @@ $langs->loadLangs(array("admin", "other", "agenda")); $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $param = GETPOST('param', 'alpha'); $cancel = GETPOST('cancel', 'alpha'); $scandir = GETPOST('scandir', 'alpha'); diff --git a/htdocs/admin/barcode.php b/htdocs/admin/barcode.php index 2fbfed35536..ee0fcd5d130 100644 --- a/htdocs/admin/barcode.php +++ b/htdocs/admin/barcode.php @@ -36,6 +36,7 @@ if (!$user->admin) { } $action = GETPOST('action', 'aZ09'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php /* diff --git a/htdocs/admin/bom.php b/htdocs/admin/bom.php index a36c3698306..e3adb206d7e 100644 --- a/htdocs/admin/bom.php +++ b/htdocs/admin/bom.php @@ -36,6 +36,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'bom'; diff --git a/htdocs/admin/commande.php b/htdocs/admin/commande.php index 24a45bb413a..5c8eb88126c 100644 --- a/htdocs/admin/commande.php +++ b/htdocs/admin/commande.php @@ -46,6 +46,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'order'; diff --git a/htdocs/admin/contract.php b/htdocs/admin/contract.php index 1c6a0ec0458..0c8aba5ae2d 100644 --- a/htdocs/admin/contract.php +++ b/htdocs/admin/contract.php @@ -37,6 +37,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'contract'; diff --git a/htdocs/admin/delivery.php b/htdocs/admin/delivery.php index 8e60b02a5bf..6f0f4c1b415 100644 --- a/htdocs/admin/delivery.php +++ b/htdocs/admin/delivery.php @@ -43,6 +43,8 @@ if (!$user->admin) { $action = GETPOST('action', 'alpha'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'delivery'; diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 5245e60ad67..4de4c682483 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2018 Laurent Destailleur * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2005-2017 Regis Houssin - * Copyright (C) 2010-2016 Juanjo Menent + * Copyright (C) 2010-2022 Juanjo Menent * Copyright (C) 2011-2021 Philippe Grand * Copyright (C) 2011 Remy Younes * Copyright (C) 2012-2015 Marcos García @@ -223,7 +223,7 @@ $tabsql[24] = "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFI $tabsql[25] = "SELECT rowid as rowid, code, label, active, module FROM ".MAIN_DB_PREFIX."c_type_container as t WHERE t.entity = ".getEntity($tabname[25]); //$tabsql[26]= "SELECT rowid as rowid, code, label, short_label, active FROM ".MAIN_DB_PREFIX."c_units"; $tabsql[27] = "SELECT id as rowid, code, libelle, picto, active FROM ".MAIN_DB_PREFIX."c_stcomm"; -$tabsql[28] = "SELECT h.rowid as rowid, h.code, h.label, h.affect, h.delay, h.newbymonth, h.fk_country as country_id, c.code as country_code, c.label as country, h.active FROM ".MAIN_DB_PREFIX."c_holiday_types as h LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON h.fk_country=c.rowid"; +$tabsql[28] = "SELECT h.rowid as rowid, h.code, h.label, h.affect, h.delay, h.newbymonth, h.fk_country as country_id, c.code as country_code, c.label as country, h.block_if_negative, h.active FROM ".MAIN_DB_PREFIX."c_holiday_types as h LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON h.fk_country=c.rowid"; $tabsql[29] = "SELECT rowid as rowid, code, label, percent, position, active FROM ".MAIN_DB_PREFIX."c_lead_status"; $tabsql[30] = "SELECT rowid, code, name, paper_size, orientation, metric, leftmargin, topmargin, nx, ny, spacex, spacey, width, height, font_size, custom_x, custom_y, active FROM ".MAIN_DB_PREFIX."c_format_cards"; //$tabsql[31]= "SELECT s.rowid as rowid, pcg_version, s.label, s.active FROM ".MAIN_DB_PREFIX."accounting_system as s"; @@ -315,7 +315,7 @@ $tabfield[24] = "code,label"; $tabfield[25] = "code,label"; //$tabfield[26]= "code,label,short_label"; $tabfield[27] = "code,libelle,picto"; -$tabfield[28] = "code,label,affect,delay,newbymonth,country_id,country"; +$tabfield[28] = "code,label,affect,delay,newbymonth,country_id,country,block_if_negative"; $tabfield[29] = "code,label,percent,position"; $tabfield[30] = "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; //$tabfield[31]= "pcg_version,label"; @@ -361,7 +361,7 @@ $tabfieldvalue[24] = "code,label"; $tabfieldvalue[25] = "code,label"; //$tabfieldvalue[26]= "code,label,short_label"; $tabfieldvalue[27] = "code,libelle,picto"; -$tabfieldvalue[28] = "code,label,affect,delay,newbymonth,country"; +$tabfieldvalue[28] = "code,label,affect,delay,newbymonth,country,block_if_negative"; $tabfieldvalue[29] = "code,label,percent,position"; $tabfieldvalue[30] = "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; //$tabfieldvalue[31]= "pcg_version,label"; @@ -407,7 +407,7 @@ $tabfieldinsert[24] = "code,label"; $tabfieldinsert[25] = "code,label"; //$tabfieldinsert[26]= "code,label,short_label"; $tabfieldinsert[27] = "code,libelle,picto"; -$tabfieldinsert[28] = "code,label,affect,delay,newbymonth,fk_country"; +$tabfieldinsert[28] = "code,label,affect,delay,newbymonth,fk_country,block_if_negative"; $tabfieldinsert[29] = "code,label,percent,position"; $tabfieldinsert[30] = "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; //$tabfieldinsert[31]= "pcg_version,label"; @@ -706,19 +706,19 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) { continue; // For some pages, country is not mandatory } // Discard check of mandatory fiedls for other fields - if ($value == 'localtax1' && empty($_POST['localtax1_type'])) { + if ($value == 'localtax1' && !GETPOST('localtax1_type')) { continue; } - if ($value == 'localtax2' && empty($_POST['localtax2_type'])) { + if ($value == 'localtax2' && !GETPOST('localtax2_type')) { continue; } - if ($value == 'color' && empty($_POST['color'])) { + if ($value == 'color' && !GETPOST('color')) { continue; } - if ($value == 'formula' && empty($_POST['formula'])) { + if ($value == 'formula' && !GETPOST('formula')) { continue; } - if ($value == 'dayrule' && empty($_POST['dayrule'])) { + if ($value == 'dayrule' && !GETPOST('dayrule')) { continue; } if ($value == 'sortorder') { @@ -794,11 +794,6 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) { $ok = 0; setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors'); } - /*if (!is_numeric($_POST['code'])) // disabled, code may not be in numeric base - { - $ok = 0; - $msg .= $langs->transnoentities('ErrorFieldFormat', $langs->transnoentities('Code')).'
'; - }*/ } if (GETPOSTISSET("country") && (GETPOST("country") == '0') && ($id != 2)) { if (in_array($tablib[$id], array('DictionaryCompanyType', 'DictionaryHolidayTypes'))) { // Field country is no mandatory for such dictionaries @@ -830,7 +825,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) { $_POST["accountancy_code_buy"] = ''; // If empty, we force to null } if ($id == 10 && GETPOSTISSET("code")) { // Spaces are not allowed into code for tax dictionary - $_POST["code"] = preg_replace('/[^a-zA-Z0-9\-\+]/', '', $_POST["code"]); + $_POST["code"] = preg_replace('/[^a-zA-Z0-9\-\+]/', '', GETPOST("code")); } // If check ok and action add, add the line @@ -883,7 +878,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) { if ($keycode == 'sortorder') { // For column name 'sortorder', we use the field name 'position' $sql .= (int) GETPOST('position', 'int'); - } elseif ($_POST[$keycode] == '' && !($keycode == 'code' && $id == 10)) { + } elseif (GETPOST($keycode) == '' && !($keycode == 'code' && $id == 10)) { $sql .= "null"; // For vat, we want/accept code = '' } elseif ($keycode == 'content') { $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; @@ -952,7 +947,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) { $sql .= $field."="; if ($listfieldvalue[$i] == 'sortorder') { // For column name 'sortorder', we use the field name 'position' $sql .= (int) GETPOST('position', 'int'); - } elseif ($_POST[$keycode] == '' && !($keycode == 'code' && $id == 10)) { + } elseif (GETPOST($keycode) == '' && !($keycode == 'code' && $id == 10)) { $sql .= "null"; // For vat, we want/accept code = '' } elseif ($keycode == 'content') { $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; @@ -1418,6 +1413,9 @@ if ($id) { if ($value == 'public' && $tablib[$id] == 'TicketDictCategory') { $valuetoshow = $langs->trans('TicketGroupIsPublic'); $class = 'center'; } + if ($value == 'block_if_negative') { + $valuetoshow = $langs->trans('BlockHolidayIfNegative'); + } if ($id == 2) { // Special case for state page if ($value == 'region_id') { @@ -1764,6 +1762,9 @@ if ($id) { if ($value == 'public' && $tablib[$id] == 'TicketDictCategory') { $valuetoshow = $langs->trans('TicketGroupIsPublic'); $cssprefix = 'center '; } + if ($value == 'block_if_negative') { + $valuetoshow = $langs->trans('BlockHolidayIfNegative'); + } if ($value == 'region_id' || $value == 'country_id') { $showfield = 0; @@ -1981,8 +1982,9 @@ if ($id) { } } } elseif ($value == 'fk_c_exp_tax_cat') { - $valuetoshow = getDictionaryValue(MAIN_DB_PREFIX.'c_exp_tax_cat', 'label', $valuetoshow); - $valuetoshow = $langs->trans($valuetoshow); + $tmpid = $valuetoshow; + $valuetoshow = getDictionaryValue(MAIN_DB_PREFIX.'c_exp_tax_cat', 'label', $tmpid); + $valuetoshow = $langs->trans($valuetoshow ? $valuetoshow : $tmpid); } elseif ($tabname[$id] == MAIN_DB_PREFIX.'c_exp_tax_cat') { $valuetoshow = $langs->trans($valuetoshow); } elseif ($value == 'label' && $tabname[$id] == MAIN_DB_PREFIX.'c_units') { @@ -1997,6 +1999,8 @@ if ($id) { } elseif ($fieldlist[$field] == 'label' && $tabname[$id] == MAIN_DB_PREFIX.'c_productbatch_qcstatus') { $langs->load("productbatch"); $valuetoshow = $langs->trans($obj->{$value}); + } elseif ($value == 'block_if_negative') { + $valuetoshow = yn($obj->{$value}); } $class .= ($class ? ' ' : '').'tddict'; if ($value == 'note' && $id == 10) { @@ -2379,6 +2383,10 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') print ''; print $form->selectExpenseRanges($obj->fk_range); print ''; + } elseif ($value == 'block_if_negative') { + print ''; + print $form->selectyesno("block_if_negative", (!empty($obj->{$value}) ? $obj->{$value}:''), 1); + print ''; } else { $fieldValue = isset($obj->{$value}) ? $obj->{$value}: ''; @@ -2408,6 +2416,31 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') $fieldValue = '0'; } } + + // Labels Length + $maxlength = ''; + if (in_array($fieldlist[$field], array('libelle', 'label'))) { + switch ($tabname) { + case MAIN_DB_PREFIX . 'c_accounting_category': + case MAIN_DB_PREFIX . 'c_ecotaxe': + case MAIN_DB_PREFIX . 'c_email_senderprofile': + case MAIN_DB_PREFIX . 'c_forme_juridique': + case MAIN_DB_PREFIX . 'c_holiday_types': + case MAIN_DB_PREFIX . 'c_payment_term': + case MAIN_DB_PREFIX . 'c_transport_mode': + $maxlength = ' maxlength="255"'; + break; + case MAIN_DB_PREFIX . 'c_email_templates': + $maxlength = ' maxlength="180"'; + break; + case MAIN_DB_PREFIX . 'c_socialnetworks': + $maxlength = ' maxlength="150"'; + break; + default: + $maxlength = ' maxlength="128"'; + } + } + print ''; $transfound = 0; $transkey = ''; @@ -2426,7 +2459,7 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') } } if (!$transfound) { - print ''; + print ''; } else { print ''; } diff --git a/htdocs/admin/eventorganization.php b/htdocs/admin/eventorganization.php index 8edc61bf255..904d10bff67 100644 --- a/htdocs/admin/eventorganization.php +++ b/htdocs/admin/eventorganization.php @@ -41,6 +41,8 @@ $backtopage = GETPOST('backtopage', 'alpha'); $value = GETPOST('value', 'alpha'); $label = GETPOST('label', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $scandir = GETPOST('scan_dir', 'alpha'); $type = 'myobject'; diff --git a/htdocs/admin/expedition.php b/htdocs/admin/expedition.php index 2d4736cc49d..12e0d0a6d01 100644 --- a/htdocs/admin/expedition.php +++ b/htdocs/admin/expedition.php @@ -43,6 +43,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'shipping'; diff --git a/htdocs/admin/expensereport.php b/htdocs/admin/expensereport.php index 5b73d995b5c..fc63940f0b8 100644 --- a/htdocs/admin/expensereport.php +++ b/htdocs/admin/expensereport.php @@ -43,6 +43,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'expensereport'; diff --git a/htdocs/admin/facture.php b/htdocs/admin/facture.php index ae269492ddf..9eec54b03a7 100644 --- a/htdocs/admin/facture.php +++ b/htdocs/admin/facture.php @@ -42,6 +42,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'invoice'; diff --git a/htdocs/admin/facture_situation.php b/htdocs/admin/facture_situation.php index 91134671692..609a6605d1a 100644 --- a/htdocs/admin/facture_situation.php +++ b/htdocs/admin/facture_situation.php @@ -28,24 +28,93 @@ */ require '../main.inc.php'; + +// Libraries require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice.lib.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formsetup.class.php'; // Load translation files required by the page $langs->loadLangs(array('admin', 'errors', 'other', 'bills')); +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('situationinvoicesetup', 'globalsetup')); + +// Access control if (!$user->admin) { accessforbidden(); } $action = GETPOST('action', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + $value = GETPOST('value', 'alpha'); $label = GETPOST('label', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $scandir = GETPOST('scan_dir', 'alpha'); $type = 'invoice'; +$form = new Form($db); +$formSetup = new FormSetup($db); + + +// Setup conf MYMODULE_MYPARAM4 : exemple of quick define write style +$formSetup->newItem('INVOICE_USE_SITUATION') + ->setAsYesNo() + ->nameText = $langs->trans('UseSituationInvoices'); + +$item = $formSetup->newItem('INVOICE_USE_SITUATION_CREDIT_NOTE') + ->setAsYesNo() + ->nameText = $langs->trans('UseSituationInvoicesCreditNote'); + +//$item = $formSetup->newItem('INVOICE_USE_RETAINED_WARRANTY') +// ->setAsYesNo() +// ->nameText = $langs->trans('Retainedwarranty'); + + +$item = $formSetup->newItem('INVOICE_USE_RETAINED_WARRANTY'); +$item->nameText = $langs->trans('AllowedInvoiceForRetainedWarranty'); + +$arrayAvailableType = array( + Facture::TYPE_SITUATION => $langs->trans("InvoiceSituation"), + Facture::TYPE_STANDARD.'+'.Facture::TYPE_SITUATION => $langs->trans("InvoiceSituation").' + '.$langs->trans("InvoiceStandard"), +); + +if ($action == 'edit') { + $item->fieldInputOverride = $form->selectarray('INVOICE_USE_RETAINED_WARRANTY', $arrayAvailableType, $conf->global->INVOICE_USE_RETAINED_WARRANTY, 1); +} else { + $item->fieldOutputOverride= isset($arrayAvailableType[$conf->global->INVOICE_USE_RETAINED_WARRANTY])?$arrayAvailableType[$conf->global->INVOICE_USE_RETAINED_WARRANTY]:''; +} + +//$item = $formSetup->newItem('INVOICE_RETAINED_WARRANTY_LIMITED_TO_SITUATION')->setAsYesNo(); +//$item->nameText = $langs->trans('RetainedwarrantyOnlyForSituation'); + +$formSetup->newItem('INVOICE_RETAINED_WARRANTY_LIMITED_TO_FINAL_SITUATION') + ->setAsYesNo() + ->nameText = $langs->trans('RetainedwarrantyOnlyForSituationFinal'); + + +$item = $formSetup->newItem('INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_PERCENT'); +$item->nameText = $langs->trans('RetainedwarrantyDefaultPercent'); +$item->fieldAttr = array( + 'type' => 'number', + 'step' => '0.01', + 'min' => 0, + 'max' => 100 +); + + +// Conditions paiements +$item = $formSetup->newItem('INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID'); +$item->nameText = $langs->trans('PaymentConditionsShortRetainedWarranty'); +$form->load_cache_conditions_paiements(); +if (!empty($conf->global->INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID) && isset($form->cache_conditions_paiements[$conf->global->INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID]['label'])) { + $item->fieldOutputOverride = $form->cache_conditions_paiements[$conf->global->INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID]['label']; +} +$item->fieldInputOverride = $form->getSelectConditionsPaiements($conf->global->INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID, 'INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID', -1, 1); + /* * Actions @@ -67,7 +136,6 @@ llxHeader( 'EN:Invoice_Configuration|FR:Configuration_module_facture|ES:ConfiguracionFactura' ); -$form = new Form($db); $linkback = ''.$langs->trans("BackToModuleList").''; @@ -84,170 +152,25 @@ print ''.$langs->trans("InvoiceFirstSituationDesc"). * Numbering module */ -print '
'; -print ''; +if ($action == 'edit') { + print $formSetup->generateOutput(true); +} else { + print $formSetup->generateOutput(); +} +if (count($formSetup->items) > 0) { + if ($action != 'edit') { + print '
'; + print ''.$langs->trans("Modify").''; + print '
'; + } +} else { + print '
'.$langs->trans("NothingToSetup"); +} -print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table -print ''; - -print ''; -print ''; -print ''; -print ''; -print "\n"; - -_printOnOff('INVOICE_USE_SITUATION', $langs->trans('UseSituationInvoices')); -_printOnOff('INVOICE_USE_SITUATION_CREDIT_NOTE', $langs->trans('UseSituationInvoicesCreditNote')); -//_printOnOff('INVOICE_USE_RETAINED_WARRANTY', $langs->trans('Retainedwarranty')); - -$confkey = 'INVOICE_USE_RETAINED_WARRANTY'; - -$arrayAvailableType = array( - Facture::TYPE_SITUATION => $langs->trans("InvoiceSituation"), - Facture::TYPE_STANDARD.'+'.Facture::TYPE_SITUATION => $langs->trans("InvoiceSituation").' + '.$langs->trans("InvoiceStandard"), -); -$selected = $conf->global->$confkey; -$curentInput = (empty($inputCount) ? 1 : ($inputCount + 1)); -$formSelectInvoiceType = $form->selectarray('value'.$curentInput, $arrayAvailableType, $selected, 1); -_printInputFormPart($confkey, $langs->trans('AllowedInvoiceForRetainedWarranty'), '', array(), $formSelectInvoiceType); - -//_printOnOff('INVOICE_RETAINED_WARRANTY_LIMITED_TO_SITUATION', $langs->trans('RetainedwarrantyOnlyForSituation')); -_printOnOff('INVOICE_RETAINED_WARRANTY_LIMITED_TO_FINAL_SITUATION', $langs->trans('RetainedwarrantyOnlyForSituationFinal')); - -$metas = array( - 'type' => 'number', - 'step' => '0.01', - 'min' => 0, - 'max' => 100 -); -_printInputFormPart('INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_PERCENT', $langs->trans('RetainedwarrantyDefaultPercent'), '', $metas); - -// Conditions paiements -$inputCount = empty($inputCount) ? 1 : ($inputCount + 1); -print ''; -print ''; -print ''; -print ''; - - -print '
'.$langs->trans("Parameter").''.$langs->trans("Value").' 
'.$langs->trans('PaymentConditionsShortRetainedWarranty').' '; -print ''; -$form->select_conditions_paiements($conf->global->INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID, 'value'.$inputCount, -1, 1); -print '
'; -print '
'; - -print '
'; - -_updateBtn(); - -print '
'; print dol_get_fiche_end(); // End of page llxFooter(); $db->close(); - -/** - * Print an update button - * - * @return void - */ -function _updateBtn() -{ - global $langs; - print '
'; - print ''; - print '
'; -} - -/** - * Print a On/Off button - * - * @param string $confkey the conf key - * @param bool $title Title of conf - * @param string $desc Description - * - * @return void - */ -function _printOnOff($confkey, $title = false, $desc = '') -{ - global $langs; - - print ''; - print ''.($title ? $title : $langs->trans($confkey)); - if (!empty($desc)) { - print '
'.$langs->trans($desc).''; - } - print ''; - print ' '; - print ''; - print ajax_constantonoff($confkey); - print ''; -} - - -/** - * Print a form part - * - * @param string $confkey the conf key - * @param bool $title Title of conf - * @param string $desc Description of - * @param array $metas html meta - * @param string $type type of input textarea or input - * @param bool $help help description - * - * @return void - */ -function _printInputFormPart($confkey, $title = false, $desc = '', $metas = array(), $type = 'input', $help = false) -{ - global $langs, $conf, $db, $inputCount; - - $inputCount = empty($inputCount) ? 1 : ($inputCount + 1); - $form = new Form($db); - - $defaultMetas = array( - 'name' => 'value'.$inputCount - ); - - if ($type != 'textarea') { - $defaultMetas['type'] = 'text'; - $defaultMetas['value'] = $conf->global->{$confkey}; - } - - - $metas = array_merge($defaultMetas, $metas); - $metascompil = ''; - foreach ($metas as $key => $values) { - $metascompil .= ' '.$key.'="'.$values.'" '; - } - - print ''; - print ''; - - if (!empty($help)) { - print $form->textwithtooltip(($title ? $title : $langs->trans($confkey)), $langs->trans($help), 2, 1, img_help(1, '')); - } else { - print $title ? $title : $langs->trans($confkey); - } - - if (!empty($desc)) { - print '
'.$langs->trans($desc).''; - } - - print ''; - print ' '; - print ''; - print ''; - print ''; - if ($type == 'textarea') { - print ''; - } elseif ($type == 'input') { - print ''; - } else { - // custom - print $type; - } - print ''; -} diff --git a/htdocs/admin/fichinter.php b/htdocs/admin/fichinter.php index 4369bb9a2a7..c95f354a189 100644 --- a/htdocs/admin/fichinter.php +++ b/htdocs/admin/fichinter.php @@ -43,6 +43,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'ficheinter'; diff --git a/htdocs/admin/holiday.php b/htdocs/admin/holiday.php index bfd7e22c461..c1755b17edf 100644 --- a/htdocs/admin/holiday.php +++ b/htdocs/admin/holiday.php @@ -39,6 +39,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'contract'; diff --git a/htdocs/admin/hrm.php b/htdocs/admin/hrm.php index 1ad84ce19ac..aea86069f4d 100644 --- a/htdocs/admin/hrm.php +++ b/htdocs/admin/hrm.php @@ -50,6 +50,8 @@ $backtopage = GETPOST('backtopage', 'alpha'); $value = GETPOST('value', 'alpha'); $label = GETPOST('label', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $scandir = GETPOST('scan_dir', 'alpha'); $type = 'myobject'; diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index 697f8fa2130..2c997d746d9 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -5,6 +5,7 @@ * Copyright (C) 2016 Juanjo Menent * Copyright (C) 2018 Ferran Marcet * Copyright (C) 2021 Alexandre Spangaro + * Copyright (C) 2021 Anthony Berton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -199,6 +200,20 @@ if ($action == 'update') { } else { dolibarr_set_const($db, "THEME_ELDY_USE_CHECKED", $val, 'chaine', 0, '', $conf->entity); } + + $val=(implode(',', (colorStringToArray(GETPOST('THEME_ELDY_BTNACTION'), array())))); + if ($val == '') { + dolibarr_del_const($db, 'THEME_ELDY_BTNACTION', $conf->entity); + } else { + dolibarr_set_const($db, 'THEME_ELDY_BTNACTION', $val, 'chaine', 0, '', $conf->entity); + } + + $val=(implode(',', (colorStringToArray(GETPOST('THEME_ELDY_TEXTBTNACTION'), array())))); + if ($val == '') { + dolibarr_del_const($db, 'THEME_ELDY_TEXTBTNACTION', $conf->entity); + } else { + dolibarr_set_const($db, 'THEME_ELDY_TEXTBTNACTION', $val, 'chaine', 0, '', $conf->entity); + } } if ($mode == 'dashboard') { @@ -265,6 +280,10 @@ if ($action == 'update') { $_SESSION["mainmenu"] = ""; // The menu manager may have changed + if (GETPOST('dol_resetcache')) { + dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", ((int) $conf->global->MAIN_IHM_PARAMS_REV) + 1, 'chaine', 0, '', $conf->entity); + } + header("Location: ".$_SERVER["PHP_SELF"]."?mainmenu=home&leftmenu=setup".'&mode='.$mode.(GETPOSTISSET('page_y') ? '&page_y='.GETPOST('page_y', 'int') : '')); exit; } @@ -294,6 +313,7 @@ print ''; print ''; print ''; print ''; +print ''; $head = ihm_prepare_head(); @@ -634,6 +654,7 @@ if ($mode == 'login') { print '
'; print ''; +print ''; print '
'; print ''; diff --git a/htdocs/admin/import.php b/htdocs/admin/import.php index cd9d7b44074..37168baa3d4 100644 --- a/htdocs/admin/import.php +++ b/htdocs/admin/import.php @@ -41,6 +41,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + /* * Actions diff --git a/htdocs/admin/knowledgemanagement.php b/htdocs/admin/knowledgemanagement.php index 8d93c16741a..c2440bbb885 100644 --- a/htdocs/admin/knowledgemanagement.php +++ b/htdocs/admin/knowledgemanagement.php @@ -37,8 +37,9 @@ $langs->loadLangs(array("admin", "knowledgemanagement")); // Parameters $action = GETPOST('action', 'aZ09'); $backtopage = GETPOST('backtopage', 'alpha'); - $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'knowledgemanagement'; diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index 41a436b70a8..fc8e24b9322 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -903,8 +903,8 @@ if ($action == 'edit') { include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; $formmail = new FormMail($db); $formmail->trackid = (($action == 'testhtml') ? "testhtml" : "test"); - $formmail->fromname = (GETPOSTISSET('fromname') ? $_POST['fromname'] : $conf->global->MAIN_MAIL_EMAIL_FROM); - $formmail->frommail = (GETPOSTISSET('frommail') ? $_POST['frommail'] : $conf->global->MAIN_MAIL_EMAIL_FROM); + $formmail->fromname = (GETPOSTISSET('fromname') ? GETPOST('fromname') : $conf->global->MAIN_MAIL_EMAIL_FROM); + $formmail->frommail = (GETPOSTISSET('frommail') ? GETPOST('frommail') : $conf->global->MAIN_MAIL_EMAIL_FROM); $formmail->fromid = $user->id; $formmail->fromalsorobot = 1; $formmail->fromtype = (GETPOSTISSET('fromtype') ?GETPOST('fromtype', 'aZ09') : (!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE) ? $conf->global->MAIN_MAIL_DEFAULT_FROMTYPE : 'user')); @@ -912,9 +912,9 @@ if ($action == 'edit') { $formmail->withsubstit = 1; $formmail->withfrom = 1; $formmail->witherrorsto = 1; - $formmail->withto = (!empty($_POST['sendto']) ? GETPOST('sendto', 'restricthtml') : ($user->email ? $user->email : 1)); - $formmail->withtocc = (!empty($_POST['sendtocc']) ? GETPOST('sendtocc', 'restricthtml') : 1); // ! empty to keep field if empty - $formmail->withtoccc = (!empty($_POST['sendtoccc']) ? GETPOST('sendtoccc', 'restricthtml') : 1); // ! empty to keep field if empty + $formmail->withto = (GETPOSTISSET('sendto') ? GETPOST('sendto', 'restricthtml') : ($user->email ? $user->email : 1)); + $formmail->withtocc = (GETPOSTISSET('sendtocc') ? GETPOST('sendtocc', 'restricthtml') : 1); // ! empty to keep field if empty + $formmail->withtoccc = (GETPOSTISSET('sendtoccc') ? GETPOST('sendtoccc', 'restricthtml') : 1); // ! empty to keep field if empty $formmail->withtopic = (GETPOSTISSET('subject') ? GETPOST('subject') : $langs->trans("Test")); $formmail->withtopicreadonly = 0; $formmail->withfile = 2; diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index fb3a1ccf702..476f15459cb 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -308,7 +308,7 @@ if (empty($reshook)) { // Rename some POST variables into a generic name if (GETPOST('actionmodify', 'alpha') && $value == 'topic') { - $_POST['topic'] = $_POST['topic-'.$rowid]; + $_POST['topic'] = GETPOST('topic-'.$rowid); } if ((!GETPOSTISSET($value) || GETPOST($value) == '' || GETPOST($value) == '-1') && $value != 'lang' && $value != 'fk_user' && $value != 'position') { diff --git a/htdocs/admin/mails_ticket.php b/htdocs/admin/mails_ticket.php index 79c549c0609..481fcad212c 100644 --- a/htdocs/admin/mails_ticket.php +++ b/htdocs/admin/mails_ticket.php @@ -537,16 +537,16 @@ if ($action == 'edit') { // Cree l'objet formulaire mail include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; $formmail = new FormMail($db); - $formmail->fromname = (GETPOSTISSET('fromname') ? $_POST['fromname'] : $conf->global->MAIN_MAIL_EMAIL_FROM); - $formmail->frommail = (GETPOSTISSET('frommail') ? $_POST['frommail'] : $conf->global->MAIN_MAIL_EMAIL_FROM); + $formmail->fromname = (GETPOSTISSET('fromname') ? GETPOST('fromname') : $conf->global->MAIN_MAIL_EMAIL_FROM); + $formmail->frommail = (GETPOSTISSET('frommail') ? GETPOST('frommail') : $conf->global->MAIN_MAIL_EMAIL_FROM); $formmail->trackid = (($action == 'testhtml') ? "testhtml" : "test"); $formmail->withfromreadonly = 0; $formmail->withsubstit = 0; $formmail->withfrom = 1; $formmail->witherrorsto = 1; - $formmail->withto = (!empty($_POST['sendto']) ? GETPOST('sendto', 'restricthtml') : ($user->email ? $user->email : 1)); - $formmail->withtocc = (!empty($_POST['sendtocc']) ? GETPOST('sendtocc', 'restricthtml') : 1); // ! empty to keep field if empty - $formmail->withtoccc = (!empty($_POST['sendtoccc']) ? GETPOST('sendtoccc', 'restricthtml') : 1); // ! empty to keep field if empty + $formmail->withto = (GETPOSTISSET('sendto') ? GETPOST('sendto', 'restricthtml') : ($user->email ? $user->email : 1)); + $formmail->withtocc = (GETPOSTISSET('sendtocc') ? GETPOST('sendtocc', 'restricthtml') : 1); + $formmail->withtoccc = (GETPOSTISSET('sendtoccc') ? GETPOST('sendtoccc', 'restricthtml') : 1); $formmail->withtopic = (GETPOSTISSET('subject') ? GETPOST('subject') : $langs->trans("Test")); $formmail->withtopicreadonly = 0; $formmail->withfile = 2; diff --git a/htdocs/admin/menus/edit.php b/htdocs/admin/menus/edit.php index 02c46d8ca35..b3c3e5066c2 100644 --- a/htdocs/admin/menus/edit.php +++ b/htdocs/admin/menus/edit.php @@ -152,32 +152,32 @@ if ($action == 'add') { $langs->load("errors"); $error = 0; - if (!$error && !$_POST['menu_handler']) { + if (!$error && !GETPOST('menu_handler')) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("MenuHandler")), null, 'errors'); $action = 'create'; $error++; } - if (!$error && !$_POST['type']) { + if (!$error && !GETPOST('type')) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Type")), null, 'errors'); $action = 'create'; $error++; } - if (!$error && !$_POST['url']) { + if (!$error && !GETPOST('url')) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("URL")), null, 'errors'); $action = 'create'; $error++; } - if (!$error && !$_POST['titre']) { + if (!$error && !GETPOST('titre')) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Title")), null, 'errors'); $action = 'create'; $error++; } - if (!$error && $_POST['menuId'] && $_POST['type'] == 'top') { + if (!$error && GETPOST('menuId') && GETPOST('type') == 'top') { setEventMessages($langs->trans("ErrorTopMenuMustHaveAParentWithId0"), null, 'errors'); $action = 'create'; $error++; } - if (!$error && !$_POST['menuId'] && $_POST['type'] == 'left') { + if (!$error && !GETPOST('menuId') && GETPOST('type') == 'left') { setEventMessages($langs->trans("ErrorLeftMenuMustHaveAParentId"), null, 'errors'); $action = 'create'; $error++; diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 29d2335a0f9..4ad384233d8 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -48,7 +48,6 @@ if (empty($mode)) { $mode = 'common'; } $action = GETPOST('action', 'aZ09'); -//var_dump($_POST);exit; $value = GETPOST('value', 'alpha'); $page_y = GETPOST('page_y', 'int'); $search_keyword = GETPOST('search_keyword', 'alpha'); diff --git a/htdocs/admin/mrp.php b/htdocs/admin/mrp.php index 54efdc4df19..fac6a3f3d41 100644 --- a/htdocs/admin/mrp.php +++ b/htdocs/admin/mrp.php @@ -37,6 +37,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'mrp'; diff --git a/htdocs/admin/oauth.php b/htdocs/admin/oauth.php index 9bf5be2c294..a0d82d1d6bd 100644 --- a/htdocs/admin/oauth.php +++ b/htdocs/admin/oauth.php @@ -27,6 +27,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; +// $supportedoauth2array is defined into oauth.lib.php // Define $urlwithroot $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); @@ -96,10 +97,12 @@ print ''; $i = 0; -// $list is defined into oauth.lib.php +// $list is defined into oauth.lib.php to the list of supporter OAuth providers. foreach ($list as $key) { $supported = 0; - if (in_array($key[0], array_keys($supportedoauth2array))) { + $keyforsupportedoauth2array = $key[0]; + + if (in_array($keyforsupportedoauth2array, array_keys($supportedoauth2array))) { $supported = 1; } if (!$supported) { @@ -110,20 +113,23 @@ foreach ($list as $key) { print ''; // Api Name - $label = $langs->trans($key[0]); - print ''; + $label = $langs->trans($keyforsupportedoauth2array); print ''; + print ''; print ''; if ($supported) { - $redirect_uri = $urlwithroot.'/core/modules/oauth/'.$supportedoauth2array[$key[0]].'_oauthcallback.php'; + $redirect_uri = $urlwithroot.'/core/modules/oauth/'.$supportedoauth2array[$keyforsupportedoauth2array]['callbackfile'].'_oauthcallback.php'; print ''; print ''; - print ''; } else { print ''; diff --git a/htdocs/admin/oauthlogintokens.php b/htdocs/admin/oauthlogintokens.php index 8697b400a2b..73a9139f856 100644 --- a/htdocs/admin/oauthlogintokens.php +++ b/htdocs/admin/oauthlogintokens.php @@ -25,17 +25,13 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; // This define $list +require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; // This define $list and $supportedoauth2array require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; use OAuth\Common\Storage\DoliStorage; // Load translation files required by the page $langs->loadLangs(array('admin', 'printing', 'oauth')); -if (!$user->admin) { - accessforbidden(); -} - $action = GETPOST('action', 'aZ09'); $mode = GETPOST('mode', 'alpha'); $value = GETPOST('value', 'alpha'); @@ -50,6 +46,10 @@ if (!$mode) { $mode = 'setup'; } +if (!$user->admin) { + accessforbidden(); +} + /* * Action @@ -122,7 +122,7 @@ $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domai $form = new Form($db); -llxHeader('', $langs->trans("PrintingSetup")); +llxHeader('', $langs->trans("TokenManager")); $linkback = ''.$langs->trans("BackToModuleList").''; print load_fiche_titre($langs->trans('ConfigOAuth'), $linkback, 'title_setup'); @@ -140,7 +140,9 @@ if ($mode == 'setup' && $user->admin) { foreach ($list as $key) { $supported = 0; - if (in_array($key[0], array_keys($supportedoauth2array))) { + $keyforsupportedoauth2array = $key[0]; + + if (in_array($keyforsupportedoauth2array, array_keys($supportedoauth2array))) { $supported = 1; } if (!$supported) { @@ -148,34 +150,44 @@ if ($mode == 'setup' && $user->admin) { } - $OAUTH_SERVICENAME = 'Unknown'; - if ($key[0] == 'OAUTH_GITHUB_NAME') { - $OAUTH_SERVICENAME = 'GitHub'; + $OAUTH_SERVICENAME = empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name']; + + // Define $shortscope, $urltorenew, $urltodelete, $urltocheckperms + // TODO Use array $supportedoauth2array + if ($keyforsupportedoauth2array == 'OAUTH_GITHUB_NAME') { // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service). // We pass this param list in to 'state' because we need it before and after the redirect. $shortscope = 'user,public_repo'; $urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltocheckperms = 'https://github.com/settings/applications/'; - } elseif ($key[0] == 'OAUTH_GOOGLE_NAME') { - $OAUTH_SERVICENAME = 'Google'; + } elseif ($keyforsupportedoauth2array == 'OAUTH_GOOGLE_NAME') { // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service). - // We pass this param list in to 'state' because we need it before and after the redirect. - $shortscope = 'userinfo_email,userinfo_profile,cloud_print'; - if (!empty($conf->global->OAUTH_GSUITE)) { + // List of scopes for Google are here: https://developers.google.com/identity/protocols/oauth2/scopes + // We pass this key list into the param 'state' because we need it before and after the redirect. + $shortscope = 'userinfo_email,userinfo_profile'; + $shortscope .= ',openid,email,profile'; // For openid connect + if (!empty($conf->printing->enabled)) { + $shortscope .= ',cloud_print'; + } + if (!empty($conf->global->OAUTH_GOOGLE_GSUITE)) { $shortscope .= ',admin_directory_user'; } - //$scope.=',gmail_full'; - $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); + if (!empty($conf->global->OAUTH_GOOGLE_GMAIL)) { + $shortscope.=',gmail_full'; + } + + $oauthstateanticsrf = bin2hex(random_bytes(128/8)); + $_SESSION['oauthstateanticsrf'] = $shortscope.'-'.$oauthstateanticsrf; + + $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltocheckperms = 'https://security.google.com/settings/security/permissions'; - } elseif ($key[0] == 'OAUTH_STRIPE_TEST_NAME') { - $OAUTH_SERVICENAME = 'StripeTest'; + } elseif ($keyforsupportedoauth2array == 'OAUTH_STRIPE_TEST_NAME') { $urltorenew = $urlwithroot.'/core/modules/oauth/stripetest_oauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = ''; $urltocheckperms = ''; - } elseif ($key[0] == 'OAUTH_STRIPE_LIVE_NAME') { - $OAUTH_SERVICENAME = 'StripeLive'; + } elseif ($keyforsupportedoauth2array == 'OAUTH_STRIPE_LIVE_NAME') { $urltorenew = $urlwithroot.'/core/modules/oauth/stripelive_oauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = ''; $urltocheckperms = ''; @@ -230,11 +242,14 @@ if ($mode == 'setup' && $user->admin) { print ''; print ''; - print '
'; + print '
'; print '
'.$label.''; - if (!empty($key[3])) { - print $langs->trans($key[3]); + print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"'); + print $label; + print ''; + if (!empty($supportedoauth2array[$keyforsupportedoauth2array]['urlforapp'])) { + print $langs->trans($supportedoauth2array[$keyforsupportedoauth2array]['urlforapp']); } print '
'.$langs->trans("UseTheFollowingUrlAsRedirectURI").''; + print ''; print '
'."\n"; print ''; - print ''; + print ''; print ''; print ''; print "\n"; @@ -244,7 +259,7 @@ if ($mode == 'setup' && $user->admin) { //var_dump($key); print $langs->trans("OAuthIDSecret").''; print ''; print ''; @@ -259,7 +274,7 @@ if ($mode == 'setup' && $user->admin) { if (is_object($tokenobj)) { print $langs->trans("HasAccessToken"); } else { - print $langs->trans("NoAccessToken"); + print ''.$langs->trans("NoAccessToken").''; } print ''; print ''; +print '"; +print ''; +print ''; +print ''; + +print ''; +print '"; +print ''; +print ''; +print ''; + +print ''; + +print '
'.$langs->trans($key[0]).''; + print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"'); + print $langs->trans($keyforsupportedoauth2array); + print '
'; - print $langs->trans("SeePreviousTab"); + print ''.$langs->trans("SeePreviousTab").''; print ''; print ''; @@ -346,7 +361,7 @@ if ($mode == 'setup' && $user->admin) { if ($mode == 'test' && $user->admin) { print $langs->trans('PrintTestDesc'.$driver)."

\n"; - print '
'; + print '
'; print ''; if (!empty($driver)) { require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; diff --git a/htdocs/admin/pdf.php b/htdocs/admin/pdf.php index 33f8f5b87f2..fd8377b0a27 100644 --- a/htdocs/admin/pdf.php +++ b/htdocs/admin/pdf.php @@ -96,9 +96,9 @@ if ($action == 'update') { dolibarr_set_const($db, "MAIN_PDF_NO_RECIPENT_FRAME", GETPOST("MAIN_PDF_NO_RECIPENT_FRAME"), 'chaine', 0, '', $conf->entity); } - if (GETPOSTISSET('MAIN_PDF_HIDE_SENDER_NAME')) { + /*if (GETPOSTISSET('MAIN_PDF_HIDE_SENDER_NAME')) { dolibarr_set_const($db, "MAIN_PDF_HIDE_SENDER_NAME", GETPOST("MAIN_PDF_HIDE_SENDER_NAME"), 'chaine', 0, '', $conf->entity); - } + }*/ if (GETPOSTISSET('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) { dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT", GETPOST("MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT"), 'chaine', 0, '', $conf->entity); @@ -307,6 +307,18 @@ print '
'; print '
'; print ''; +// Show sender name + +/* Set option as hidden because no need of this for 99.99% of users. +print ''; +*/ + // Hide VAT Intra on address print ''; - //Invert sender and recipient print ''; -print ''; - -print ''; - // Desc print ''; +// Swicth in Bold + +print ''; + +// Swicth in Bold + +print ''; + // SHOW_SUBPRODUCT_REF_IN_PDF - Option to show the detail of product ref for kits. print ''; print ''; print "\n"; +// Auto mark ticket read when created from backoffice +print ''; +print ''; +print ''; +print ''; + // Auto assign ticket at user who created it -print ''; +print ''; +print ''; print ''; print ''; -print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("MAIN_PDF_HIDE_SENDER_NAME").''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('MAIN_PDF_HIDE_SENDER_NAME'); +} else { + print $form->selectyesno('MAIN_PDF_HIDE_SENDER_NAME', (!empty($conf->global->MAIN_PDF_HIDE_SENDER_NAME)) ? $conf->global->MAIN_PDF_HIDE_SENDER_NAME : 0, 1); +} +print '
'.$langs->trans("ShowVATIntaInAddress").''; @@ -358,16 +370,6 @@ if ($conf->use_javascript_ajax) { print $form->selectarray("MAIN_PDF_NO_RECIPENT_FRAME", $arrval, $conf->global->MAIN_PDF_NO_RECIPENT_FRAME); } -// Show sender name - -print '
'.$langs->trans("MAIN_PDF_HIDE_SENDER_NAME").''; -if ($conf->use_javascript_ajax) { - print ajax_constantonoff('MAIN_PDF_HIDE_SENDER_NAME'); -} else { - print $form->selectyesno('MAIN_PDF_HIDE_SENDER_NAME', (!empty($conf->global->MAIN_PDF_HIDE_SENDER_NAME)) ? $conf->global->MAIN_PDF_HIDE_SENDER_NAME : 0, 1); -} -print '
'.$langs->trans("SwapSenderAndRecipientOnPDF").''; @@ -506,22 +508,6 @@ if ($conf->use_javascript_ajax) { } print '
'.$langs->trans("BoldLabelOnPDF").''; -if ($conf->use_javascript_ajax) { - print ajax_constantonoff('PDF_BOLD_PRODUCT_LABEL'); -} else { - print $form->selectyesno('PDF_BOLD_PRODUCT_LABEL', (!empty($conf->global->PDF_BOLD_PRODUCT_LABEL)) ? $conf->global->PDF_BOLD_PRODUCT_LABEL : 0, 1); -} -print '
'.$langs->trans("BoldRefAndPeriodOnPDF").''; -if ($conf->use_javascript_ajax) { - print ajax_constantonoff('PDF_BOLD_PRODUCT_REF_AND_PERIOD'); -} else { - print $form->selectyesno('PDF_BOLD_PRODUCT_REF_AND_PERIOD', (!empty($conf->global->PDF_BOLD_PRODUCT_REF_AND_PERIOD)) ? $conf->global->PDF_BOLD_PRODUCT_REF_AND_PERIOD : 0, 1); -} -print '
'.$langs->trans("HideDescOnPDF").''; @@ -542,6 +528,26 @@ if ($conf->use_javascript_ajax) { } print '
'.$langs->trans("BoldLabelOnPDF").''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('PDF_BOLD_PRODUCT_LABEL'); +} else { + print $form->selectyesno('PDF_BOLD_PRODUCT_LABEL', (!empty($conf->global->PDF_BOLD_PRODUCT_LABEL)) ? $conf->global->PDF_BOLD_PRODUCT_LABEL : 0, 1); +} +print '
'.$langs->trans("BoldRefAndPeriodOnPDF").''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('PDF_BOLD_PRODUCT_REF_AND_PERIOD'); +} else { + print $form->selectyesno('PDF_BOLD_PRODUCT_REF_AND_PERIOD', (!empty($conf->global->PDF_BOLD_PRODUCT_REF_AND_PERIOD)) ? $conf->global->PDF_BOLD_PRODUCT_REF_AND_PERIOD : 0, 1); +} +print '
'.$langs->trans("SHOW_SUBPRODUCT_REF_IN_PDF", $langs->transnoentitiesnoconv("AssociatedProductsAbility"), $langs->transnoentitiesnoconv("Products")).''; diff --git a/htdocs/admin/propal.php b/htdocs/admin/propal.php index 22ce045a7ab..6384c561967 100644 --- a/htdocs/admin/propal.php +++ b/htdocs/admin/propal.php @@ -43,6 +43,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'propal'; diff --git a/htdocs/admin/reception_setup.php b/htdocs/admin/reception_setup.php index 218cc1ef853..26300ece329 100644 --- a/htdocs/admin/reception_setup.php +++ b/htdocs/admin/reception_setup.php @@ -36,6 +36,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'reception'; diff --git a/htdocs/admin/sms.php b/htdocs/admin/sms.php index 05abf8c3995..19a94d05dd8 100644 --- a/htdocs/admin/sms.php +++ b/htdocs/admin/sms.php @@ -62,7 +62,7 @@ if ($action == 'update' && !$cancel) { // Send sms -if ($action == 'send' && !$_POST['cancel']) { +if ($action == 'send' && !$cancel) { $error = 0; $smsfrom = ''; diff --git a/htdocs/admin/supplier_order.php b/htdocs/admin/supplier_order.php index 808528cdc0a..0da79845d14 100644 --- a/htdocs/admin/supplier_order.php +++ b/htdocs/admin/supplier_order.php @@ -43,6 +43,8 @@ if (!$user->admin) { $type = GETPOST('type', 'alpha'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $action = GETPOST('action', 'aZ09'); $scandir = GETPOST('scan_dir', 'alpha'); diff --git a/htdocs/admin/supplier_payment.php b/htdocs/admin/supplier_payment.php index b31e4c9a433..a41f9fdf80c 100644 --- a/htdocs/admin/supplier_payment.php +++ b/htdocs/admin/supplier_payment.php @@ -37,6 +37,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scandir', 'alpha'); $type = 'supplier_payment'; diff --git a/htdocs/admin/supplier_proposal.php b/htdocs/admin/supplier_proposal.php index 6e3f190aeb6..9bd684afb22 100644 --- a/htdocs/admin/supplier_proposal.php +++ b/htdocs/admin/supplier_proposal.php @@ -38,6 +38,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'supplier_proposal'; diff --git a/htdocs/admin/system/filecheck.php b/htdocs/admin/system/filecheck.php index 1f183e1b730..10edae1a24b 100644 --- a/htdocs/admin/system/filecheck.php +++ b/htdocs/admin/system/filecheck.php @@ -416,7 +416,7 @@ if (empty($error) && !empty($xml)) { $outexpectedchecksum = ($checksumtoget ? $checksumtoget : $langs->trans("Unknown")); if ($checksumget == $checksumtoget) { - if (count($file_list['added'])) { + if (is_array($file_list['added']) && count($file_list['added'])) { $resultcode = 'warning'; $resultcomment = 'FileIntegrityIsOkButFilesWereAdded'; $outcurrentchecksum = $checksumget.' - '.$langs->trans($resultcomment).''; diff --git a/htdocs/admin/ticket.php b/htdocs/admin/ticket.php index 03fd647dd29..c36f6ae1d1b 100644 --- a/htdocs/admin/ticket.php +++ b/htdocs/admin/ticket.php @@ -38,6 +38,8 @@ if (!$user->admin) { // Parameters $value = GETPOST('value', 'alpha'); $action = GETPOST('action', 'aZ09'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scandir', 'alpha'); $type = 'ticket'; @@ -141,6 +143,20 @@ if ($action == 'updateMask') { } } +if ($action == 'setvarworkflow') { + $param_auto_read = GETPOST('TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND', 'alpha'); + $res = dolibarr_set_const($db, 'TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND', $param_auto_read, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } + + $param_auto_assign = GETPOST('TICKET_AUTO_ASSIGN_USER_CREATE', 'alpha'); + $res = dolibarr_set_const($db, 'TICKET_AUTO_ASSIGN_USER_CREATE', $param_auto_assign, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } +} + if ($action == 'setvarother') { $param_must_exists = GETPOST('TICKET_EMAIL_MUST_EXISTS', 'alpha'); $res = dolibarr_set_const($db, 'TICKET_EMAIL_MUST_EXISTS', $param_must_exists, 'chaine', 0, '', $conf->entity); @@ -176,8 +192,14 @@ if ($action == 'setvarother') { $error++; } - $param_auto_assign = GETPOST('TICKET_AUTO_ASSIGN_USER_CREATE', 'alpha'); - $res = dolibarr_set_const($db, 'TICKET_AUTO_ASSIGN_USER_CREATE', $param_auto_assign, 'chaine', 0, '', $conf->entity); + $param_delay_first_response = GETPOST('delay_first_response', 'int'); + $res = dolibarr_set_const($db, 'TICKET_DELAY_BEFORE_FIRST_RESPONSE', $param_delay_first_response, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } + + $param_delay_between_responses = GETPOST('delay_between_responses', 'int'); + $res = dolibarr_set_const($db, 'TICKET_DELAY_SINCE_LAST_RESPONSE', $param_delay_between_responses, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { $error++; } @@ -465,7 +487,7 @@ print '
'; if (!$conf->use_javascript_ajax) { print '
'; print ''; - print ''; + print ''; } print load_fiche_titre($langs->trans("Other"), '', ''); @@ -477,8 +499,24 @@ print '
'.$langs->trans("TicketsAutoReadTicket").''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND'); +} else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND", $arrval, $conf->global->TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND); +} +print ''; +print $form->textwithpicto('', $langs->trans("TicketsAutoReadTicketHelp"), 1, 'help'); +print '
'.$langs->trans("TicketsAutoAssignTicket").'
'.$langs->trans("TicketsAutoAssignTicket").''; if ($conf->use_javascript_ajax) { print ajax_constantonoff('TICKET_AUTO_ASSIGN_USER_CREATE'); @@ -492,12 +530,41 @@ print $form->textwithpicto('', $langs->trans("TicketsAutoAssignTicketHelp"), 1, print '

'; - if (!$conf->use_javascript_ajax) { print ''; } +// Define wanted maximum time elapsed before answers to tickets +print '
'; +print ''; + +print '
'.$langs->trans("TicketsDelayBeforeFirstAnswer")." + + + '; +print $form->textwithpicto('', $langs->trans("TicketsDelayBeforeFirstAnswerHelp"), 1, 'help'); +print '
'.$langs->trans("TicketsDelayBetweenAnswers")." + + + '; +print $form->textwithpicto('', $langs->trans("TicketsDelayBetweenAnswersHelp"), 1, 'help'); +print '

'; + + // Admin var of module print load_fiche_titre($langs->trans("Notification"), '', ''); diff --git a/htdocs/admin/user.php b/htdocs/admin/user.php index 85ab0f0e9a8..53de8fe2502 100644 --- a/htdocs/admin/user.php +++ b/htdocs/admin/user.php @@ -43,9 +43,11 @@ $extrafields = new ExtraFields($db); $action = GETPOST('action', 'aZ09'); $backtopage = GETPOST('backtopage', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php $value = GETPOST('value', 'alpha'); $label = GETPOST('label', 'alpha'); + $scandir = GETPOST('scandir', 'alpha'); $type = 'user'; diff --git a/htdocs/admin/usergroup.php b/htdocs/admin/usergroup.php index 3319ab994a6..709b60068f7 100644 --- a/htdocs/admin/usergroup.php +++ b/htdocs/admin/usergroup.php @@ -42,6 +42,8 @@ $extrafields = new ExtraFields($db); $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $type = 'group'; /* diff --git a/htdocs/admin/website.php b/htdocs/admin/website.php index d1a24ff072c..b5098bfd3ce 100644 --- a/htdocs/admin/website.php +++ b/htdocs/admin/website.php @@ -198,15 +198,15 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { $_POST[$listfieldvalue[$i]] = $conf->entity; } if ($value == 'ref') { - $_POST[$listfieldvalue[$i]] = strtolower($_POST[$listfieldvalue[$i]]); + $_POST[$listfieldvalue[$i]] = strtolower(GETPOST($listfieldvalue[$i])); } if ($i) { $sql .= ","; } - if ($_POST[$listfieldvalue[$i]] == '') { + if (GETPOST($listfieldvalue[$i]) == '') { $sql .= "null"; } else { - $sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'"; } $i++; } @@ -259,7 +259,7 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { if ($_POST[$listfieldvalue[$i]] == '') { $sql .= "null"; } else { - $sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'"; } $i++; } diff --git a/htdocs/admin/workstation.php b/htdocs/admin/workstation.php index e89cbb2fd41..58118827ed4 100644 --- a/htdocs/admin/workstation.php +++ b/htdocs/admin/workstation.php @@ -36,6 +36,7 @@ $langs->loadLangs(array("admin", "workstation")); // Parameters $action = GETPOST('action', 'aZ09'); $backtopage = GETPOST('backtopage', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php $value = GETPOST('value', 'alpha'); diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index 2a6b5f33a27..fa21c37649f 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -173,6 +173,7 @@ class DolibarrApi unset($object->stats_mrptoproduce); unset($object->element); + unset($object->element_for_permission); unset($object->fk_element); unset($object->table_element); unset($object->table_element_line); diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php index 2ab8c7837ac..9c7cc01630d 100644 --- a/htdocs/api/class/api_setup.class.php +++ b/htdocs/api/class/api_setup.class.php @@ -209,7 +209,7 @@ class Setup extends DolibarrApi if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; + $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -239,7 +239,6 @@ class Setup extends DolibarrApi return $list; } - /** * Get the list of states/provinces. * @@ -252,27 +251,34 @@ class Setup extends DolibarrApi * @param string $sortorder Sort order * @param int $limit Number of items per page * @param int $page Page number (starting from zero) - * @param string $filter To filter the countries by name + * @param int $country To filter on country + * @param string $filter To filter the states by name * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" - * @return array List of countries + * @return array List of states * * @url GET dictionary/states * * @throws RestException */ - public function getListOfStates($sortfield = "code_departement", $sortorder = 'ASC', $limit = 100, $page = 0, $filter = '', $sqlfilters = '') + public function getListOfStates($sortfield = "code_departement", $sortorder = 'ASC', $limit = 100, $page = 0, $country = 0, $filter = '', $sqlfilters = '') { $list = array(); // Note: The filter is not applied in the SQL request because it must // be applied to the translated names, not to the names in database. - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."c_departements as t"; + $sql = "SELECT t.rowid FROM ".MAIN_DB_PREFIX."c_departements as t"; + if ($country) { + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_regions as d ON t.fk_region = d.code_region"; + } $sql .= " WHERE 1 = 1"; + if ($country) { + $sql .= " AND d.fk_pays = ".((int) $country); + } // Add sql filters if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -373,7 +379,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -665,7 +671,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -729,7 +735,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -797,7 +803,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -860,7 +866,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -933,7 +939,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1004,7 +1010,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1078,7 +1084,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1143,9 +1149,9 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(400, 'error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; + $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -1202,9 +1208,9 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(400, 'error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; + $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -1261,7 +1267,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1301,7 +1307,7 @@ class Setup extends DolibarrApi * @param string $sortorder Sort order * @param int $limit Number of items per page * @param int $page Page number (starting from zero) - * @param string $country To filter on country + * @param int $country To filter on country * @param int $active Lega form is active or not {@min 0} {@max 1} * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" * @return array List of legal form @@ -1310,7 +1316,7 @@ class Setup extends DolibarrApi * * @throws RestException */ - public function getListOfLegalForm($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $country = '', $active = 1, $sqlfilters = '') + public function getListOfLegalForm($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $country = 0, $active = 1, $sqlfilters = '') { $list = array(); @@ -1318,13 +1324,13 @@ class Setup extends DolibarrApi $sql .= " FROM ".MAIN_DB_PREFIX."c_forme_juridique as t"; $sql .= " WHERE t.active = ".((int) $active); if ($country) { - $sql .= " AND t.fk_pays = '".$this->db->escape($country)."'"; + $sql .= " AND t.fk_pays = ".((int) $country); } // Add sql filters if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1383,7 +1389,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1449,7 +1455,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1508,7 +1514,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1567,7 +1573,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1628,7 +1634,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; diff --git a/htdocs/asset/class/asset.class.php b/htdocs/asset/class/asset.class.php index e5ec21bfa6d..916fb376526 100644 --- a/htdocs/asset/class/asset.class.php +++ b/htdocs/asset/class/asset.class.php @@ -305,7 +305,7 @@ class Asset extends CommonObject */ public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1) { - global $db, $conf, $langs; + global $db, $conf, $langs, $hookmanager; global $dolibarr_main_authentication, $dolibarr_main_demo; global $menumanager; @@ -360,7 +360,15 @@ class Asset extends CommonObject } $result .= $linkend; //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); - + global $action; + $hookmanager->initHooks(array($this->element . 'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } diff --git a/htdocs/barcode/printsheet.php b/htdocs/barcode/printsheet.php index 8663d50e66a..763463d6fb8 100644 --- a/htdocs/barcode/printsheet.php +++ b/htdocs/barcode/printsheet.php @@ -23,7 +23,7 @@ * \brief Page to print sheets with barcodes using the document templates into core/modules/printsheets */ -if (!empty($_POST['mode']) && $_POST['mode'] === 'label') { // Page is called to build a PDF and output, we must ne renew the token. +if (!empty($_POST['mode']) && $_POST['mode'] === 'label') { // Page is called to build a PDF and output, we must not renew the token. if (!defined('NOTOKENRENEWAL')) { define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) } diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index 748aea4ddb2..f6e40b511f1 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -148,8 +148,17 @@ if (empty($reshook)) { $error = 0; // Set if we used free entry or predefined product - $idprod = (int) GETPOST('idprod', 'int'); - $bom_child = (int) GETPOST('bom_select', 'int'); + $bom_child_id = (int) GETPOST('bom_id', 'int'); + if ($bom_child_id > 0) { + $bom_child = new BOM($db); + $res = $bom_child->fetch($bom_child_id); + if ($res) { + $idprod = $bom_child->fk_product; + } + } else { + $idprod = (int) GETPOST('idprod', 'int'); + } + $qty = price2num(GETPOST('qty', 'alpha'), 'MS'); $qty_frozen = price2num(GETPOST('qty_frozen', 'alpha'), 'MS'); $disable_stock_change = GETPOST('disable_stock_change', 'int'); @@ -173,7 +182,7 @@ if (empty($reshook)) { $bomline = new BOMLine($db); $bomline->fk_bom = $id; $bomline->fk_product = $idprod; - $bomline->fk_bom_child = $bom_child; + $bomline->fk_bom_child = $bom_child_id; $bomline->qty = $qty; $bomline->qty_frozen = (int) $qty_frozen; $bomline->disable_stock_change = (int) $disable_stock_change; @@ -354,8 +363,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $formquestion = array(); if (!empty($conf->bom->enabled)) { $langs->load("mrp"); - require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct = new FormProduct($db); $forcecombo = 0; if ($conf->browser->name == 'ie') { $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy @@ -384,8 +391,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $formquestion = array(); if (!empty($conf->bom->enabled)) { $langs->load("mrp"); - require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct = new FormProduct($db); $forcecombo = 0; if ($conf->browser->name == 'ie') { $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy @@ -415,7 +420,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (!empty($conf->bom->enabled)) { $langs->load("mrp"); require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct = new FormProduct($db); $forcecombo = 0; if ($conf->browser->name == 'ie') { $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy @@ -514,7 +518,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Common attributes $keyforbreak = 'duration'; include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; - + $object->calculateCosts(); print ''.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).''.price($object->total_cost).''; print ''.$langs->trans("UnitCost").''.price($object->unit_cost).''; @@ -585,13 +589,14 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $(".collapse_bom").click(function() { console.log("We click on collapse"); var id_bom_line = $(this).attr('id').replace('collapse-', ''); - if($(this).text().indexOf('+') > 0) { + console.log($(this).html().indexOf('folder-open')); + if($(this).html().indexOf('folder-open') <= 0) { $('[parentid="'+ id_bom_line +'"]').show(); - $(this).html('(-) '); + $(this).html(''); } else { $('[parentid="'+ id_bom_line +'"]').hide(); - $(this).html('(+) '); + $(this).html(''); } return false; @@ -601,7 +606,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $("#show_all").click(function() { console.log("We click on show all"); $("[class^=sub_bom_lines]").show(); - $("[class^=collapse_bom]").html('(-) '); + $("[class^=collapse_bom]").html(''); return false; }); @@ -609,7 +614,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $("#hide_all").click(function() { console.log("We click on hide all"); $("[class^=sub_bom_lines]").hide(); - $("[class^=collapse_bom]").html('(+) '); + $("[class^=collapse_bom]").html(''); return false; }); diff --git a/htdocs/bom/bom_net_needs.php b/htdocs/bom/bom_net_needs.php new file mode 100644 index 00000000000..4b2d5cdecab --- /dev/null +++ b/htdocs/bom/bom_net_needs.php @@ -0,0 +1,328 @@ + + * Copyright (C) 2019 Frédéric France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/bom/bom_net_needs.php + * \ingroup bom + * \brief Page to create/edit/view bom + */ + +// Load Dolibarr environment +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php'; +require_once DOL_DOCUMENT_ROOT.'/bom/lib/bom.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("mrp", "other")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm', 'alpha'); +$cancel = GETPOST('cancel', 'aZ09'); +$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'bomnet_needs'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); + + + +// Initialize technical objects +$object = new BOM($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->bom->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('bomnetneeds')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); +$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); + +// Initialize array of search criterias +$search_all = GETPOST("search_all", 'alpha'); +$search = array(); +foreach ($object->fields as $key => $val) { + if (GETPOST('search_'.$key, 'alpha')) { + $search[$key] = GETPOST('search_'.$key, 'alpha'); + } +} + +if (empty($action) && empty($id) && empty($ref)) { + $action = 'view'; +} + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. +if ($object->id > 0) { + $object->calculateCosts(); +} + + + +// Security check - Protection if external user +//if ($user->socid > 0) accessforbidden(); +//if ($user->socid > 0) $socid = $user->socid; +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +$result = restrictedArea($user, 'bom', $object->id, 'bom_bom', '', '', 'rowid', $isdraft); + +$permissionnote = $user->rights->bom->write; // Used by the include of actions_setnotes.inc.php +$permissiondellink = $user->rights->bom->write; // Used by the include of actions_dellink.inc.php +$permissiontoadd = $user->rights->bom->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php +$permissiontodelete = $user->rights->bom->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); +$upload_dir = $conf->bom->multidir_output[isset($object->entity) ? $object->entity : 1]; + + +/* + * Actions + */ + +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + $error = 0; + + $backurlforlist = DOL_URL_ROOT.'/bom/bom_list.php'; + + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { + $backtopage = $backurlforlist; + } else { + $backtopage = DOL_URL_ROOT.'/bom/bom_net_needs.php?id='.($id > 0 ? $id : '__ID__'); + } + } + } + if ($action == 'treeview') $object->getNetNeedsTree($TChildBom, 1); + else $object->getNetNeeds($TChildBom, 1); +} + + +/* + * View + */ + +$form = new Form($db); +$formfile = new FormFile($db); + + +$title = $langs->trans('BOM'); +$help_url ='EN:Module_BOM'; +llxHeader('', $title, $help_url); + + + +// Part to show record +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { + $head = bomPrepareHead($object); + print dol_get_fiche_head($head, 'net_needs', $langs->trans("BillOfMaterials"), -1, 'bom'); + + $formconfirm = ''; + + // Call Hook formConfirm + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); + $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + $formconfirm .= $hookmanager->resPrint; + } elseif ($reshook > 0) { + $formconfirm = $hookmanager->resPrint; + } + + // Print form confirm + print $formconfirm; + + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
'; + + $morehtmlref .= '
'; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
'; + print '
'; + print '
'; + print ''."\n"; + + // Common attributes + $keyforbreak = 'duration'; + include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; + + print ''; + print ''; + + // Other attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; + + print '
'.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).''.price($object->total_cost).'
'.$langs->trans("UnitCost").''.price($object->unit_cost).'
'; + print '
'; + print '
'; + + print '
'; + + print dol_get_fiche_end(); + + $viewlink = dolGetButtonTitle($langs->trans('GroupByProduct'), '', 'fa fa-list-alt imgforviewmode', $_SERVER['PHP_SELF'].'?id='.$object->id.'&token='.newToken(), '', 1, array('morecss' => 'reposition '.($action !== 'treeview' ? 'btnTitleSelected':''))); + $viewlink .= dolGetButtonTitle($langs->trans('TreeStructure'), '', 'fa fa-stream imgforviewmode', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=treeview&token='.newToken(), '', 1, array('morecss' => 'reposition marginleftonly '.($action == 'treeview' ? 'btnTitleSelected':''))); + + print load_fiche_titre($langs->trans("BillOfMaterials"), $viewlink, 'cubes'); + + /* + * Lines + */ + $text_stock_options = $langs->trans("RealStockDesc").'
'; + $text_stock_options .= $langs->trans("RealStockWillAutomaticallyWhen").'
'; + $text_stock_options .= (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE) ? '- '.$langs->trans("DeStockOnShipment").'
' : ''); + $text_stock_options .= (! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) ? '- '.$langs->trans("DeStockOnValidateOrder").'
' : ''); + $text_stock_options .= (! empty($conf->global->STOCK_CALCULATE_ON_BILL) ? '- '.$langs->trans("DeStockOnBill").'
' : ''); + $text_stock_options .= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL) ? '- '.$langs->trans("ReStockOnBill").'
' : ''); + $text_stock_options .= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER) ? '- '.$langs->trans("ReStockOnValidateOrder").'
' : ''); + $text_stock_options .= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) ? '- '.$langs->trans("ReStockOnDispatchOrder").'
' : ''); + $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE) ? '- '.$langs->trans("StockOnReception").'
' : ''); + + print ''; + print "\n"; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if (! empty($TChildBom)) { + if ($action == 'treeview') { + foreach ($TChildBom as $fk_bom => $TProduct) { + $repeatChar = ' '; + if (! empty($TProduct['bom'])) { + if ($TProduct['parentid'] != $object->id) print ''; + else print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } + if (! empty($TProduct['product'])) { + foreach ($TProduct['product'] as $fk_product => $TInfos) { + $prod = new Product($db); + $prod->fetch($fk_product); + $prod->load_virtual_stock(); + if (empty($prod->stock_reel)) $prod->stock_reel = 0; + if ($fk_bom != $object->id) print ''; + else print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } + } + } + } else { + foreach ($TChildBom as $fk_product => $qty) { + $prod = new Product($db); + $prod->fetch($fk_product); + $prod->load_virtual_stock(); + if (empty($prod->stock_reel)) $prod->stock_reel = 0; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } + } + } + print ''; + print '
'.$langs->trans('Product'); + if (! empty($conf->global->BOM_SUB_BOM) && $action == 'treeview') { + print '   '.img_picto('', 'folder-open', 'class="paddingright"').$langs->trans("ExpandAll").'  '; + print ''.img_picto('', 'folder', 'class="paddingright"').$langs->trans("UndoExpandAll").' '; + } + print ''.$langs->trans('Quantity').''.$form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1).''.$form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc")).'
'.str_repeat($repeatChar, $TProduct['level']).$TProduct['bom']->getNomUrl(1); + print ' '; + print img_picto('', 'folder-open'); + print ''; + print ''.$TProduct['qty'].'
'.str_repeat($repeatChar, $TInfos['level']).$prod->getNomUrl(1).''.$TInfos['qty'].''.$prod->stock_reel.''.$prod->stock_theorique.'
'.$prod->getNomUrl(1).''.$qty.''.$prod->stock_reel.''.$prod->stock_theorique.'
'; + + + + /* + * ButAction + */ + print '
'."\n"; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + print '
'; + + + ?> + + + + close(); diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 0520c76dde2..20ff5fe27b1 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -847,7 +847,7 @@ class BOM extends CommonObject global $action, $hookmanager; $hookmanager->initHooks(array('bomdao')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { $result = $hookmanager->resPrint; @@ -1064,26 +1064,89 @@ class BOM extends CommonObject $tmpproduct->cost_price = 0; $tmpproduct->pmp = 0; - $result = $tmpproduct->fetch($line->fk_product, '', '', '', 0, 1, 1); // We discard selling price and language loading - if ($result < 0) { - $this->error = $tmpproduct->error; - return -1; - } - $line->unit_cost = price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp); - if (empty($line->unit_cost)) { - if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) { - $line->unit_cost = $productFournisseur->fourn_unitprice; + if (empty($line->fk_bom_child)) { + $result = $tmpproduct->fetch($line->fk_product, '', '', '', 0, 1, 1); // We discard selling price and language loading + if ($result < 0) { + $this->error = $tmpproduct->error; + return -1; + } + $line->unit_cost = price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp); + if (empty($line->unit_cost)) { + if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) { + $line->unit_cost = $productFournisseur->fourn_unitprice; + } + } + + $line->total_cost = price2num($line->qty * $line->unit_cost, 'MT'); + + $this->total_cost += $line->total_cost; + } else { + $bom_child= new BOM($this->db); + $res = $bom_child->fetch($line->fk_bom_child); + if ($res>0) { + $bom_child->calculateCosts(); + $line->childBom[] = $bom_child; + $this->total_cost += $bom_child->total_cost * $line->qty; + } else { + $this->error = $bom_child->error; + return -2; } } - - $line->total_cost = price2num($line->qty * $line->unit_cost, 'MT'); - - $this->total_cost += $line->total_cost; } $this->total_cost = price2num($this->total_cost, 'MT'); - if ($this->qty) { + if ($this->qty > 0) { $this->unit_cost = price2num($this->total_cost / $this->qty, 'MU'); + } elseif ($this->qty < 0) { + $this->unit_cost = price2num($this->total_cost * $this->qty, 'MU'); + } + } + } + + /** + * Get Net needs by product + * + * @param array $TNetNeeds Array of ChildBom and infos linked to + * @param int $qty qty needed + * @return void + */ + public function getNetNeeds(&$TNetNeeds = array(), $qty = 0) + { + if (! empty($this->lines)) { + foreach ($this->lines as $line) { + if (! empty($line->childBom)) { + foreach ($line->childBom as $childBom) $childBom->getNetNeeds($TNetNeeds, $line->qty*$qty); + } else { + $TNetNeeds[$line->fk_product] += $line->qty*$qty; + } + } + } + } + + /** + * Get Net needs Tree by product or bom + * + * @param array $TNetNeeds Array of ChildBom and infos linked to + * @param int $qty qty needed + * @param int $level level of recursivity + * @return void + */ + public function getNetNeedsTree(&$TNetNeeds = array(), $qty = 0, $level = 0) + { + if (! empty($this->lines)) { + foreach ($this->lines as $line) { + if (! empty($line->childBom)) { + foreach ($line->childBom as $childBom) { + $TNetNeeds[$childBom->id]['bom'] = $childBom; + $TNetNeeds[$childBom->id]['parentid'] = $this->id; + $TNetNeeds[$childBom->id]['qty'] = $line->qty*$qty; + $TNetNeeds[$childBom->id]['level'] = $level; + $childBom->getNetNeedsTree($TNetNeeds, $line->qty*$qty, $level+1); + } + } else { + $TNetNeeds[$this->id]['product'][$line->fk_product]['qty'] += $line->qty * $qty; + $TNetNeeds[$this->id]['product'][$line->fk_product]['level'] = $level; + } } } } @@ -1213,6 +1276,11 @@ class BOMLine extends CommonObjectLine public $unit_cost = 0; + /** + * @var Bom array of Bom in line + */ + public $childBom = array(); + /** * Constructor * @@ -1453,7 +1521,7 @@ class BOMLine extends CommonObjectLine global $action, $hookmanager; $hookmanager->initHooks(array('bomlinedao')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { $result = $hookmanager->resPrint; diff --git a/htdocs/bom/lib/bom.lib.php b/htdocs/bom/lib/bom.lib.php index 805ba304c1d..954959d5d7a 100644 --- a/htdocs/bom/lib/bom.lib.php +++ b/htdocs/bom/lib/bom.lib.php @@ -84,6 +84,11 @@ function bomPrepareHead($object) $head[$h][2] = 'card'; $h++; + $head[$h][0] = DOL_URL_ROOT."/bom/bom_net_needs.php?id=".$object->id; + $head[$h][1] = $langs->trans("BOMNetNeeds"); + $head[$h][2] = 'net_needs'; + $h++; + if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { $nbNote = 0; if (!empty($object->note_private)) { diff --git a/htdocs/bom/tpl/objectline_create.tpl.php b/htdocs/bom/tpl/objectline_create.tpl.php index 7419c4618e0..0a3a3b34e7a 100644 --- a/htdocs/bom/tpl/objectline_create.tpl.php +++ b/htdocs/bom/tpl/objectline_create.tpl.php @@ -109,7 +109,7 @@ if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) { if (!empty($conf->global->BOM_SUB_BOM)) { print '
'.$langs->trans("or").'
'.$langs->trans("BOM"); // TODO Add component to select a BOM - print ''; + $form->select_bom(); } print ''; diff --git a/htdocs/bom/tpl/objectline_view.tpl.php b/htdocs/bom/tpl/objectline_view.tpl.php index 82626c12fec..8040310ea53 100644 --- a/htdocs/bom/tpl/objectline_view.tpl.php +++ b/htdocs/bom/tpl/objectline_view.tpl.php @@ -41,7 +41,7 @@ if (empty($object) || !is_object($object)) { } -global $forceall, $senderissupplier, $inputalsopricewithtax, $outputalsopricetotalwithtax; +global $forceall, $senderissupplier, $inputalsopricewithtax, $outputalsopricetotalwithtax, $langs; if (empty($dateSelector)) { $dateSelector = 0; @@ -83,8 +83,12 @@ $tmpproduct->fetch($line->fk_product); $tmpbom = new BOM($object->db); $res = $tmpbom->fetch($line->fk_bom_child); if ($tmpbom->id > 0) { + print $tmpproduct->getNomUrl(1); + print ' '.$langs->trans("or").' '; print $tmpbom->getNomUrl(1); - print '' . (empty($conf->global->BOM_SHOW_ALL_BOM_BY_DEFAULT) ? '(+)' : '(-)') . ' '; + print ' '; + print (empty($conf->global->BOM_SHOW_ALL_BOM_BY_DEFAULT) ? img_picto('', 'folder') : img_picto('', 'folder-open')); + print ''; } else { print $tmpproduct->getNomUrl(1); print ' - '.$tmpproduct->label; @@ -176,7 +180,8 @@ if ($action == 'selectlines') { print ''; // Select of all the sub-BOM lines -$sql = 'SELECT rowid, fk_bom_child, fk_product FROM '.MAIN_DB_PREFIX.'bom_bomline AS bl'; +// From this pont to the end of the file, we only take care of sub-BOM lines +$sql = 'SELECT rowid, fk_bom_child, fk_product, qty FROM '.MAIN_DB_PREFIX.'bom_bomline AS bl'; $sql.= ' WHERE fk_bom ='. (int) $tmpbom->id; $resql = $object->db->query($sql); @@ -187,7 +192,9 @@ if ($resql) { $sub_bom_product->fetch($obj->fk_product); $sub_bom = new BOM($object->db); - $sub_bom->fetch($obj->fk_bom_child); + if (!empty($obj->fk_bom_child)) { + $sub_bom->fetch($obj->fk_bom_child); + } $sub_bom_line = new BOMLine($object->db); $sub_bom_line->fetch($obj->rowid); @@ -199,21 +206,23 @@ if ($resql) { print ''; } - // Product - print ''.$sub_bom_product->getNomUrl(1).''; - - // Sub-BOM - if ($sub_bom_line->fk_bom_child > 0) { - print ''.$sub_bom->getNomUrl(1).''; + // Product OR BOM + print ''; + if (!empty($obj->fk_bom_child)) { + print $sub_bom_product->getNomUrl(1); + print ' '.$langs->trans('or').' '; + print $sub_bom->getNomUrl(1); } else { - print ' '; + print $sub_bom_product->getNomUrl(1); + print ''; } // Qty - print ''.price($sub_bom_line->qty * $line->qty, 0, '', 0, 0).''; if ($sub_bom_line->qty_frozen > 0) { - print ''.$sub_bom_line->qty_frozen.''; + print ''.price($sub_bom_line->qty, 0, '', 0, 0).''; + print ''.$langs->trans('Yes').''; } else { + print ''.price($sub_bom_line->qty * $line->qty, 0, '', 0, 0).''; print ' '; } @@ -227,21 +236,26 @@ if ($resql) { // Efficiency print ''.$sub_bom_line->efficiency.''; - // Cost price if it's defined - if ($sub_bom_product->cost_price > 0) { - print ''.price($sub_bom_product->cost_price * $line->qty).''; - $total_cost.= $sub_bom_product->cost_price * $line->qty; + if (!empty($sub_bom->id)) { + $sub_bom->calculateCosts(); + print ''.price($sub_bom->total_cost * $sub_bom_line->qty * $line->qty).''; + $total_cost+= $sub_bom->total_cost * $sub_bom_line->qty * $line->qty; + } elseif ($sub_bom_product->cost_price > 0) { + print ''.price($sub_bom_product->cost_price * $sub_bom_line->qty * $line->qty).''; + $total_cost+= $sub_bom_product->cost_price * $sub_bom_line->qty * $line->qty; } elseif ($sub_bom_product->pmp > 0) { // PMP if cost price isn't defined - print ''.price($sub_bom_product->pmp * $line->qty).''; - $total_cost.= $sub_bom_product->pmp * $line->qty; + print ''.price($sub_bom_product->pmp * $sub_bom_line->qty * $line->qty).''; + $total_cost.= $sub_bom_product->pmp * $sub_bom_line->qty * $line->qty; } else { // Minimum purchase price if cost price and PMP aren't defined - $sql_supplier_price = 'SELECT MIN(price) AS min_price FROM '.MAIN_DB_PREFIX.'product_fournisseur_price'; + $sql_supplier_price = 'SELECT MIN(price) AS min_price, quantity AS qty FROM '.MAIN_DB_PREFIX.'product_fournisseur_price'; $sql_supplier_price.= ' WHERE fk_product = '. (int) $sub_bom_product->id; $resql_supplier_price = $object->db->query($sql_supplier_price); if ($resql_supplier_price) { $obj = $object->db->fetch_object($resql_supplier_price); - print ''.price($obj->min_price * $line->qty).''; - $total_cost+= $obj->min_price * $line->qty; + $line_cost = $obj->min_price/$obj->qty * $sub_bom_line->qty * $line->qty; + + print ''.price($line_cost).''; + $total_cost+= $line_cost; } } diff --git a/htdocs/bookmarks/class/bookmark.class.php b/htdocs/bookmarks/class/bookmark.class.php index 9a5b3a53c20..39bb06c2ada 100644 --- a/htdocs/bookmarks/class/bookmark.class.php +++ b/htdocs/bookmarks/class/bookmark.class.php @@ -344,7 +344,7 @@ class Bookmark extends CommonObject global $action, $hookmanager; $hookmanager->initHooks(array('mybookmarkdao')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { $result = $hookmanager->resPrint; diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 5ffed2e5e4b..a3d2dc3e57f 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -10,7 +10,7 @@ * Copyright (C) 2015 Marcos García * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2016 Charlie Benke - * Copyright (C) 2018-2019 Frédéric France + * Copyright (C) 2018-2022 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 @@ -185,7 +185,8 @@ class Categorie extends CommonObject 'contact' => 'socpeople', 'account' => 'bank_account', // old for bank account 'project' => 'projet', - 'warehouse'=> 'entrepot' + 'warehouse'=> 'entrepot', + 'knowledgemanagement' => 'knowledgemanagement_knowledgerecord' ); /** @@ -1612,7 +1613,7 @@ class Categorie extends CommonObject */ public function getNomUrl($withpicto = 0, $option = '', $maxlength = 0, $moreparam = '') { - global $langs; + global $langs, $hookmanager; $result = ''; $label = $langs->trans("ShowCategory").': '.($this->ref ? $this->ref : $this->label); @@ -1640,6 +1641,15 @@ class Categorie extends CommonObject if ($withpicto != 2) { $result .= $link.dol_trunc(($this->ref ? $this->ref : $this->label), $maxlength).$linkend; } + global $action; + $hookmanager->initHooks(array($this->element . 'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } diff --git a/htdocs/categories/edit.php b/htdocs/categories/edit.php index 2b3ffc95c41..518889b85b3 100644 --- a/htdocs/categories/edit.php +++ b/htdocs/categories/edit.php @@ -178,7 +178,9 @@ print ''; // Parent category print ''.$langs->trans("In").''; +print img_picto('', 'category', 'class="pictofixedwidth"'); print $form->select_all_categories($type, $object->fk_parent, 'parent', 64, $object->id); +print ajax_combobox('parent'); print ''; $parameters = array(); diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 1e640f7afbe..a5b4f1d8ce9 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -123,16 +123,17 @@ class ActionComm extends CommonObject */ public $label; + /** + * @var string Agenda event label + * @deprecated Use $label + */ + public $libelle; + /** * @var integer Date creation record (datec) */ public $datec; - /** - * @var integer Date end record (datef) - */ - public $datef; - /** * @var integer Duration (duree) */ @@ -172,6 +173,21 @@ class ActionComm extends CommonObject */ public $datep; + /** + * @var integer Date action end (datef) + */ + public $datef; + + /** + * @var integer This is date start action (datep) but modified to not be outside calendar view. + */ + public $date_start_in_calendar; + + /** + * @var integer This is date end action (datef) but modified to not be outside calendar view. + */ + public $date_end_in_calendar; + /** * @var integer Date action end (datep2) */ @@ -188,6 +204,11 @@ class ActionComm extends CommonObject */ public $fulldayevent = 0; + /** + * @var int 1=??? + */ + public $ponctuel; + /** * @var integer Percentage */ @@ -219,8 +240,7 @@ class ActionComm extends CommonObject public $userownerid; /** - * @var int Id of user done (deprecated) - * @deprecated + * @var int Id of user that has done the event. Used only if AGENDA_ENABLE_DONEBY is set. */ public $userdoneid; @@ -239,20 +259,6 @@ class ActionComm extends CommonObject */ public $reminders = array(); - /** - * @var User Object user of owner - * @deprecated - * @see $userownerid - */ - public $usertodo; - - /** - * @var User Object user that did action - * @deprecated - * @see $userdoneid - */ - public $userdone; - /** * @var int thirdparty id linked to action */ @@ -831,18 +837,17 @@ class ActionComm extends CommonObject $this->usermodid = $obj->fk_user_mod; if (!is_object($this->author)) { - $this->author = new stdClass(); // To avoid warning + $this->author = new User($this->db); // To avoid warning } $this->author->id = $obj->fk_user_author; // deprecated $this->author->firstname = $obj->firstname; // deprecated $this->author->lastname = $obj->lastname; // deprecated if (!is_object($this->usermod)) { - $this->usermod = new stdClass(); // To avoid warning + $this->usermod = new User($this->db); // To avoid warning } $this->usermod->id = $obj->fk_user_mod; // deprecated $this->userownerid = $obj->fk_user_action; - $this->userdoneid = $obj->fk_user_done; $this->priority = $obj->priority; $this->fulldayevent = $obj->fulldayevent; $this->location = $obj->location; @@ -1134,18 +1139,18 @@ class ActionComm extends CommonObject $sql .= ", datep2 = ".(strval($this->datef) != '' ? "'".$this->db->idate($this->datef)."'" : 'null'); $sql .= ", durationp = ".(isset($this->durationp) && $this->durationp >= 0 && $this->durationp != '' ? "'".$this->db->escape($this->durationp)."'" : "null"); // deprecated $sql .= ", note = '".$this->db->escape($this->note_private)."'"; - $sql .= ", fk_project =".($this->fk_project > 0 ? $this->fk_project : "null"); - $sql .= ", fk_soc =".($socid > 0 ? $socid : "null"); - $sql .= ", fk_contact =".($contactid > 0 ? $contactid : "null"); + $sql .= ", fk_project =".($this->fk_project > 0 ? ((int) $this->fk_project) : "null"); + $sql .= ", fk_soc =".($socid > 0 ? ((int) $socid) : "null"); + $sql .= ", fk_contact =".($contactid > 0 ? ((int) $contactid) : "null"); $sql .= ", priority = '".$this->db->escape($this->priority)."'"; $sql .= ", fulldayevent = '".$this->db->escape($this->fulldayevent)."'"; $sql .= ", location = ".($this->location ? "'".$this->db->escape($this->location)."'" : "null"); $sql .= ", transparency = '".$this->db->escape($this->transparency)."'"; - $sql .= ", fk_user_mod = ".$user->id; - $sql .= ", fk_user_action = ".($userownerid > 0 ? "'".$this->db->escape($userownerid)."'" : "null"); - $sql .= ", fk_user_done = ".($userdoneid > 0 ? "'".$this->db->escape($userdoneid)."'" : "null"); + $sql .= ", fk_user_mod = ".((int) $user->id); + $sql .= ", fk_user_action = ".($userownerid > 0 ? ((int) $userownerid) : "null"); + $sql .= ", fk_user_done = ".($userdoneid > 0 ? ((int) $userdoneid) : "null"); if (!empty($this->fk_element)) { - $sql .= ", fk_element=".($this->fk_element ? $this->db->escape($this->fk_element) : "null"); + $sql .= ", fk_element=".($this->fk_element ? ((int) $this->fk_element) : "null"); } if (!empty($this->elementtype)) { $sql .= ", elementtype=".($this->elementtype ? "'".$this->db->escape($this->elementtype)."'" : "null"); @@ -1443,9 +1448,9 @@ class ActionComm extends CommonObject /** - * Return label of status + * Return the label of the status * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @param int $mode 0=Long label, 1=Short label, 2=Picto+Short label, 3=Picto, 4=Picto+Short label, 5=Short label+Picto, 6=Picto+Long label, 7=Very short label+Picto * @param int $hidenastatus 1=Show nothing if status is "Not applicable" * @return string String with status */ @@ -1632,41 +1637,39 @@ class ActionComm extends CommonObject } if ($withpicto == 2) { - $libelle = $label; if (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) { - $libelle = $labeltype; + $label = $labeltype; } - $libelleshort = ''; + $labelshort = ''; } else { - $libelle = (empty($this->libelle) ? $label : $this->libelle.(($label && $label != $this->libelle) ? ' '.$label : '')); - if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && empty($libelle)) { - $libelle = $labeltype; + if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && empty($label)) { + $label = $labeltype; } if ($maxlength < 0) { - $libelleshort = $this->ref; + $labelshort = $this->ref; } else { - $libelleshort = dol_trunc($libelle, $maxlength); + $labelshort = dol_trunc($label, $maxlength); } } if ($withpicto) { if (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) { // Add code into () if ($labeltype) { - $libelle .= (preg_match('/'.preg_quote($labeltype, '/').'/', $libelle) ? '' : ' ('.$langs->transnoentities("Action".$this->type_code).')'); + $label .= (preg_match('/'.preg_quote($labeltype, '/').'/', $label) ? '' : ' ('.$langs->transnoentities("Action".$this->type_code).')'); } } } $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $langs->trans("ShowAction").': '.$libelle), ($overwritepicto ? $overwritepicto : 'action'), (($this->type_color && $overwritepicto) ? 'style="color: #'.$this->type_color.' !important;" ' : '').($notooltip ? 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"' : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $langs->trans("ShowAction").': '.$label), ($overwritepicto ? $overwritepicto : 'action'), (($this->type_color && $overwritepicto) ? 'style="color: #'.$this->type_color.' !important;" ' : '').($notooltip ? 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"' : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); } - $result .= $libelleshort; + $result .= $labelshort; $result .= $linkend; global $action; $hookmanager->initHooks(array('actiondao')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { $result = $hookmanager->resPrint; diff --git a/htdocs/comm/action/class/actioncommreminder.class.php b/htdocs/comm/action/class/actioncommreminder.class.php index aa693d2e41f..ff242430b0a 100644 --- a/htdocs/comm/action/class/actioncommreminder.class.php +++ b/htdocs/comm/action/class/actioncommreminder.class.php @@ -205,9 +205,9 @@ class ActionCommReminder extends CommonObject } /** - * Retourne le libelle du status d'un user (actif, inactif) + * Return label of the status of a reminder * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto * @return string Label of status */ public function getLibStatut($mode = 0) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 81df122f1a9..e8060bc314d 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -847,7 +847,7 @@ if ($resql) { $event->fk_project = $obj->fk_project; - $event->thirdparty_id = $obj->fk_soc; + $event->socid = $obj->fk_soc; $event->contact_id = $obj->fk_contact; // Defined date_start_in_calendar and date_end_in_calendar property @@ -858,10 +858,6 @@ if ($resql) { } else { $event->date_end_in_calendar = $event->datep; } - // Define ponctual property - if ($event->date_start_in_calendar == $event->date_end_in_calendar) { - $event->ponctuel = 1; - } // Check values if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar >= $lastdaytoshow) { @@ -973,7 +969,6 @@ if ($showbirthday) { $event->date_start_in_calendar = $db->jdate($event->datep); $event->date_end_in_calendar = $db->jdate($event->datef); - $event->ponctuel = 0; // Add an entry in eventarray for each day $daycursor = $event->datep; @@ -1316,12 +1311,6 @@ if (count($listofextcals)) { $event->date_end_in_calendar = $event->datep; } - // Define ponctual property - if ($event->date_start_in_calendar == $event->date_end_in_calendar) { - $event->ponctuel = 1; - //print 'x'.$datestart.'-'.$dateend;exit; - } - // Add event into $eventarray if date range are ok. if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar >= $lastdaytoshow) { //print 'x'.$datestart.'-'.$dateend;exit; @@ -1996,7 +1985,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa if ($event->type_code != 'ICALEVENT') { $savlabel = $event->label ? $event->label : $event->libelle; $event->label = $titletoshow; - $event->libelle = $titletoshow; + $event->libelle = $titletoshow; // deprecatd // Note: List of users are inside $event->userassigned. Link may be clickable depending on permissions of user. $titletoshow = (($event->type_picto || $event->type_code) ? $event->getTypePicto() : ''); $titletoshow .= $event->getNomUrl(0, $maxnbofchar, 'cal_event cal_event_title', '', 0, 0); @@ -2028,7 +2017,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa print '
('.dol_trunc($event->icalname, $maxnbofchar).')'; } - $thirdparty_id = ($event->thirdparty_id > 0 ? $event->thirdparty_id : ((is_object($event->societe) && $event->societe->id > 0) ? $event->societe->id : 0)); + $thirdparty_id = ($event->socid > 0 ? $event->socid : ((is_object($event->societe) && $event->societe->id > 0) ? $event->societe->id : 0)); $contact_id = ($event->contact_id > 0 ? $event->contact_id : ((is_object($event->contact) && $event->contact->id > 0) ? $event->contact->id : 0)); // If action related to company / contact diff --git a/htdocs/comm/action/pertype.php b/htdocs/comm/action/pertype.php index 43d55424cd3..eee8baa2b20 100644 --- a/htdocs/comm/action/pertype.php +++ b/htdocs/comm/action/pertype.php @@ -683,10 +683,6 @@ if ($resql) { $event->date_end_in_calendar = $datep; } } - // Define ponctual property - if ($event->date_start_in_calendar == $event->date_end_in_calendar) { - $event->ponctuel = 1; - } // Check values if ($event->date_end_in_calendar < $firstdaytoshow || diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index f74974a26d9..957ccd6e361 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -711,10 +711,6 @@ if ($resql) { $event->date_end_in_calendar = $datep; } } - // Define ponctual property - if ($event->date_start_in_calendar == $event->date_end_in_calendar) { - $event->ponctuel = 1; - } // Check values if ($event->date_end_in_calendar < $firstdaytoshow || diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 90d3ed128f7..eabcb1a55bf 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -214,7 +214,7 @@ if (empty($reshook)) { // assujetissement a la TVA if ($action == 'setassujtva' && $user->rights->societe->creer) { $object->fetch($id); - $object->tva_assuj = $_POST['assujtva_value']; + $object->tva_assuj = GETPOST('assujtva_value'); $result = $object->update($object->id); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); diff --git a/htdocs/comm/contact.php b/htdocs/comm/contact.php index 57a88bef157..62f57c008ba 100644 --- a/htdocs/comm/contact.php +++ b/htdocs/comm/contact.php @@ -157,10 +157,10 @@ if ($resql) { print ''; print ''.img_object($langs->trans("ShowContact"), "contact"); print ' '.$obj->name.''; - print "$obj->firstname"; + print ''.dol_escape_htmltag($obj->firstname).''; print ''.img_object($langs->trans("ShowCompany"), "company").' '; - print "rowid."\">$obj->name\n"; + print ''.$obj->name."\n"; print ''.dol_print_phone($obj->email, $obj->cidp, $obj->rowid, 'AC_EMAIL').''; diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php index 79faf4b2cd2..f82df06313b 100644 --- a/htdocs/comm/mailing/card.php +++ b/htdocs/comm/mailing/card.php @@ -745,7 +745,7 @@ if ($action == 'create') { print ''; print ''; print ''; print '
'.$langs->trans("MailTopic").'
'.$langs->trans("BackgroundColorByDefault").''; - print $htmlother->selectColor($_POST['bgcolor'], 'bgcolor', '', 0); + print $htmlother->selectColor(GETPOST('bgcolor'), 'bgcolor', '', 0); print '
'; diff --git a/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php b/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php index cfdca4a1fc2..f4295fa6583 100644 --- a/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php +++ b/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php @@ -230,7 +230,7 @@ class FormAdvTargetEmailing extends Form $InfoFieldList = explode(":", $param_list [0]); // 0 1 : tableName - // 1 2 : label field name Nom du champ contenant le libelle + // 1 2 : label field name Name of field that contains the label // 2 3 : key fields name (if differ of rowid) // 3 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value @@ -304,7 +304,7 @@ class FormAdvTargetEmailing extends Form if ($num) { while ($i < $num) { $obj = $this->db->fetch_object($resql); - // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut + // If a translation exists, we use it, else we use the default label $label = ($langs->trans("Civility".$obj->code) != "Civility".$obj->code ? $langs->trans("Civility".$obj->code) : ($obj->civilite != '-' ? $obj->civilite : '')); $options_array[$obj->code] = $label; diff --git a/htdocs/comm/mailing/class/mailing.class.php b/htdocs/comm/mailing/class/mailing.class.php index cb900f7ac7b..588faa392e3 100644 --- a/htdocs/comm/mailing/class/mailing.class.php +++ b/htdocs/comm/mailing/class/mailing.class.php @@ -740,7 +740,7 @@ class Mailing extends CommonObject global $action; $hookmanager->initHooks(array('emailingdao')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { $result = $hookmanager->resPrint; @@ -754,7 +754,7 @@ class Mailing extends CommonObject /** * Return label of status of emailing (draft, validated, ...) * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long + * @param int $mode 0=Long label, 1=Short label, 2=Picto+Short label, 3=Picto, 4=Picto+Short label, 5=Short label+Picto, 6=Picto+Long label, 7=Very short label+Picto * @return string Label */ public function getLibStatut($mode = 0) @@ -764,10 +764,10 @@ class Mailing extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Renvoi le libelle d'un statut donne + * Return the label of a given status * * @param int $status Id status - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @param int $mode 0=Long label, 1=Short label, 2=Picto+Short label, 3=Picto, 4=Picto+Short label, 5=Short label+Picto, 6=Picto+Long label, 7=Very short label+Picto * @return string Label */ public function LibStatut($status, $mode = 0) @@ -792,11 +792,11 @@ class Mailing extends CommonObject /** - * Renvoi le libelle d'un statut donne + * Return the label of a given status of a recipient * TODO Add class mailin_target.class.php * * @param int $status Id status - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @param int $mode 0=Long label, 1=Short label, 2=Picto+Short label, 3=Picto, 4=Picto+Short label, 5=Short label+Picto, 6=Picto+Long label, 7=Very short label+Picto * @param string $desc Desc error * @return string Label */ diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 45a4d2fdb57..61a406a2378 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -302,7 +302,7 @@ if (empty($reshook)) { } } } elseif ($action == 'setdate' && $usercancreate) { - $datep = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + $datep = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); if (empty($datep)) { $error++; @@ -316,7 +316,7 @@ if (empty($reshook)) { } } } elseif ($action == 'setecheance' && $usercancreate) { - $result = $object->set_echeance($user, dol_mktime(12, 0, 0, $_POST['echmonth'], $_POST['echday'], $_POST['echyear'])); + $result = $object->set_echeance($user, dol_mktime(12, 0, 0, GETPOST('echmonth', 'int'), GETPOST('echday', 'int'), GETPOST('echyear', 'int'))); if ($result >= 0) { if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { $outputlangs = $langs; @@ -339,7 +339,7 @@ if (empty($reshook)) { setEventMessages($object->error, $object->errors, 'errors'); } } elseif ($action == 'setdate_livraison' && $usercancreate) { - $result = $object->setDeliveryDate($user, dol_mktime(12, 0, 0, $_POST['date_livraisonmonth'], $_POST['date_livraisonday'], $_POST['date_livraisonyear'])); + $result = $object->setDeliveryDate($user, dol_mktime(12, 0, 0, GETPOST('date_livraisonmonth', 'int'), GETPOST('date_livraisonday', 'int'), GETPOST('date_livraisonyear', 'int'))); if ($result < 0) { dol_print_error($db, $object->error); } diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index 41ed388e044..f03d66bae54 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -1,7 +1,9 @@ - * Copyright (C) 2016 Laurent Destailleur - * Copyright (C) 2020 Thibault FOUCART +/* Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2016 Laurent Destailleur + * Copyright (C) 2020 Thibault FOUCART + * Copyright (C) 2022 ATM Consulting + * Copyright (C) 2022 OpenDSI * * 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 @@ -274,14 +276,17 @@ class Proposals extends DolibarrApi /** * Get lines of a commercial proposal * - * @param int $id Id of commercial proposal + * @param int $id Id of commercial proposal + * @param string $sqlfilters Other criteria to filter answers separated by a comma. d is the alias for proposal lines table, p is the alias for product table. "Syntax example "(p.ref:like:'SO-%') and (d.date_start:<:'20220101')" * * @url GET {id}/lines * * @return int */ - public function getLines($id) + public function getLines($id, $sqlfilters = '') { + $filters = ""; + if (!DolibarrApiAccess::$user->rights->propal->lire) { throw new RestException(401); } @@ -294,7 +299,16 @@ class Proposals extends DolibarrApi if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - $this->propal->getLinesArray(); + + if (!empty($sqlfilters)) { + if (!DolibarrApi::_checkFilters($sqlfilters)) { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $filters = " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + $this->propal->getLinesArray($filters); $result = array(); foreach ($this->propal->lines as $line) { array_push($result, $this->_cleanObjectDatas($line)); @@ -308,7 +322,7 @@ class Proposals extends DolibarrApi * @param int $id Id of commercial proposal to update * @param array $request_data Commercial proposal line data * - * @url POST {id}/lines + * @url POST {id}/line * * @return int */ @@ -368,6 +382,84 @@ class Proposals extends DolibarrApi } } + /** + * Add lines to given commercial proposal + * + * @param int $id Id of commercial proposal to update + * @param array $request_data Commercial proposal line data + * + * @url POST {id}/lines + * + * @return int + */ + public function postLines($id, $request_data = null) + { + if (!DolibarrApiAccess::$user->rights->propal->creer) { + throw new RestException(401); + } + + $result = $this->propal->fetch($id); + if (!$result) { + throw new RestException(404, 'Commercial Proposal not found'); + } + + if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $errors = []; + $this->db->begin(); + + foreach ($request_data as $TData) { + if (empty($TData[0])) $TData = array($TData); + + foreach ($TData as $lineData) { + $line = (object) $lineData; + + $updateRes = $this->propal->addline( + $line->desc, + $line->subprice, + $line->qty, + $line->tva_tx, + $line->localtax1_tx, + $line->localtax2_tx, + $line->fk_product, + $line->remise_percent, + 'HT', + 0, + $line->info_bits, + $line->product_type, + $line->rang, + $line->special_code, + $line->fk_parent_line, + $line->fk_fournprice, + $line->pa_ht, + $line->label, + $line->date_start, + $line->date_end, + $line->array_options, + $line->fk_unit, + $line->origin, + $line->origin_id, + $line->multicurrency_subprice, + $line->fk_remise_except + ); + + if ($updateRes < 0) { + $errors['lineLabel'] = $line->label; + $errors['msg'] = $this->propal->errors; + } + } + } + if (empty($errors)) { + $this->db->commit(); + return count($request_data); + } else { + $this->db->rollback(); + throw new RestException(400, implode(", ", $errors)); + } + } + /** * Update a line of given commercial proposal * diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index fd3bbfe7171..029706dfb5d 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -1,20 +1,22 @@ - * Copyright (C) 2004 Eric Seigne - * Copyright (C) 2004-2011 Laurent Destailleur - * Copyright (C) 2005 Marc Barilley - * Copyright (C) 2005-2013 Regis Houssin - * Copyright (C) 2006 Andre Cianfarani - * Copyright (C) 2008 Raphael Bertrand - * Copyright (C) 2010-2020 Juanjo Menent - * Copyright (C) 2010-2017 Philippe Grand - * Copyright (C) 2012-2014 Christophe Battarel - * Copyright (C) 2012 Cedric Salvador - * Copyright (C) 2013 Florian Henry - * Copyright (C) 2014-2015 Marcos García - * Copyright (C) 2018 Nicolas ZABOURI - * Copyright (C) 2018-2021 Frédéric France - * Copyright (C) 2018 Ferran Marcet +/* Copyright (C) 2002-2004 Rodolphe Quiedeville + * Copyright (C) 2004 Eric Seigne + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2005 Marc Barilley + * Copyright (C) 2005-2013 Regis Houssin + * Copyright (C) 2006 Andre Cianfarani + * Copyright (C) 2008 Raphael Bertrand + * Copyright (C) 2010-2020 Juanjo Menent + * Copyright (C) 2010-2017 Philippe Grand + * Copyright (C) 2012-2014 Christophe Battarel + * Copyright (C) 2012 Cedric Salvador + * Copyright (C) 2013 Florian Henry + * Copyright (C) 2014-2015 Marcos García + * Copyright (C) 2018 Nicolas ZABOURI + * Copyright (C) 2018-2021 Frédéric France + * Copyright (C) 2018 Ferran Marcet + * Copyright (C) 2022 ATM Consulting + * Copyright (C) 2022 OpenDSI * * 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 @@ -1246,7 +1248,7 @@ class Propal extends CommonObject break; } // Defined the new fk_parent_line - if ($result > 0 && $line->product_type == 9) { + if ($result > 0) { $fk_parent_line = $result; } } @@ -1714,12 +1716,13 @@ class Propal extends CommonObject /** * Load array lines * - * @param int $only_product Return only physical products - * @param int $loadalsotranslation Return translation for products + * @param int $only_product Return only physical products + * @param int $loadalsotranslation Return translation for products + * @param string $filters Filter on other fields * - * @return int <0 if KO, >0 if OK + * @return int <0 if KO, >0 if OK */ - public function fetch_lines($only_product = 0, $loadalsotranslation = 0) + public function fetch_lines($only_product = 0, $loadalsotranslation = 0, $filters = '') { global $langs, $conf; // phpcs:enable @@ -1738,6 +1741,9 @@ class Propal extends CommonObject if ($only_product) { $sql .= ' AND p.fk_product_type = 0'; } + if ($filters) { + $sql .= $filters; + } $sql .= ' ORDER by d.rang'; dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG); @@ -3563,7 +3569,7 @@ class Propal extends CommonObject */ public function getNomUrl($withpicto = 0, $option = '', $get_params = '', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = -1) { - global $langs, $conf, $user; + global $langs, $conf, $user, $hookmanager; if (!empty($conf->dol_no_mouse_hover)) { $notooltip = 1; // Force disable tooltips @@ -3684,17 +3690,27 @@ class Propal extends CommonObject } } + global $action; + $hookmanager->initHooks(array($this->element . 'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } /** * Retrieve an array of proposal lines + * @param string $filters Filter on other fields * * @return int >0 if OK, <0 if KO */ - public function getLinesArray() + public function getLinesArray($filters = '') { - return $this->fetch_lines(); + return $this->fetch_lines(0, 0, $filters); } /** diff --git a/htdocs/comm/propal/contact.php b/htdocs/comm/propal/contact.php index fedf6a6233d..989dcfe7098 100644 --- a/htdocs/comm/propal/contact.php +++ b/htdocs/comm/propal/contact.php @@ -107,12 +107,6 @@ if ($action == 'addcontact' && $user->rights->propale->creer) { dol_print_error($db); } } -/* -elseif ($action == 'setaddress' && $user->rights->propale->creer) -{ - $result=$object->setDeliveryAddress($_POST['fk_address']); - if ($result < 0) dol_print_error($db,$object->error); -}*/ /* diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index b6977940411..3e790bf6448 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -42,6 +42,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formpropal.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +if (!empty($conf->margin->enabled)) { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmargin.class.php'; +} require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; @@ -223,6 +226,10 @@ $arrayfields = array( 'p.multicurrency_total_invoiced'=>array('label'=>'MulticurrencyAmountInvoicedTTC', 'checked'=>0, 'enabled'=>!empty($conf->multicurrency->enabled) && !empty($conf->global->PROPOSAL_SHOW_INVOICED_AMOUNT)), 'u.login'=>array('label'=>"Author", 'checked'=>1, 'position'=>10), 'sale_representative'=>array('label'=>"SaleRepresentativesOfThirdParty", 'checked'=>-1), + 'total_pa' => array('label' => ($conf->global->MARGIN_TYPE == '1' ? 'BuyingPrice' : 'CostPrice'), 'checked' => 0, 'position' => 300, 'enabled' => (empty($conf->margin->enabled) || !$user->rights->margins->liretous ? 0 : 1)), + 'total_margin' => array('label' => 'Margin', 'checked' => 0, 'position' => 301, 'enabled' => (empty($conf->margin->enabled) || !$user->rights->margins->liretous ? 0 : 1)), + 'total_margin_rate' => array('label' => 'MarginRate', 'checked' => 0, 'position' => 302, 'enabled' => (empty($conf->margin->enabled) || !$user->rights->margins->liretous || empty($conf->global->DISPLAY_MARGIN_RATES) ? 0 : 1)), + 'total_mark_rate' => array('label' => 'MarkRate', 'checked' => 0, 'position' => 303, 'enabled' => (empty($conf->margin->enabled) || !$user->rights->margins->liretous || empty($conf->global->DISPLAY_MARK_RATES) ? 0 : 1)), 'p.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500), 'p.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500), 'p.date_cloture'=>array('label'=>"DateClosing", 'checked'=>0, 'position'=>500), @@ -486,6 +493,10 @@ $form = new Form($db); $formother = new FormOther($db); $formfile = new FormFile($db); $formpropal = new FormPropal($db); +$formmargin = null; +if (!empty($conf->margin->enabled)) { + $formmargin = new FormMargin($db); +} $companystatic = new Societe($db); $projectstatic = new Project($db); $formcompany = new FormCompany($db); @@ -1244,6 +1255,22 @@ if ($resql) { if (!empty($arrayfields['sale_representative']['checked'])) { print ''; } + if (!empty($arrayfields['total_pa']['checked'])) { + print ''; + print ''; + } + if (!empty($arrayfields['total_margin']['checked'])) { + print ''; + print ''; + } + if (!empty($arrayfields['total_margin_rate']['checked'])) { + print ''; + print ''; + } + if (!empty($arrayfields['total_mark_rate']['checked'])) { + print ''; + print ''; + } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; @@ -1392,6 +1419,18 @@ if ($resql) { if (!empty($arrayfields['sale_representative']['checked'])) { print_liste_field_titre($arrayfields['sale_representative']['label'], $_SERVER["PHP_SELF"], "", "", "$param", '', $sortfield, $sortorder); } + if (!empty($arrayfields['total_pa']['checked'])) { + print_liste_field_titre($arrayfields['total_pa']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + } + if (!empty($arrayfields['total_margin']['checked'])) { + print_liste_field_titre($arrayfields['total_margin']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + } + if (!empty($arrayfields['total_margin_rate']['checked'])) { + print_liste_field_titre($arrayfields['total_margin_rate']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + } + if (!empty($arrayfields['total_mark_rate']['checked'])) { + print_liste_field_titre($arrayfields['total_mark_rate']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + } $totalarray = array( 'nbfield' => 0, 'val' => array( @@ -1437,7 +1476,21 @@ if ($resql) { $i = 0; $typenArray = null; - while ($i < min($num, $limit)) { + $with_margin_info = false; + if (!empty($conf->margin->enabled) && ( + !empty($arrayfields['total_pa']['checked']) + || !empty($arrayfields['total_margin']['checked']) + || !empty($arrayfields['total_margin_rate']['checked']) + || !empty($arrayfields['total_mark_rate']['checked']) + ) + ) { + $with_margin_info = true; + } + $total_ht = 0; + $total_margin = 0; + + $last_num = min($num, $limit); + while ($i < $last_num) { $obj = $db->fetch_object($resql); $objectstatic->id = $obj->rowid; @@ -1487,6 +1540,14 @@ if ($resql) { } } + $marginInfo = array(); + if ($with_margin_info === true) { + $objectstatic->fetch_lines(); + $marginInfo = $formmargin->getMarginInfosArray($objectstatic); + $total_ht += $obj->total_ht; + $total_margin += $marginInfo['total_margin']; + } + print ''; if (!empty($arrayfields['p.ref']['checked'])) { @@ -1887,6 +1948,49 @@ if ($resql) { } } + // Total buying or cost price + if (!empty($arrayfields['total_pa']['checked'])) { + print ''.price($marginInfo['pa_total']).''; + if (!$i) { + $totalarray['nbfield']++; + } + } + // Total margin + if (!empty($arrayfields['total_margin']['checked'])) { + print ''.price($marginInfo['total_margin']).''; + if (!$i) { + $totalarray['nbfield']++; + } + if (!$i) { + $totalarray['pos'][$totalarray['nbfield']] = 'total_margin'; + } + $totalarray['val']['total_margin'] = $total_margin; + } + // Total margin rate + if (!empty($arrayfields['total_margin_rate']['checked'])) { + print ''.(($marginInfo['total_margin_rate'] == '') ? '' : price($marginInfo['total_margin_rate'], null, null, null, null, 2).'%').''; + if (!$i) { + $totalarray['nbfield']++; + } + } + // Total mark rate + if (!empty($arrayfields['total_mark_rate']['checked'])) { + print ''.(($marginInfo['total_mark_rate'] == '') ? '' : price($marginInfo['total_mark_rate'], null, null, null, null, 2).'%').''; + if (!$i) { + $totalarray['nbfield']++; + } + if (!$i) { + $totalarray['pos'][$totalarray['nbfield']] = 'total_mark_rate'; + } + if ($i >= $last_num - 1) { + if (!empty($total_ht)) { + $totalarray['val']['total_mark_rate'] = price2num($total_margin * 100 / $total_ht, 'MT'); + } else { + $totalarray['val']['total_mark_rate'] = ''; + } + } + } + // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook diff --git a/htdocs/comm/prospect/index.php b/htdocs/comm/prospect/index.php index 1e1caa796b5..0bcf2662a44 100644 --- a/htdocs/comm/prospect/index.php +++ b/htdocs/comm/prospect/index.php @@ -77,7 +77,7 @@ if (!empty($conf->propal->enabled)) { * */ -$sql = "SELECT count(*) as cc, st.libelle, st.picto, st.id"; +$sql = "SELECT count(*) as cc, st.libelle as stcomm, st.picto, st.id"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."c_stcomm as st "; if (empty($user->rights->societe->client->voir) && !$socid) { diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index 4404f9758a6..d44093dbab5 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -160,7 +160,7 @@ if ($action == 'setremise' && $user->rights->societe->creer) { $amount_ht = price2num(GETPOST('amount_ht', 'alpha')); $desc = GETPOST('desc', 'alpha'); $tva_tx = GETPOST('tva_tx', 'alpha'); - $discount_type = !empty($_POST['discount_type']) ?GETPOST('discount_type', 'alpha') : 0; + $discount_type = GETPOSTISSET('discount_type') ? GETPOST('discount_type', 'alpha') : 0; if ($amount_ht > 0) { $error = 0; diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 958ff542fed..9b11a477d52 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -421,7 +421,7 @@ if (empty($reshook)) { } // Defined the new fk_parent_line - if ($result > 0 && $lines[$i]->product_type == 9) { + if ($result > 0) { $fk_parent_line = $result; } } @@ -533,7 +533,6 @@ if (empty($reshook)) { } } } elseif ($action == 'setdate' && $usercancreate) { - // print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; $date = dol_mktime(0, 0, 0, GETPOST('order_month', 'int'), GETPOST('order_day', 'int'), GETPOST('order_year', 'int')); $result = $object->set_date($user, $date); @@ -541,7 +540,6 @@ if (empty($reshook)) { setEventMessages($object->error, $object->errors, 'errors'); } } elseif ($action == 'setdate_livraison' && $usercancreate) { - // print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; $date_delivery = dol_mktime(GETPOST('liv_hour', 'int'), GETPOST('liv_min', 'int'), 0, GETPOST('liv_month', 'int'), GETPOST('liv_day', 'int'), GETPOST('liv_year', 'int')); $object->fetch($id); diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 48b7e499dbb..a9ff2e09cf3 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -11,7 +11,7 @@ * Copyright (C) 2014-2015 Marcos García * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2016-2018 Ferran Marcet - * Copyright (C) 2021 Frédéric France + * Copyright (C) 2021-2022 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 @@ -495,7 +495,8 @@ class Commande extends CommonOrder $sql .= " SET ref = '".$this->db->escape($num)."',"; $sql .= " fk_statut = ".self::STATUS_VALIDATED.","; $sql .= " date_valid='".$this->db->idate($now)."',"; - $sql .= " fk_user_valid = ".((int) $user->id); + $sql .= " fk_user_valid = ".((int) $user->id).","; + $sql .= " fk_user_modif = ".((int) $user->id); $sql .= " WHERE rowid = ".((int) $this->id); dol_syslog(get_class($this)."::valid", LOG_DEBUG); @@ -625,7 +626,8 @@ class Commande extends CommonOrder $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."commande"; - $sql .= " SET fk_statut = ".self::STATUS_DRAFT; + $sql .= " SET fk_statut = ".self::STATUS_DRAFT.","; + $sql .= " fk_user_modif = ".((int) $user->id); $sql .= " WHERE rowid = ".((int) $this->id); if ($this->db->query($sql)) { @@ -699,7 +701,8 @@ class Commande extends CommonOrder $this->db->begin(); $sql = 'UPDATE '.MAIN_DB_PREFIX.'commande'; - $sql .= ' SET fk_statut='.self::STATUS_VALIDATED.', facture=0'; + $sql .= ' SET fk_statut='.self::STATUS_VALIDATED.', facture=0,'; + $sql .= " fk_user_modif = ".((int) $user->id); $sql .= " WHERE rowid = ".((int) $this->id); dol_syslog(get_class($this)."::set_reopen", LOG_DEBUG); @@ -760,7 +763,8 @@ class Commande extends CommonOrder $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; $sql .= ' SET fk_statut = '.self::STATUS_CLOSED.','; $sql .= ' fk_user_cloture = '.((int) $user->id).','; - $sql .= " date_cloture = '".$this->db->idate($now)."'"; + $sql .= " date_cloture = '".$this->db->idate($now)."',"; + $sql .= " fk_user_modif = ".((int) $user->id); $sql .= " WHERE rowid = ".((int) $this->id).' AND fk_statut > '.self::STATUS_DRAFT; if ($this->db->query($sql)) { @@ -808,7 +812,8 @@ class Commande extends CommonOrder $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."commande"; - $sql .= " SET fk_statut = ".self::STATUS_CANCELED; + $sql .= " SET fk_statut = ".self::STATUS_CANCELED.","; + $sql .= " fk_user_modif = ".((int) $user->id); $sql .= " WHERE rowid = ".((int) $this->id); $sql .= " AND fk_statut = ".self::STATUS_VALIDATED; @@ -1051,7 +1056,7 @@ class Commande extends CommonOrder return -1; } // Defined the new fk_parent_line - if ($result > 0 && $line->product_type == 9) { + if ($result > 0) { $fk_parent_line = $result; } } @@ -1784,7 +1789,7 @@ class Commande extends CommonOrder return -1; } - $sql = 'SELECT c.rowid, c.entity, c.date_creation, c.ref, c.fk_soc, c.fk_user_author, c.fk_user_valid, c.fk_statut'; + $sql = 'SELECT c.rowid, c.entity, c.date_creation, c.ref, c.fk_soc, c.fk_user_author, c.fk_user_valid, c.fk_user_modif, c.fk_statut'; $sql .= ', c.amount_ht, c.total_ht, c.total_ttc, c.total_tva, c.localtax1 as total_localtax1, c.localtax2 as total_localtax2, c.fk_cond_reglement, c.fk_mode_reglement, c.fk_availability, c.fk_input_reason'; $sql .= ', c.fk_account'; $sql .= ', c.date_commande, c.date_valid, c.tms'; @@ -1849,6 +1854,7 @@ class Commande extends CommonOrder $this->user_author_id = $obj->fk_user_author; $this->user_valid = $obj->fk_user_valid; + $this->user_modification = $obj->fk_user_modif; $this->total_ht = $obj->total_ht; $this->total_tva = $obj->total_tva; $this->total_localtax1 = $obj->total_localtax1; @@ -3657,7 +3663,7 @@ class Commande extends CommonOrder */ public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0) { - global $conf, $langs, $user; + global $conf, $langs, $user, $hookmanager; if (!empty($conf->dol_no_mouse_hover)) { $notooltip = 1; // Force disable tooltips @@ -3758,6 +3764,15 @@ class Commande extends CommonOrder } } + global $action; + $hookmanager->initHooks(array($this->element . 'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } diff --git a/htdocs/commande/contact.php b/htdocs/commande/contact.php index a4d857a47fd..b89623fc3a0 100644 --- a/htdocs/commande/contact.php +++ b/htdocs/commande/contact.php @@ -91,13 +91,6 @@ if ($action == 'addcontact' && $user->rights->commande->creer) { setEventMessages($object->error, $object->errors, 'errors'); } } -/* -elseif ($action == 'setaddress' && $user->rights->commande->creer) -{ - $object->fetch($id); - $result=$object->setDeliveryAddress($_POST['fk_address']); - if ($result < 0) dol_print_error($db,$object->error); -}*/ /* diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 48a3c294b26..27391d7a901 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -40,6 +40,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +if (!empty($conf->margin->enabled)) { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmargin.class.php'; +} require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; @@ -187,6 +190,10 @@ $arrayfields = array( 'c.multicurrency_total_ttc'=>array('label'=>'MulticurrencyAmountTTC', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1), 'position'=>110), 'u.login'=>array('label'=>"Author", 'checked'=>1, 'position'=>115), 'sale_representative'=>array('label'=>"SaleRepresentativesOfThirdParty", 'checked'=>0, 'position'=>116), + 'total_pa' => array('label' => ($conf->global->MARGIN_TYPE == '1' ? 'BuyingPrice' : 'CostPrice'), 'checked' => 0, 'position' => 300, 'enabled' => (empty($conf->margin->enabled) || !$user->rights->margins->liretous ? 0 : 1)), + 'total_margin' => array('label' => 'Margin', 'checked' => 0, 'position' => 301, 'enabled' => (empty($conf->margin->enabled) || !$user->rights->margins->liretous ? 0 : 1)), + 'total_margin_rate' => array('label' => 'MarginRate', 'checked' => 0, 'position' => 302, 'enabled' => (empty($conf->margin->enabled) || !$user->rights->margins->liretous || empty($conf->global->DISPLAY_MARGIN_RATES) ? 0 : 1)), + 'total_mark_rate' => array('label' => 'MarkRate', 'checked' => 0, 'position' => 303, 'enabled' => (empty($conf->margin->enabled) || !$user->rights->margins->liretous || empty($conf->global->DISPLAY_MARK_RATES) ? 0 : 1)), 'c.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>120), 'c.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>125), 'c.date_cloture'=>array('label'=>"DateClosing", 'checked'=>0, 'position'=>130), @@ -407,6 +414,10 @@ $now = dol_now(); $form = new Form($db); $formother = new FormOther($db); $formfile = new FormFile($db); +$formmargin = null; +if (!empty($conf->margin->enabled)) { + $formmargin = new FormMargin($db); +} $companystatic = new Societe($db); $formcompany = new FormCompany($db); $projectstatic = new Project($db); @@ -1193,6 +1204,22 @@ if ($resql) { if (!empty($arrayfields['sale_representative']['checked'])) { print ''; } + if (!empty($arrayfields['total_pa']['checked'])) { + print ''; + print ''; + } + if (!empty($arrayfields['total_margin']['checked'])) { + print ''; + print ''; + } + if (!empty($arrayfields['total_margin_rate']['checked'])) { + print ''; + print ''; + } + if (!empty($arrayfields['total_mark_rate']['checked'])) { + print ''; + print ''; + } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; // Fields from hook @@ -1354,6 +1381,18 @@ if ($resql) { if (!empty($arrayfields['sale_representative']['checked'])) { print_liste_field_titre($arrayfields['sale_representative']['label'], $_SERVER["PHP_SELF"], "", "", "$param", '', $sortfield, $sortorder); } + if (!empty($arrayfields['total_pa']['checked'])) { + print_liste_field_titre($arrayfields['total_pa']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + } + if (!empty($arrayfields['total_margin']['checked'])) { + print_liste_field_titre($arrayfields['total_margin']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + } + if (!empty($arrayfields['total_margin_rate']['checked'])) { + print_liste_field_titre($arrayfields['total_margin_rate']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + } + if (!empty($arrayfields['total_mark_rate']['checked'])) { + print_liste_field_titre($arrayfields['total_mark_rate']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + } $totalarray = array( 'nbfield' => 0, @@ -1413,7 +1452,22 @@ if ($resql) { $generic_product = new Product($db); $userstatic = new User($db); $i = 0; - while ($i < min($num, $limit)) { + + $with_margin_info = false; + if (!empty($conf->margin->enabled) && ( + !empty($arrayfields['total_pa']['checked']) + || !empty($arrayfields['total_margin']['checked']) + || !empty($arrayfields['total_margin_rate']['checked']) + || !empty($arrayfields['total_mark_rate']['checked']) + ) + ) { + $with_margin_info = true; + } + $total_ht = 0; + $total_margin = 0; + + $last_num = min($num, $limit); + while ($i < $last_num) { $obj = $db->fetch_object($resql); $notshippable = 0; @@ -1455,6 +1509,14 @@ if ($resql) { $projectstatic->ref = $obj->project_ref; $projectstatic->title = $obj->project_label; + $marginInfo = array(); + if ($with_margin_info === true) { + $generic_commande->fetch_lines(); + $marginInfo = $formmargin->getMarginInfosArray($generic_commande); + $total_ht += $obj->total_ht; + $total_margin += $marginInfo['total_margin']; + } + print ''; // Ref @@ -1462,11 +1524,6 @@ if ($resql) { print ''; print $generic_commande->getNomUrl(1, ($search_status != 2 ? 0 : $obj->fk_statut), 0, 0, 0, 1, 1); - // Warning late icon and note - if ($generic_commande->hasDelay()) { - print img_picto($langs->trans("Late").' : '.$generic_commande->showDelay(), "warning"); - } - $filename = dol_sanitizeFileName($obj->ref); $filedir = $conf->commande->multidir_output[$conf->entity].'/'.dol_sanitizeFileName($obj->ref); $urlsource = $_SERVER['PHP_SELF'].'?id='.$obj->rowid; @@ -1590,6 +1647,10 @@ if ($resql) { if (!empty($arrayfields['c.date_commande']['checked'])) { print ''; print dol_print_date($db->jdate($obj->date_commande), 'day'); + // Warning late icon and note + if ($generic_commande->hasDelay()) { + print img_picto($langs->trans("Late").' : '.$generic_commande->showDelay(), "warning"); + } print ''; if (!$i) { $totalarray['nbfield']++; @@ -1792,6 +1853,49 @@ if ($resql) { } } + // Total buying or cost price + if (!empty($arrayfields['total_pa']['checked'])) { + print ''.price($marginInfo['pa_total']).''; + if (!$i) { + $totalarray['nbfield']++; + } + } + // Total margin + if (!empty($arrayfields['total_margin']['checked'])) { + print ''.price($marginInfo['total_margin']).''; + if (!$i) { + $totalarray['nbfield']++; + } + if (!$i) { + $totalarray['pos'][$totalarray['nbfield']] = 'total_margin'; + } + $totalarray['val']['total_margin'] += $marginInfo['total_margin']; + } + // Total margin rate + if (!empty($arrayfields['total_margin_rate']['checked'])) { + print ''.(($marginInfo['total_margin_rate'] == '') ? '' : price($marginInfo['total_margin_rate'], null, null, null, null, 2).'%').''; + if (!$i) { + $totalarray['nbfield']++; + } + } + // Total mark rate + if (!empty($arrayfields['total_mark_rate']['checked'])) { + print ''.(($marginInfo['total_mark_rate'] == '') ? '' : price($marginInfo['total_mark_rate'], null, null, null, null, 2).'%').''; + if (!$i) { + $totalarray['nbfield']++; + } + if (!$i) { + $totalarray['pos'][$totalarray['nbfield']] = 'total_mark_rate'; + } + if ($i >= $last_num - 1) { + if (!empty($total_ht)) { + $totalarray['val']['total_mark_rate'] = price2num($total_margin * 100 / $total_ht, 'MT'); + } else { + $totalarray['val']['total_mark_rate'] = ''; + } + } + } + // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook diff --git a/htdocs/compta/ajaxpayment.php b/htdocs/compta/ajaxpayment.php index d22e1a0182a..0332a925f9d 100644 --- a/htdocs/compta/ajaxpayment.php +++ b/htdocs/compta/ajaxpayment.php @@ -47,28 +47,32 @@ $langs->load('compta'); //init var $invoice_type = GETPOST('invoice_type', 'int'); -$amountPayment = $_POST['amountPayment']; -$amounts = $_POST['amounts']; // from text inputs : invoice amount payment (check required) -$remains = $_POST['remains']; // from dolibarr's object (no need to check) -$currentInvId = $_POST['imgClicked']; // from DOM elements : imgId (equals invoice id) +$amountPayment = GETPOST('amountPayment'); +$amounts = GETPOST('amounts'); // from text inputs : invoice amount payment (check required) +$remains = GETPOST('remains'); // from dolibarr's object (no need to check) +$currentInvId = GETPOST('imgClicked'); // from DOM elements : imgId (equals invoice id) // Getting the posted keys=>values, sanitize the ones who are from text inputs $amountPayment = $amountPayment != '' ? (is_numeric(price2num($amountPayment)) ? price2num($amountPayment) : '') : ''; // keep void if not a valid entry // Clean checkamounts -foreach ($amounts as $key => $value) { - $value = price2num($value); - $amounts[$key] = $value; - if (empty($value)) { - unset($amounts[$key]); +if (is_array($amounts)) { + foreach ($amounts as $key => $value) { + $value = price2num($value); + $amounts[$key] = $value; + if (empty($value)) { + unset($amounts[$key]); + } } } // Clean remains -foreach ($remains as $key => $value) { - $value = price2num($value); - $remains[$key] = (($invoice_type) == 2 ?-1 : 1) * $value; - if (empty($value)) { - unset($remains[$key]); +if (is_array($remains)) { + foreach ($remains as $key => $value) { + $value = price2num($value); + $remains[$key] = (($invoice_type) == 2 ?-1 : 1) * $value; + if (empty($value)) { + unset($remains[$key]); + } } } diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index 524d8c79d4a..e991831a6dd 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -1339,14 +1339,15 @@ if ($resql) { $labeltoshow = $langs->trans($reg[1]); } else { if ($objp->label == '(payment_salary)') { - $labeltoshow = dol_trunc($langs->trans("SalaryPayment", 40)); + $labeltoshow = $langs->trans("SalaryPayment"); } else { $labeltoshow = dol_escape_htmltag($objp->label); $titletoshow = $objp->label; } } - print ''; - print $labeltoshow; // Already escaped + + + print ''; // Add info about links after description $cachebankaccount = array(); @@ -1355,70 +1356,70 @@ if ($resql) { if ($links[$key]['type'] == 'withdraw') { $banktransferstatic->id = $links[$key]['url_id']; $banktransferstatic->ref = $links[$key]['label']; - print ' '.$banktransferstatic->getNomUrl(0); + print $banktransferstatic->getNomUrl(0).' '; } elseif ($links[$key]['type'] == 'payment') { $paymentstatic->id = $links[$key]['url_id']; $paymentstatic->ref = $links[$key]['url_id']; // FIXME This is id, not ref of payment $paymentstatic->date = $db->jdate($objp->do); - print ' '.$paymentstatic->getNomUrl(2); + print $paymentstatic->getNomUrl(2).' '; } elseif ($links[$key]['type'] == 'payment_supplier') { $paymentsupplierstatic->id = $links[$key]['url_id']; $paymentsupplierstatic->ref = $links[$key]['url_id']; // FIXME This is id, not ref of payment - print ' '.$paymentsupplierstatic->getNomUrl(2); + print $paymentsupplierstatic->getNomUrl(2).' '; } elseif ($links[$key]['type'] == 'payment_sc') { $paymentscstatic->id = $links[$key]['url_id']; $paymentscstatic->ref = $links[$key]['url_id']; $paymentscstatic->label = $links[$key]['label']; - print ' '.$paymentscstatic->getNomUrl(2); + print $paymentscstatic->getNomUrl(2).' '; } elseif ($links[$key]['type'] == 'payment_vat') { $paymentvatstatic->id = $links[$key]['url_id']; $paymentvatstatic->ref = $links[$key]['url_id']; - print ' '.$paymentvatstatic->getNomUrl(2); + print $paymentvatstatic->getNomUrl(2).' '; } elseif ($links[$key]['type'] == 'payment_salary') { $paymentsalstatic->id = $links[$key]['url_id']; $paymentsalstatic->ref = $links[$key]['url_id']; $paymentsalstatic->label = $links[$key]['label']; - print ' '.$paymentsalstatic->getNomUrl(2); + print $paymentsalstatic->getNomUrl(2).' '; } elseif ($links[$key]['type'] == 'payment_loan') { print ''; print ' '.img_object($langs->trans('ShowPayment'), 'payment').' '; - print ''; + print ' '; } elseif ($links[$key]['type'] == 'payment_donation') { $paymentdonationstatic->id = $links[$key]['url_id']; $paymentdonationstatic->ref = $links[$key]['url_id']; - print ' '.$paymentdonationstatic->getNomUrl(2); + print $paymentdonationstatic->getNomUrl(2).' '; } elseif ($links[$key]['type'] == 'payment_expensereport') { $paymentexpensereportstatic->id = $links[$key]['url_id']; $paymentexpensereportstatic->ref = $links[$key]['url_id']; - print ' '.$paymentexpensereportstatic->getNomUrl(2); + print $paymentexpensereportstatic->getNomUrl(2).' '; } elseif ($links[$key]['type'] == 'payment_various') { $paymentvariousstatic->id = $links[$key]['url_id']; $paymentvariousstatic->ref = $links[$key]['url_id']; - print ' '.$paymentvariousstatic->getNomUrl(2); + print $paymentvariousstatic->getNomUrl(2).' '; } elseif ($links[$key]['type'] == 'banktransfert') { // Do not show link to transfer since there is no transfer card (avoid confusion). Can already be accessed from transaction detail. if ($objp->amount > 0) { $banklinestatic->fetch($links[$key]['url_id']); $bankstatic->id = $banklinestatic->fk_account; $bankstatic->label = $banklinestatic->bank_account_ref; - print ' ('.$langs->trans("TransferFrom").' '; + print $langs->trans("TransferFrom").' '; print $bankstatic->getNomUrl(1, 'transactions'); print ' '.$langs->trans("toward").' '; $bankstatic->id = $objp->bankid; $bankstatic->label = $objp->bankref; print $bankstatic->getNomUrl(1, ''); - print ')'; + print ' - '; } else { $bankstatic->id = $objp->bankid; $bankstatic->label = $objp->bankref; - print ' ('.$langs->trans("TransferFrom").' '; + print $langs->trans("TransferFrom").' '; print $bankstatic->getNomUrl(1, ''); print ' '.$langs->trans("toward").' '; $banklinestatic->fetch($links[$key]['url_id']); $bankstatic->id = $banklinestatic->fk_account; $bankstatic->label = $banklinestatic->bank_account_ref; print $bankstatic->getNomUrl(1, 'transactions'); - print ')'; + print ' - '; } //var_dump($links); } elseif ($links[$key]['type'] == 'company') { @@ -1430,22 +1431,22 @@ if ($resql) { // Information is already shown using the payment_salary link. No need of this link. } else { // Show link with label $links[$key]['label'] - if (!empty($objp->label) && !empty($links[$key]['label'])) { - print ' - '; - } print ''; if (preg_match('/^\((.*)\)$/i', $links[$key]['label'], $reg)) { // Label generique car entre parentheses. On l'affiche en le traduisant if ($reg[1] == 'paiement') { $reg[1] = 'Payment'; } - print ' '.$langs->trans($reg[1]); + print $langs->trans($reg[1]); } else { - print ' '.$links[$key]['label']; + print $links[$key]['label']; } - print ''; + print ''.($labeltoshow ? ' - ' : ''); } } + + print $labeltoshow; // Already escaped + print ''; if (!$i) { $totalarray['nbfield']++; @@ -1488,7 +1489,7 @@ if ($resql) { // Payment type if (!empty($arrayfields['type']['checked'])) { - print ''; + print ''; $labeltype = ($langs->trans("PaymentTypeShort".$objp->fk_type) != "PaymentTypeShort".$objp->fk_type) ? $langs->trans("PaymentTypeShort".$objp->fk_type) : $langs->getLabelFromKey($db, $objp->fk_type, 'c_paiement', 'code', 'libelle', '', 1); if ($labeltype == 'SOLD') { print ' '; //$langs->trans("InitialBankBalance"); @@ -1514,9 +1515,9 @@ if ($resql) { print ''; $companylinked_id = 0; - $userlinked_id = 0; + $userlinked_id = 0; - //payment line type to define user display and user or company linked + //payment line type to define user display and user or company linked foreach ($links as $key => $value) { if ($links[$key]['type'] == 'payment_sc') { $type_link = 'payment_sc'; diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 8430d9e7440..4e37268756d 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -283,7 +283,7 @@ if (empty($reshook)) { $categories = GETPOST('categories', 'array'); $object->setCategories($categories); - $_GET["id"] = $_POST["id"]; // Force chargement page en mode visu + $_GET["id"] = GETPOST("id", 'int'); // Force chargement page en mode visu } else { $error++; setEventMessages($object->error, $object->errors, 'errors'); diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index c2745b31426..cb2de5aca46 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -1511,10 +1511,10 @@ class Account extends CommonObject { $country_code = $this->getCountryCode(); - if (in_array($country_code, array('AD', 'FR', 'ES', 'GA', 'IT', 'NC'))) { + if (in_array($country_code, array('FR', 'ES', 'GA', 'IT', 'NC'))) { return 1; // France, Spain, Gabon, ... - Not valid for CH } - if (in_array($country_code, array('AU', 'BE', 'CA', 'DE', 'DK', 'GR', 'GB', 'ID', 'IE', 'IR', 'KR', 'NL', 'NZ', 'UK', 'US'))) { + if (in_array($country_code, array('AD', 'AU', 'BE', 'CA', 'DE', 'DK', 'GR', 'GB', 'ID', 'IE', 'IR', 'KR', 'NL', 'NZ', 'UK', 'US'))) { return 2; // Australia, England... } return 0; diff --git a/htdocs/compta/bank/class/paymentvarious.class.php b/htdocs/compta/bank/class/paymentvarious.class.php index d88676563d6..cdcd26490a3 100644 --- a/htdocs/compta/bank/class/paymentvarious.class.php +++ b/htdocs/compta/bank/class/paymentvarious.class.php @@ -721,7 +721,7 @@ class PaymentVarious extends CommonObject global $action; $hookmanager->initHooks(array('variouspayment')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { $result = $hookmanager->resPrint; diff --git a/htdocs/compta/cashcontrol/class/cashcontrol.class.php b/htdocs/compta/cashcontrol/class/cashcontrol.class.php index 5308c8df1d6..63dae3a3a1c 100644 --- a/htdocs/compta/cashcontrol/class/cashcontrol.class.php +++ b/htdocs/compta/cashcontrol/class/cashcontrol.class.php @@ -466,7 +466,7 @@ class CashControl extends CommonObject global $action; $hookmanager->initHooks(array('cashfencedao')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { $result = $hookmanager->resPrint; diff --git a/htdocs/compta/facture/card-rec.php b/htdocs/compta/facture/card-rec.php index a76332197bc..a30abcc9ca1 100644 --- a/htdocs/compta/facture/card-rec.php +++ b/htdocs/compta/facture/card-rec.php @@ -488,7 +488,7 @@ if (empty($reshook)) { // Define special_code for special lines $special_code = 0; - // if (empty($_POST['qty'])) $special_code=3; // Options should not exists on invoices + // if (!GETPOST('qty')) $special_code=3; // Options should not exists on invoices // Ecrase $pu par celui du produit // Ecrase $desc par celui du produit @@ -1354,6 +1354,7 @@ if ($action == 'create') { $dateexample = $object->date_when; } + // Help of substitution key $substitutionarray = getCommonSubstitutionArray($langs, 2, null, $object); $substitutionarray['__INVOICE_PREVIOUS_MONTH__'] = $langs->trans("PreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%m').')'; diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index f2b26c73242..278a7837374 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -130,6 +130,7 @@ $usercanread = $user->rights->facture->lire; $usercancreate = $user->rights->facture->creer; $usercanissuepayment = $user->rights->facture->paiement; $usercandelete = $user->rights->facture->supprimer; +$usercancreatecontract = $user->rights->contrat->creer; $usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->facture->invoice_advance->validate))); $usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->facture->invoice_advance->send))); $usercanreopen = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->facture->invoice_advance->reopen))); @@ -366,7 +367,7 @@ if (empty($reshook)) { } } elseif ($action == 'classin' && $usercancreate) { $object->fetch($id); - $object->setProject($_POST['projectid']); + $object->setProject(GETPOST('projectid', 'int')); } elseif ($action == 'setmode' && $usercancreate) { $object->fetch($id); $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); @@ -488,7 +489,7 @@ if (empty($reshook)) { } } elseif ($action == 'setpaymentterm' && $usercancreate) { $object->fetch($id); - $object->date_lim_reglement = dol_mktime(12, 0, 0, $_POST['paymenttermmonth'], $_POST['paymenttermday'], $_POST['paymenttermyear']); + $object->date_lim_reglement = dol_mktime(12, 0, 0, GETPOST('paymenttermmonth', 'int'), GETPOST('paymenttermday', 'int'), GETPOST('paymenttermyear', 'int')); if ($object->date_lim_reglement < $object->date) { $object->date_lim_reglement = $object->calculate_date_lim_reglement(); setEventMessages($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"), null, 'warnings'); @@ -609,7 +610,7 @@ if (empty($reshook)) { // Check parameters // Check for mandatory fields in thirdparty (defined into setup) - $array_to_check = array('IDPROF1', 'IDPROF2', 'IDPROF3', 'IDPROF4', 'IDPROF5', 'IDPROF6', 'EMAIL'); + $array_to_check = array('IDPROF1', 'IDPROF2', 'IDPROF3', 'IDPROF4', 'IDPROF5', 'IDPROF6', 'EMAIL', 'ACCOUNTANCY_CODE_CUSTOMER'); foreach ($array_to_check as $key) { $keymin = strtolower($key); $i = (int) preg_replace('/[^0-9]/', '', $key); @@ -637,6 +638,14 @@ if (empty($reshook)) { setEventMessages($langs->trans("ErrorBadEMail", $object->thirdparty->email).' ('.$langs->trans("ForbiddenBySetupRules").')', null, 'errors'); } } + if ($key == 'ACCOUNTANCY_CODE_CUSTOMER') { + // Check for mandatory + if (!empty($conf->global->SOCIETE_ACCOUNTANCY_CODE_CUSTOMER_INVOICE_MANDATORY) && empty($object->thirdparty->code_compta)) { + $langs->load("errors"); + $error++; + setEventMessages($langs->trans("ErrorAccountancyCodeCustomerIsMandatory", $object->thirdparty->name).' ('.$langs->trans("ForbiddenBySetupRules").')', null, 'errors'); + } + } } } @@ -1261,7 +1270,7 @@ if (empty($reshook)) { $object->lines[] = $line; // insert new line in current object // Defined the new fk_parent_line - if ($result > 0 && $line->product_type == 9) { + if ($result > 0) { $fk_parent_line = $result; } } @@ -1772,7 +1781,7 @@ if (empty($reshook)) { } // Defined the new fk_parent_line - if ($result > 0 && $lines[$i]->product_type == 9) { + if ($result > 0) { $fk_parent_line = $result; } } @@ -2101,7 +2110,7 @@ if (empty($reshook)) { // Define special_code for special lines $special_code = 0; - // if (empty($_POST['qty'])) $special_code=3; // Options should not exists on invoices + // if (!GETPOST(qty)) $special_code=3; // Options should not exists on invoices // Ecrase $pu par celui du produit // Ecrase $desc par celui du produit @@ -2275,7 +2284,7 @@ if (empty($reshook)) { } // Insert line - $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $date_start, $date_end, 0, $info_bits, '', $price_base_type, $pu_ttc, $type, - 1, $special_code, '', 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_options, $_POST['progress'], '', $fk_unit, $pu_ht_devise); + $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $date_start, $date_end, 0, $info_bits, '', $price_base_type, $pu_ttc, $type, - 1, $special_code, '', 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_options, GETPOST('progress'), '', $fk_unit, $pu_ht_devise); if ($result > 0) { // Define output language and generate document @@ -2570,7 +2579,7 @@ if (empty($reshook)) { setEventMessages($object->error, $object->errors, 'errors'); } } - } elseif ($action == 'updatealllines' && $usercancreate && $_POST['all_percent'] == $langs->trans('Modifier')) { // Update all lines of situation invoice + } elseif ($action == 'updatealllines' && $usercancreate && GETPOST('all_percent') == $langs->trans('Modifier')) { // Update all lines of situation invoice if (!$object->fetch($id) > 0) { dol_print_error($db); } @@ -2583,11 +2592,11 @@ if (empty($reshook)) { setEventMessages($mesg, null, 'warnings'); $result = -1; } else { - $object->update_percent($line, $_POST['all_progress']); + $object->update_percent($line, GETPOST('all_progress')); } } } - } elseif ($action == 'updateline' && $usercancreate && $_POST['cancel'] == $langs->trans("Cancel")) { + } elseif ($action == 'updateline' && $usercancreate && !$cancel) { header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); // To show again edited page exit(); } elseif ($action == 'confirm_situationout' && $confirm == 'yes' && $usercancreate) { @@ -3420,6 +3429,10 @@ if ($action == 'create') { $optionsav .= '