diff --git a/README.md b/README.md index 136f946a257..607ab21f166 100644 --- a/README.md +++ b/README.md @@ -34,12 +34,12 @@ There is a lot of different solutions to install Dolibarr. ### Using packages -If you have low technical skills and you're looking to install Dolibarr ERP/CRM with just a few clicks, you can use one of the packaged versions: +If you have low technical skills and you're looking to install Dolibarr ERP/CRM with just few clicks, you can use one of the packaged versions (see next chapter if you have IT knowledge) : - [DoliWamp for Windows](https://wiki.dolibarr.org/index.php/Dolibarr_for_Windows_(DoliWamp)) -- [DoliDeb for Debian](https://wiki.dolibarr.org/index.php/Dolibarr_for_Ubuntu_or_Debian) +- [DoliDeb for Debian, Ubuntu](https://wiki.dolibarr.org/index.php/Dolibarr_for_Ubuntu_or_Debian) - DoliRpm for Red Hat, Fedora, OpenSuse, Mandriva or Mageia -- The Docker image (see next chapter) +- The Docker image (see chapter "Using Docker") Releases can be downloaded from [official website](https://www.dolibarr.org/). diff --git a/dev/build/makepack-howto.txt b/dev/build/makepack-howto.txt index 61a6006f0ae..b23b21e1bd7 100644 --- a/dev/build/makepack-howto.txt +++ b/dev/build/makepack-howto.txt @@ -1,14 +1,14 @@ ----- Dolibarr Makepack How To ----- -This documentation describe steps to build a BETA or RELEASE versions -of Dolibarr. There is a chapter for BETA version and a chapter for RELEASE version. +This documentation describe steps to build a BETA or RELEASE versions of Dolibarr. +There is a chapter for BETA version and a chapter for RELEASE version. -***** Prerequisites For Linux ***** +***** Prerequisites on Linux ***** -Prerequisites to build tgz, debian and rpm packages: +Prerequisites to build the tgz, debian and rpm packages: > apt-get install perl tar dpkg dpatch p7zip-full rpm zip php-cli -Prerequisites to build autoexe DoliWamp package from Linux (solution seems broken since Ubuntu 20.04): +Prerequisites to build autoexe DoliWamp package from Linux (solution seems broken since Ubuntu 20.04+): > apt-get install wine q4wine > Launch "wine cmd" to check a drive Z: pointing to / exists. > Install InnoSetup @@ -23,7 +23,7 @@ Prerequisites to build autoexe DoliWamp package from Linux (solution seems broke The .exe file will be build into directory build. -***** Prerequisites For Windows ***** +***** Prerequisites on Windows ***** Prerequisites to build autoexe DoliWamp package from Windows: @@ -49,9 +49,9 @@ This files describe steps made by Dolibarr packaging team to make a beta version - Check all files are committed. - Update version/info in ChangeLog, for this you can: -To generate a changelog of a major new version x.y.0 (from a repo on branch develop), you can do "cd ~/git/dolibarr; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent develop) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa" -To generate a changelog of a major new version x.y.0 (from a repo on branch x.y repo), you can do "cd ~/git/dolibarr_x.y; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent x.y.0) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa" -To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dolibarr_x.y; git log x.y.z-1.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa" +To generate a changelog of a major new version x.y.0 (from a repo on branch develop), you can do "cd ~/git/dolibarr; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent develop) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/changelogtocopy" +To generate a changelog of a major new version x.y.0 (from a repo on branch x.y repo), you can do "cd ~/git/dolibarr_x.y; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent x.y.0) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/changelogtocopy" +To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dolibarr_x.y; git log x.y.z-1.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/changelogtocopy" Recopy the content of the output file into the file ChangeLog. - Note: To know number of lines changes: git diff --shortstat A B - Update version number with x.y.z-w in file htdocs/filefunc.inc.php @@ -67,15 +67,15 @@ Recopy the content of the output file into the file ChangeLog. ***** Actions to do a RELEASE ***** This files describe steps made by Dolibarr packaging team to make a complete release of Dolibarr, step by step. -We suppose the branch x.y has already been created during the beta (see previous step). +We suppose the branch x.y has already been created during the beta (see previous step) and we want to release a version x.y.z (with z >= 0) - Check all files are committed. -- Update version/info in ChangeLog, for this you can: -To generate a changelog of a major new version x.y.0 (from a repo on branch develop), you can do "cd ~/git/dolibarr; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent develop) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa" -To generate a changelog of a major new version x.y.0 (from a repo pn branch x.y), you can do "cd ~/git/dolibarr_x.y; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent x.y.0) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa" -To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dolibarr_x.y; git log x.y.z-1.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa" +- Update version/info in ChangeLog, for this: +To generate a changelog of a major new version x.y.0 (from a repo on branch develop), you can do "cd ~/git/dolibarr; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent develop) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/changelogtocopy" +To generate a changelog of a major new version x.y.0 (from a repo pn branch x.y), you can do "cd ~/git/dolibarr_x.y; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent x.y.0) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/changelogtocopy" +To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dolibarr_x.y; git log x.y.z-1.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/changelogtocopy" Recopy the content of the output file into the file ChangeLog. -- Note: To know the number of lines changes: git diff --shortstat A B +- Note: To know the number of lines changes: git diff --shortstat vA vB - Update version number with x.y.z in file htdocs/filefunc.inc.php - Commit all changes. @@ -84,6 +84,6 @@ Recopy the content of the output file into the file ChangeLog. - Check content of built packages. - Run makepack-dolibarr.pl again with option to publish files on dolibarr foundation server (Dir /home/dolibarr/wwwroot/files/stable on www.dolibarr.org). -- Run makepack-dolibarr.pl again with option to publish files on sourceforge. This will also add official tag. +- Run makepack-dolibarr.pl again with option to publish files on sourceforge. This will also add the official tag x.y.z. -- Post a news on dolibarr.org/dolibarr.fr + social networks +- Post a news in english dolibarr.org/dolibarr.fr web site by cloning a past news (the news will be propagated on social networks) diff --git a/dev/build/phpstan/phpstan-baseline.neon b/dev/build/phpstan/phpstan-baseline.neon index 2d9c290b25a..01c75984c0d 100644 --- a/dev/build/phpstan/phpstan-baseline.neon +++ b/dev/build/phpstan/phpstan-baseline.neon @@ -9540,12 +9540,6 @@ parameters: count: 1 path: ../../../htdocs/core/class/dolgraph.class.php - - - message: '#^Comparison operation "\>" between 0 and 0 is always false\.$#' - identifier: greater.alwaysFalse - count: 3 - path: ../../../htdocs/core/class/dolgraph.class.php - - message: '#^If condition is always false\.$#' identifier: if.alwaysFalse @@ -9564,24 +9558,6 @@ parameters: count: 1 path: ../../../htdocs/core/class/dolgraph.class.php - - - message: '#^Loose comparison using \=\= between 0 and 0 will always evaluate to true\.$#' - identifier: equal.alwaysTrue - count: 2 - path: ../../../htdocs/core/class/dolgraph.class.php - - - - message: '#^Loose comparison using \=\= between 1 and 3 will always evaluate to false\.$#' - identifier: equal.alwaysFalse - count: 1 - path: ../../../htdocs/core/class/dolgraph.class.php - - - - message: '#^Offset 0 on array\{array\{stacknum\: int, legend\: mixed, legendwithgroup\: non\-falsy\-string\}\} in empty\(\) always exists and is not falsy\.$#' - identifier: empty.offset - count: 1 - path: ../../../htdocs/core/class/dolgraph.class.php - - message: '#^Ternary operator condition is always true\.$#' identifier: ternary.alwaysTrue @@ -14670,24 +14646,12 @@ parameters: count: 12 path: ../../../htdocs/core/tpl/card_presend.tpl.php - - - message: '#^Variable \$hidedesc might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/core/tpl/card_presend.tpl.php - - message: '#^Variable \$hidedetails might not be defined\.$#' identifier: variable.undefined count: 1 path: ../../../htdocs/core/tpl/card_presend.tpl.php - - - message: '#^Variable \$hideref might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/core/tpl/card_presend.tpl.php - - message: '#^Variable \$hookmanager might not be defined\.$#' identifier: variable.undefined @@ -15444,12 +15408,6 @@ parameters: count: 1 path: ../../../htdocs/cron/list.php - - - message: '#^Variable \$texttoshow might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/cron/list.php - - message: '#^Offset ''css'' on array\{css\: ''minwidth200'', picto\: mixed\} in empty\(\) always exists and is not falsy\.$#' identifier: empty.offset @@ -15510,12 +15468,6 @@ parameters: count: 1 path: ../../../htdocs/delivery/card.php - - - message: '#^Variable \$arrayoptions might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/delivery/card.php - - message: '#^Variable \$hidedesc might not be defined\.$#' identifier: variable.undefined @@ -15786,42 +15738,12 @@ parameters: count: 1 path: ../../../htdocs/don/paiement/list.php - - - message: '#^Variable \$morecss might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/don/paiement/list.php - - - - message: '#^Variable \$morejs might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/don/paiement/list.php - - - - message: '#^Variable \$outputlangs might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/don/payment/card.php - - message: '#^Negated boolean expression is always true\.$#' identifier: booleanNot.alwaysTrue count: 1 path: ../../../htdocs/don/payment/payment.php - - - message: '#^Variable \$sumpaid might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../../htdocs/don/payment/payment.php - - - - message: '#^Variable \$objectlink might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/don/tpl/linkedobjectblock.tpl.php - - message: '#^Property EcmFiles\:\:\$acl \(string\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -15960,12 +15882,6 @@ parameters: count: 1 path: ../../../htdocs/ecm/dir_card.php - - - message: '#^Variable \$oldlabel might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/ecm/dir_card.php - - message: '#^If condition is always false\.$#' identifier: if.alwaysFalse @@ -16002,12 +15918,6 @@ parameters: count: 2 path: ../../../htdocs/ecm/file_card.php - - - message: '#^Variable \$relativepath might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/ecm/index.php - - message: '#^If condition is always true\.$#' identifier: if.alwaysTrue @@ -16338,12 +16248,6 @@ parameters: count: 1 path: ../../../htdocs/eventorganization/conferenceorboothattendee_card.php - - - message: '#^Variable \$confOrBooth might not be defined\.$#' - identifier: variable.undefined - count: 4 - path: ../../../htdocs/eventorganization/conferenceorboothattendee_card.php - - message: '#^Variable \$text might not be defined\.$#' identifier: variable.undefined @@ -16758,48 +16662,18 @@ parameters: count: 8 path: ../../../htdocs/expedition/contact.php - - - message: '#^Variable \$typeobject might not be defined\.$#' - identifier: variable.undefined - count: 4 - path: ../../../htdocs/expedition/contact.php - - message: '#^If condition is always false\.$#' identifier: if.alwaysFalse count: 1 path: ../../../htdocs/expedition/dispatch.php - - - message: '#^Variable \$modebatch might not be defined\.$#' - identifier: variable.undefined - count: 4 - path: ../../../htdocs/expedition/dispatch.php - - - - message: '#^Variable \$nbproduct might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/expedition/dispatch.php - - message: '#^Variable \$objectsrc might not be defined\.$#' identifier: variable.undefined count: 3 path: ../../../htdocs/expedition/dispatch.php - - - message: '#^Variable \$objsearchdet might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/expedition/dispatch.php - - - - message: '#^Variable \$typeobject might not be defined\.$#' - identifier: variable.undefined - count: 4 - path: ../../../htdocs/expedition/dispatch.php - - message: '#^If condition is always false\.$#' identifier: if.alwaysFalse @@ -16812,12 +16686,6 @@ parameters: count: 2 path: ../../../htdocs/expedition/document.php - - - message: '#^Variable \$typeobject might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../../htdocs/expedition/document.php - - message: '#^Call to function method_exists\(\) with Expedition and ''fetch_lines'' will always evaluate to true\.$#' identifier: function.alreadyNarrowedType @@ -16860,12 +16728,6 @@ parameters: count: 1 path: ../../../htdocs/expedition/list.php - - - message: '#^Variable \$search_shipping_method_id might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/expedition/list.php - - message: '#^If condition is always false\.$#' identifier: if.alwaysFalse @@ -16878,12 +16740,6 @@ parameters: count: 2 path: ../../../htdocs/expedition/note.php - - - message: '#^Variable \$typeobject might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../../htdocs/expedition/note.php - - message: '#^If condition is always false\.$#' identifier: if.alwaysFalse @@ -16920,12 +16776,6 @@ parameters: count: 6 path: ../../../htdocs/expedition/shipment.php - - - message: '#^Variable \$toBeShippedTotal might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../../htdocs/expedition/shipment.php - - message: '#^Variable \$socid might not be defined\.$#' identifier: variable.undefined @@ -16986,18 +16836,6 @@ parameters: count: 10 path: ../../../htdocs/expensereport/card.php - - - message: '#^Variable \$remaintopay might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/expensereport/card.php - - - - message: '#^Variable \$userauthor might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../../htdocs/expensereport/card.php - - message: '#^Method ExpenseReports\:\:_validate\(\) has parameter \$data with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue @@ -17226,12 +17064,6 @@ parameters: count: 1 path: ../../../htdocs/expensereport/payment/card.php - - - message: '#^Variable \$title_button might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/expensereport/payment/card.php - - message: '#^Variable \$linkback might not be defined\.$#' identifier: variable.undefined @@ -17262,30 +17094,12 @@ parameters: count: 1 path: ../../../htdocs/expensereport/payment/payment.php - - - message: '#^Variable \$sumpaid might not be defined\.$#' - identifier: variable.undefined - count: 5 - path: ../../../htdocs/expensereport/payment/payment.php - - - - message: '#^Variable \$fileurl_avg might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/expensereport/stats/index.php - - message: '#^Variable \$action might not be defined\.$#' identifier: variable.undefined count: 2 path: ../../../htdocs/expensereport/tpl/expensereport_addfile.tpl.php - - - message: '#^Variable \$colspan might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../../htdocs/expensereport/tpl/expensereport_addfile.tpl.php - - message: '#^Variable \$conf might not be defined\.$#' identifier: variable.undefined @@ -17316,12 +17130,6 @@ parameters: count: 2 path: ../../../htdocs/expensereport/tpl/expensereport_linktofile.tpl.php - - - message: '#^Variable \$colspan might not be defined\.$#' - identifier: variable.undefined - count: 4 - path: ../../../htdocs/expensereport/tpl/expensereport_linktofile.tpl.php - - message: '#^Variable \$conf might not be defined\.$#' identifier: variable.undefined @@ -17340,12 +17148,6 @@ parameters: count: 1 path: ../../../htdocs/expensereport/tpl/expensereport_linktofile.tpl.php - - - message: '#^Variable \$minifile might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/expensereport/tpl/expensereport_linktofile.tpl.php - - message: '#^Variable \$object might not be defined\.$#' identifier: variable.undefined @@ -17436,12 +17238,6 @@ parameters: count: 1 path: ../../../htdocs/fichinter/card.php - - - message: '#^Variable \$extrafields in empty\(\) always exists and is not falsy\.$#' - identifier: empty.variable - count: 2 - path: ../../../htdocs/fichinter/card.php - - message: '#^Variable \$line might not be defined\.$#' identifier: variable.undefined @@ -17454,66 +17250,6 @@ parameters: count: 11 path: ../../../htdocs/fichinter/card.php - - - message: '#^Method Interventions\:\:_validate\(\) has parameter \$data with no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: ../../../htdocs/fichinter/class/api_interventions.class.php - - - - message: '#^Method Interventions\:\:_validate\(\) return type has no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: ../../../htdocs/fichinter/class/api_interventions.class.php - - - - message: '#^Method Interventions\:\:_validateLine\(\) has parameter \$data with no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: ../../../htdocs/fichinter/class/api_interventions.class.php - - - - message: '#^Method Interventions\:\:_validateLine\(\) return type has no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: ../../../htdocs/fichinter/class/api_interventions.class.php - - - - message: '#^Method Interventions\:\:delete\(\) return type has no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: ../../../htdocs/fichinter/class/api_interventions.class.php - - - - message: '#^Method Interventions\:\:index\(\) return type has no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: ../../../htdocs/fichinter/class/api_interventions.class.php - - - - message: '#^Method Interventions\:\:post\(\) has parameter \$request_data with no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: ../../../htdocs/fichinter/class/api_interventions.class.php - - - - message: '#^Method Interventions\:\:postLine\(\) has parameter \$request_data with no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: ../../../htdocs/fichinter/class/api_interventions.class.php - - - - message: '#^Property Interventions\:\:\$FIELDS type has no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: ../../../htdocs/fichinter/class/api_interventions.class.php - - - - message: '#^Property Interventions\:\:\$FIELDSLINE has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/fichinter/class/api_interventions.class.php - - message: '#^Call to function method_exists\(\) with \$this\(Fichinter\) and ''getLibStatut'' will always evaluate to true\.$#' identifier: function.alreadyNarrowedType @@ -17562,24 +17298,6 @@ parameters: count: 2 path: ../../../htdocs/fichinter/class/fichinterligne.class.php - - - message: '#^Parameter \#17 \$fk_unit of method FichinterRec\:\:addLineRec\(\) expects string\|null, int\|null given\.$#' - identifier: argument.type - count: 1 - path: ../../../htdocs/fichinter/class/fichinterrec.class.php - - - - message: '#^Parameter \#2 \$pu of function calcul_price_total expects float, string given\.$#' - identifier: argument.type - count: 1 - path: ../../../htdocs/fichinter/class/fichinterrec.class.php - - - - message: '#^Parameter \#3 \$remise_percent_ligne of function calcul_price_total expects float, string given\.$#' - identifier: argument.type - count: 1 - path: ../../../htdocs/fichinter/class/fichinterrec.class.php - - message: '#^Right side of && is always false\.$#' identifier: booleanAnd.rightAlwaysFalse @@ -17622,18 +17340,6 @@ parameters: count: 2 path: ../../../htdocs/fichinter/list.php - - - message: '#^Variable \$contratstatic might not be defined\.$#' - identifier: variable.undefined - count: 6 - path: ../../../htdocs/fichinter/list.php - - - - message: '#^Variable \$projetstatic might not be defined\.$#' - identifier: variable.undefined - count: 5 - path: ../../../htdocs/fichinter/list.php - - message: '#^Right side of && is always false\.$#' identifier: booleanAnd.rightAlwaysFalse diff --git a/dev/tools/phan/baseline.txt b/dev/tools/phan/baseline.txt index 7007834787e..f69251c12c0 100644 --- a/dev/tools/phan/baseline.txt +++ b/dev/tools/phan/baseline.txt @@ -10,14 +10,14 @@ return [ // # Issue statistics: // PhanUndeclaredProperty : 540+ occurrences - // PhanPossiblyUndeclaredGlobalVariable : 250+ occurrences - // PhanUndeclaredGlobalVariable : 220+ occurrences + // PhanPossiblyUndeclaredGlobalVariable : 210+ occurrences + // PhanUndeclaredGlobalVariable : 210+ occurrences // PhanPluginUnknownArrayMethodReturnType : 180+ occurrences - // PhanTypeMismatchArgumentProbablyReal : 180+ occurrences + // PhanTypeMismatchArgumentProbablyReal : 160+ occurrences // PhanTypeMismatchProperty : 140+ occurrences // PhanPluginUnknownArrayMethodParamType : 120+ occurrences - // PhanPluginUndeclaredVariableIsset : 45+ occurrences // PhanRedefineFunction : 45+ occurrences + // PhanPluginUndeclaredVariableIsset : 40+ occurrences // PhanTypeExpectedObjectPropAccess : 40+ occurrences // PhanTypeInvalidDimOffset : 25+ occurrences // PhanTypeMismatchDimFetch : 25+ occurrences @@ -32,7 +32,7 @@ return [ // PhanPluginDuplicateExpressionBinaryOp : 6 occurrences // PhanTypeArraySuspiciousNull : 6 occurrences // PhanParamTooMany : 5 occurrences - // PhanPluginBothLiteralsBinaryOp : 5 occurrences + // PhanPluginBothLiteralsBinaryOp : 4 occurrences // PhanPluginDuplicateArrayKey : 4 occurrences // PhanEmptyFQSENInClasslike : 3 occurrences // PhanInvalidFQSENInClasslike : 3 occurrences @@ -203,41 +203,25 @@ return [ 'htdocs/don/info.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/don/list.php' => ['PhanTypeMismatchProperty'], 'htdocs/don/note.php' => ['PhanUndeclaredGlobalVariable'], - 'htdocs/ecm/dir_card.php' => ['PhanPossiblyUndeclaredGlobalVariable'], - 'htdocs/ecm/index.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/emailcollector/class/emailcollector.class.php' => ['PhanUndeclaredProperty'], 'htdocs/eventorganization/class/conferenceorboothattendee.class.php' => ['PhanUndeclaredMethod', 'PhanUndeclaredProperty'], 'htdocs/eventorganization/conferenceorbooth_card.php' => ['PhanUndeclaredGlobalVariable'], - 'htdocs/eventorganization/conferenceorbooth_list.php' => ['PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/eventorganization/conferenceorboothattendee_card.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'], - 'htdocs/eventorganization/conferenceorboothattendee_list.php' => ['PhanTypeMismatchArgumentProbablyReal'], + 'htdocs/eventorganization/conferenceorboothattendee_card.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/eventorganization/core/actions_massactions_mail.inc.php' => ['PhanUndeclaredProperty'], 'htdocs/expedition/card.php' => ['PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/expedition/class/api_shipments.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType'], 'htdocs/expedition/class/expedition.class.php' => ['PhanUndeclaredProperty'], - 'htdocs/expedition/contact.php' => ['PhanPossiblyUndeclaredGlobalVariable'], - 'htdocs/expedition/dispatch.php' => ['PhanPossiblyUndeclaredGlobalVariable'], - 'htdocs/expedition/document.php' => ['PhanPossiblyUndeclaredGlobalVariable'], - 'htdocs/expedition/list.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable'], - 'htdocs/expedition/note.php' => ['PhanPossiblyUndeclaredGlobalVariable'], - 'htdocs/expedition/shipment.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/expensereport/card.php' => ['PhanPluginBothLiteralsBinaryOp', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], + 'htdocs/expensereport/card.php' => ['PhanUndeclaredProperty'], 'htdocs/expensereport/class/api_expensereports.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType'], - 'htdocs/expensereport/payment/card.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'], + 'htdocs/expensereport/payment/card.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/expensereport/payment/info.php' => ['PhanUndeclaredGlobalVariable'], - 'htdocs/expensereport/payment/payment.php' => ['PhanPossiblyUndeclaredGlobalVariable'], - 'htdocs/expensereport/stats/index.php' => ['PhanPossiblyUndeclaredGlobalVariable'], - 'htdocs/expensereport/tpl/expensereport_addfile.tpl.php' => ['PhanUndeclaredGlobalVariable'], - 'htdocs/expensereport/tpl/expensereport_linktofile.tpl.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/expensereport/tpl/linkedobjectblock.tpl.php' => ['PhanUndeclaredProperty'], 'htdocs/externalsite/frames.php' => ['PhanUndeclaredGlobalVariable'], - 'htdocs/fichinter/card-rec.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], - 'htdocs/fichinter/class/api_interventions.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanUndeclaredProperty'], + 'htdocs/fichinter/card-rec.php' => ['PhanUndeclaredGlobalVariable'], + 'htdocs/fichinter/class/api_interventions.class.php' => ['PhanUndeclaredProperty'], 'htdocs/fichinter/class/fichinterrec.class.php' => ['PhanUndeclaredProperty'], - 'htdocs/fichinter/list.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/fichinter/tpl/linkedobjectblock.tpl.php' => ['PhanUndeclaredProperty'], 'htdocs/filefunc.inc.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'], - 'htdocs/fourn/card.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/fourn/class/api_supplier_invoices.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType'], 'htdocs/fourn/class/api_supplier_orders.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/fourn/class/fournisseur.commande.class.php' => ['PhanUndeclaredProperty'], @@ -294,7 +278,7 @@ return [ 'htdocs/loan/card.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/loan/document.php' => ['PhanUndeclaredProperty'], 'htdocs/loan/note.php' => ['PhanUndeclaredProperty'], - 'htdocs/loan/payment/payment.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], + 'htdocs/loan/payment/payment.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/margin/customerMargins.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/margin/productMargins.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/master.inc.php' => ['PhanUndeclaredGlobalVariable'], @@ -476,7 +460,6 @@ return [ 'htdocs/ticket/class/cticketcategory.class.php' => ['PhanUndeclaredProperty'], 'htdocs/ticket/class/ticket.class.php' => ['PhanUndeclaredProperty'], 'htdocs/ticket/index.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentNullableInternal'], - 'htdocs/ticket/list.php' => ['PhanTypeComparisonFromArray'], 'htdocs/user/card.php' => ['PhanTypeMismatchProperty'], 'htdocs/user/class/api_users.class.php' => ['PhanTypeMismatchProperty'], 'htdocs/user/class/user.class.php' => ['PhanUndeclaredProperty'], diff --git a/htdocs/accountancy/class/accountancycategory.class.php b/htdocs/accountancy/class/accountancycategory.class.php index 379e2b802e1..fbbdb35e7a8 100644 --- a/htdocs/accountancy/class/accountancycategory.class.php +++ b/htdocs/accountancy/class/accountancycategory.class.php @@ -439,7 +439,7 @@ class AccountancyCategory // extends CommonObject { global $conf; $sql = "SELECT t.rowid, t.account_number, t.label"; - $sql .= " FROM ".$this->db->prefix().$this->table_element." as t"; + $sql .= " FROM ".$this->db->prefix()."accounting_account as t"; $sql .= " WHERE t.fk_accounting_category = ".((int) $id); $sql .= " AND t.entity = ".$conf->entity; diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index 91f105c48b8..7db9917b1d2 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -9,7 +9,7 @@ * Copyright (C) 2020 Josep Lluís Amador * Copyright (C) 2021 Waël Almoman * Copyright (C) 2024 MDW - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024-2025 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 @@ -136,6 +136,9 @@ $result = restrictedArea($user, 'adherent', $rowid, 'adherent_type'); */ $error = 0; +// Selection of new fields +include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers $search_ref = ""; $search_lastname = ""; @@ -283,6 +286,9 @@ $help_url = 'EN:Module_Foundations|FR:Module_Adhérents|ES:Módulo_M llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-member page-type'); $arrayofselected = is_array($toselect) ? $toselect : array(); +$totalarray = [ + 'nbfield' => 0, +]; // List of members type if (!$rowid && $action != 'create' && $action != 'edit') { @@ -329,8 +335,14 @@ if (!$rowid && $action != 'create' && $action != 'edit') { print ''; print ''; print ''; + print ''; + print ''; print ''; + $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; + $htmlofselectarray = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); // This also change content of $arrayfields with user setup + $selectedfields = ($mode != 'kanban' ? $htmlofselectarray : ''); + // $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); print_barre_liste($langs->trans("MembersTypes"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'members', 0, $newcardbutton, '', $limit, 0, 0, 1); @@ -341,19 +353,48 @@ if (!$rowid && $action != 'create' && $action != 'edit') { print ''; if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ' '; + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch actioncolumn '); + $totalarray['nbfield']++; + } + if (!empty($arrayfields['t.rowid']['checked'])) { + print ''.$langs->trans("Ref").''; + $totalarray['nbfield']++; + } + if (!empty($arrayfields['t.libelle']['checked'])) { + print ''.$langs->trans($arrayfields['t.libelle']['label']).''; + $totalarray['nbfield']++; + } + if (!empty($arrayfields['t.morphy']['checked'])) { + print ''.$langs->trans("MembersNature").''; + $totalarray['nbfield']++; + } + if (!empty($arrayfields['t.duration']['checked'])) { + print ''.$langs->trans("MembershipDuration").''; + $totalarray['nbfield']++; + } + if (!empty($arrayfields['t.subscription']['checked'])) { + print ''.$langs->trans("SubscriptionRequired").''; + $totalarray['nbfield']++; + } + if (!empty($arrayfields['t.amount']['checked'])) { + print ''.$langs->trans("Amount").''; + $totalarray['nbfield']++; + } + if (!empty($arrayfields['t.caneditamount']['checked'])) { + print ''.$langs->trans("CanEditAmountShort").''; + $totalarray['nbfield']++; + } + if (!empty($arrayfields['t.vote']['checked'])) { + print ''.$langs->trans("VoteAllowed").''; + $totalarray['nbfield']++; + } + if (!empty($arrayfields['t.statut']['checked'])) { + print ''.$langs->trans("Status").''; + $totalarray['nbfield']++; } - print ''.$langs->trans("Ref").''; - print ''.$langs->trans("Label").''; - print ''.$langs->trans("MembersNature").''; - print ''.$langs->trans("MembershipDuration").''; - print ''.$langs->trans("SubscriptionRequired").''; - print ''.$langs->trans("Amount").''; - print ''.$langs->trans("CanEditAmountShort").''; - print ''.$langs->trans("VoteAllowed").''; - print ''.$langs->trans("Status").''; if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ' '; + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'maxwidthsearch center '); + $totalarray['nbfield']++; } print "\n"; @@ -397,47 +438,55 @@ if (!$rowid && $action != 'create' && $action != 'edit') { print 'rowid.'">'.img_edit().''; } } - - print ''; - print $membertype->getNomUrl(1); - //'.img_object($langs->trans("ShowType"),'group').' '.$objp->rowid.' - print ''; - - print ''.dol_escape_htmltag($objp->label).''; - - print ''; - if ($objp->morphy == 'phy') { - print $langs->trans("Physical"); - } elseif ($objp->morphy == 'mor') { - print $langs->trans("Moral"); - } else { - print $langs->trans("MorAndPhy"); + if (!empty($arrayfields['t.rowid']['checked'])) { + print ''; + print $membertype->getNomUrl(1); + //'.img_object($langs->trans("ShowType"),'group').' '.$objp->rowid.' + print ''; } - print ''; - - print ''; - if ($objp->duration) { - $duration_value = intval($objp->duration); - if ($duration_value > 1) { - $dur = array("i" => $langs->trans("Minutes"), "h" => $langs->trans("Hours"), "d" => $langs->trans("Days"), "w" => $langs->trans("Weeks"), "m" => $langs->trans("Months"), "y" => $langs->trans("Years")); + if (!empty($arrayfields['t.libelle']['checked'])) { + print ''.dol_escape_htmltag($objp->label).''; + } + if (!empty($arrayfields['t.morphy']['checked'])) { + print ''; + if ($objp->morphy == 'phy') { + print $langs->trans("Physical"); + } elseif ($objp->morphy == 'mor') { + print $langs->trans("Moral"); } else { - $dur = array("i" => $langs->trans("Minute"), "h" => $langs->trans("Hour"), "d" => $langs->trans("Day"), "w" => $langs->trans("Week"), "m" => $langs->trans("Month"), "y" => $langs->trans("Year")); + print $langs->trans("MorAndPhy"); } - $unit = preg_replace("/[^a-zA-Z]+/", "", $objp->duration); - print max(1, $duration_value).' '.$dur[$unit]; + print ''; + } + if (!empty($arrayfields['t.duration']['checked'])) { + print ''; + if ($objp->duration) { + $duration_value = intval($objp->duration); + if ($duration_value > 1) { + $dur = array("i" => $langs->trans("Minutes"), "h" => $langs->trans("Hours"), "d" => $langs->trans("Days"), "w" => $langs->trans("Weeks"), "m" => $langs->trans("Months"), "y" => $langs->trans("Years")); + } else { + $dur = array("i" => $langs->trans("Minute"), "h" => $langs->trans("Hour"), "d" => $langs->trans("Day"), "w" => $langs->trans("Week"), "m" => $langs->trans("Month"), "y" => $langs->trans("Year")); + } + $unit = preg_replace("/[^a-zA-Z]+/", "", $objp->duration); + print max(1, $duration_value).' '.$dur[$unit]; + } + print ''; + } + if (!empty($arrayfields['t.subscription']['checked'])) { + print ''.yn($objp->subscription).''; + } + if (!empty($arrayfields['t.amount']['checked'])) { + print ''.(is_null($objp->amount) || $objp->amount === '' ? '' : price($objp->amount)).''; + } + if (!empty($arrayfields['t.caneditamount']['checked'])) { + print ''.yn($objp->caneditamount).''; + } + if (!empty($arrayfields['t.vote']['checked'])) { + print ''.yn($objp->vote).''; + } + if (!empty($arrayfields['t.statut']['checked'])) { + print ''.$membertype->getLibStatut(5).''; } - print ''; - - print ''.yn($objp->subscription).''; - - print ''.(is_null($objp->amount) || $objp->amount === '' ? '' : price($objp->amount)).''; - - print ''.yn($objp->caneditamount).''; - - print ''.yn($objp->vote).''; - - print ''.$membertype->getLibStatut(5).''; - if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { if ($user->hasRight('adherent', 'configurer')) { print 'rowid.'">'.img_edit().''; diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index c201ca97b73..d96d7ce0e4f 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -11,7 +11,7 @@ * Copyright (C) 2011-2024 Alexandre Spangaro * Copyright (C) 2015 Ferran Marcet * Copyright (C) 2016 Raphaël Doursenaud - * Copyright (C) 2019-2024 Frédéric France + * Copyright (C) 2019-2025 Frédéric France * Copyright (C) 2020-2022 Open-Dsi * Copyright (C) 2024 Charlene Benke * Copyright (C) 2024 MDW @@ -716,6 +716,7 @@ if ($id == DICT_TYPE_CONTACT) { 'project_task' => img_picto('', 'projecttask', 'class="pictofixedwidth"').$langs->trans('Task'), 'propal' => img_picto('', 'propal', 'class="pictofixedwidth"').$langs->trans('Proposal'), 'commande' => img_picto('', 'order', 'class="pictofixedwidth"').$langs->trans('Order'), + 'shipping' => img_picto('', 'dolly', 'class="pictofixedwidth"') . $langs->trans('Shipment'), 'facture' => img_picto('', 'bill', 'class="pictofixedwidth"').$langs->trans('Bill'), 'fichinter' => img_picto('', 'intervention', 'class="pictofixedwidth"').$langs->trans('InterventionCard'), 'contrat' => img_picto('', 'contract', 'class="pictofixedwidth"').$langs->trans('Contract'), diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index 702c0f68e9b..ad8882f6ebc 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -815,7 +815,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; $genallowed = $user->hasRight('bom', 'read'); // If you can read, you can build the PDF to read content $delallowed = $user->hasRight('bom', 'write'); // If you can create/edit, you can remove a file on card - print $formfile->showdocuments('bom', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang); + print $formfile->showdocuments('bom', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang, '', $object); // Show links to link elements $tmparray = $form->showLinkToObjectBlock($object, array(), array('bom'), 1); diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 08a680c1e1b..ec038b7a129 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -294,8 +294,33 @@ class Categorie extends CommonObject */ public $imgHeight; + /** + * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') + * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" + * 'label' the translation key. + * 'enabled' is a condition when the field must be managed (Example: 1 or 'getDolGlobalString("MY_SETUP_PARAM")' + * 'position' is the sort order of field. + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommended to name the field fk_...). + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). + * 'css' is the CSS style to use on field. For example: 'maxwidth200' + * 'help' is a string visible as a tooltip on field + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arrayofkeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") + * 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1. + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ public $fields = array( 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 10, 'notnull' => 1, 'visible' => -1,), + 'entity' => array('type' => 'integer', 'label' => 'Entity', 'enabled' => 1, 'visible' => 0, 'default' => '1', 'notnull' => 1, 'index' => 1, 'position' => 5), 'fk_parent' => array('type' => 'integer', 'label' => 'Fkparent', 'enabled' => 1, 'position' => 20, 'notnull' => 1, 'visible' => -1, 'css' => 'maxwidth500 widthcentpercentminusxx',), 'label' => array('type' => 'varchar(180)', 'label' => 'Label', 'enabled' => 1, 'position' => 25, 'notnull' => 1, 'visible' => -1, 'alwayseditable' => 1, 'css' => 'minwidth300', 'cssview' => 'wordbreak', 'csslist' => 'tdoverflowmax150',), 'ref_ext' => array('type' => 'varchar(255)', 'label' => 'RefExt', 'enabled' => 1, 'position' => 30, 'notnull' => 0, 'visible' => 0, 'alwayseditable' => 1,), @@ -1808,9 +1833,9 @@ class Categorie extends CommonObject } // Check contrast with background and correct text color - $forced_color = 'categtextwhite'; + $forced_color = 'categtextwhite'; // We want color white because the background is dark (grey or other) if ($this->color) { - if (colorIsLight($this->color)) { + if (colorIsLight($this->color)) { // If color is light, we force color to dark $forced_color = 'categtextblack'; } } diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php index 3c3100ab6bd..b15f1f714ef 100644 --- a/htdocs/comm/action/list.php +++ b/htdocs/comm/action/list.php @@ -457,20 +457,19 @@ $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."actioncomm_extrafields as ef ON (a.id = ef.fk_object)"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON a.fk_soc = s.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople as sp ON a.fk_contact = sp.rowid"; -$sql .= " ,".MAIN_DB_PREFIX."c_actioncomm as c"; +$sql .= " INNER JOIN ".MAIN_DB_PREFIX."c_actioncomm as c ON c.id = a.fk_action"; // We must filter on resource table if ($resourceid > 0) { - $sql .= ", ".MAIN_DB_PREFIX."element_resources as r"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."element_resources as r ON r.element_type = 'action' AND r.element_id = a.id"; } // We must filter on assignment table if ($filtert > 0 || $usergroup > 0) { - $sql .= ", ".MAIN_DB_PREFIX."actioncomm_resources as ar"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."actioncomm_resources as ar ON ar.fk_actioncomm = a.id AND ar.element_type='user'"; } if ($usergroup > 0) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ugu ON ugu.fk_user = ar.fk_element"; } -$sql .= " WHERE c.id = a.fk_action"; -$sql .= ' AND a.entity IN ('.getEntity('agenda').')'; +$sql .= " WHERE a.entity IN (".getEntity('agenda').")"; // Condition on actioncode if (!empty($actioncode)) { if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE')) { @@ -501,7 +500,7 @@ if (!empty($actioncode)) { } } if ($resourceid > 0) { - $sql .= " AND r.element_type = 'action' AND r.element_id = a.id AND r.resource_id = ".((int) $resourceid); + $sql .= " AND r.resource_id = ".((int) $resourceid); } if ($pid) { $sql .= " AND a.fk_project=".((int) $pid); @@ -520,13 +519,9 @@ if ($search_sale && $search_sale != '-1') { } } // Search on socid -if ($socid) { +if ($socid > 0) { $sql .= " AND a.fk_soc = ".((int) $socid); } -// We must filter on assignment table -if ($filtert > 0 || $usergroup > 0) { - $sql .= " AND ar.fk_actioncomm = a.id AND ar.element_type='user'"; -} if ($type) { $sql .= " AND c.id = ".((int) $type); } diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index eb81c4c084e..4031c5e5361 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -19,7 +19,7 @@ * Copyright (C) 2022 OpenDSI * Copyright (C) 2022 Gauthier VERDOL * Copyright (C) 2023 William Mead - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -146,23 +146,23 @@ class Propal extends CommonObject /** * @var int|'' - * @deprecated + * @deprecated Use $date_validation * @see $date_validation */ public $datev; /** - * @var integer|'' $date_validation; + * @var int|'' */ public $date_validation; /** - * @var integer|'' $date_signature; + * @var int|'' */ public $date_signature; /** - * @var User $user_signature + * @var User */ public $user_signature; @@ -634,7 +634,7 @@ class Propal extends CommonObject */ public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $fk_product = 0, $remise_percent = 0.0, $price_base_type = 'HT', $pu_ttc = 0.0, $info_bits = 0, $type = 0, $rang = -1, $special_code = 0, $fk_parent_line = 0, $fk_fournprice = 0, $pa_ht = 0, $label = '', $date_start = '', $date_end = '', $array_options = array(), $fk_unit = null, $origin = '', $origin_id = 0, $pu_ht_devise = 0, $fk_remise_except = 0, $noupdateafterinsertline = 0) { - global $mysoc, $conf, $langs; + global $mysoc, $langs; dol_syslog(get_class($this)."::addline propalid=$this->id, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, fk_product=$fk_product, remise_except=$remise_percent, price_base_type=$price_base_type, pu_ttc=$pu_ttc, info_bits=$info_bits, type=$type, fk_remise_except=".$fk_remise_except); @@ -659,7 +659,7 @@ class Propal extends CommonObject } $remise_percent = price2num($remise_percent); - $qty = (float) price2num($qty); + $qty = (float) price2num($qty, 'MS'); $pu_ht = price2num($pu_ht); $pu_ht_devise = price2num($pu_ht_devise); $pu_ttc = price2num($pu_ttc); @@ -710,14 +710,14 @@ class Propal extends CommonObject $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $product = new Product($this->db); - $result = $product->fetch($fk_product); - if ($qty < $product->packaging) { - $qty = $product->packaging; + $tmpproduct = new Product($this->db); + $result = $tmpproduct->fetch($fk_product); + if (abs($qty) < $tmpproduct->packaging) { + $qty = (float) $tmpproduct->packaging; } else { - if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { - $coeff = intval((float) $qty / $product->packaging) + 1; - $qty = (float) $product->packaging * $coeff; + if (!empty($tmpproduct->packaging) && $qty > $tmpproduct->packaging) { + $coeff = intval(abs($qty) / $tmpproduct->packaging) + 1; + $qty = price2num((float) $tmpproduct->packaging * $coeff, 'MS'); setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); } } @@ -772,7 +772,7 @@ class Propal extends CommonObject $this->line->fk_propal = $this->id; $this->line->label = $label; $this->line->desc = $desc; - $this->line->qty = $qty; + $this->line->qty = (float) $qty; $this->line->vat_src_code = $vat_src_code; $this->line->tva_tx = $txtva; diff --git a/htdocs/comm/propal/class/propaleligne.class.php b/htdocs/comm/propal/class/propaleligne.class.php index 67c941e9851..b976193a0e1 100644 --- a/htdocs/comm/propal/class/propaleligne.class.php +++ b/htdocs/comm/propal/class/propaleligne.class.php @@ -373,10 +373,8 @@ class PropaleLigne extends CommonObjectLine $sql .= ' pd.localtax1_tx, pd.localtax2_tx, pd.total_localtax1, pd.total_localtax2,'; $sql .= ' pd.fk_multicurrency, pd.multicurrency_code, pd.multicurrency_subprice, pd.multicurrency_total_ht, pd.multicurrency_total_tva, pd.multicurrency_total_ttc,'; $sql .= ' p.ref as product_ref, p.label as product_label, p.description as product_desc,'; + $sql .= ' p.packaging,'; $sql .= ' pd.date_start, pd.date_end, pd.product_type'; - if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $sql .= ', p.packaging'; - } $sql .= ' FROM '.MAIN_DB_PREFIX.'propaldet as pd'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON pd.fk_product = p.rowid'; $sql .= ' WHERE pd.rowid = '.((int) $rowid); @@ -425,9 +423,7 @@ class PropaleLigne extends CommonObjectLine $this->product_desc = $objp->product_desc; $this->fk_unit = $objp->fk_unit; - if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $this->packaging = $objp->packaging; - } + $this->packaging = $objp->packaging; $this->date_start = $this->db->jdate($objp->date_start); $this->date_end = $this->db->jdate($objp->date_end); diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 71e03085f69..7a68bc13620 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -13,7 +13,7 @@ * Copyright (C) 2016-2022 Ferran Marcet * Copyright (C) 2021-2025 Frédéric France * Copyright (C) 2022 Gauthier VERDOL - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 William Mead * * This program is free software; you can redistribute it and/or modify @@ -1635,14 +1635,14 @@ class Commande extends CommonOrder $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $product = new Product($this->db); - $result = $product->fetch($fk_product); - if ($qty < $product->packaging) { - $qty = $product->packaging; + $tmpproduct = new Product($this->db); + $result = $tmpproduct->fetch($fk_product); + if (abs($qty) < $tmpproduct->packaging) { + $qty = (float) $tmpproduct->packaging; } else { - if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { - $coeff = intval((float) $qty / $product->packaging) + 1; - $qty = (float) $product->packaging * $coeff; + if (!empty($tmpproduct->packaging) && $qty > $tmpproduct->packaging) { + $coeff = intval(abs($qty) / $tmpproduct->packaging) + 1; + $qty = price2num((float) $tmpproduct->packaging * $coeff, 'MS'); setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); } } @@ -1703,7 +1703,7 @@ class Commande extends CommonOrder $this->line->fk_commande = $this->id; $this->line->label = $label; $this->line->desc = $desc; - $this->line->qty = $qty; + $this->line->qty = (float) $qty; $this->line->ref_ext = $ref_ext; $this->line->vat_src_code = $vat_src_code; @@ -1863,21 +1863,21 @@ class Commande extends CommonOrder $this->lines[] = $line; /** POUR AJOUTER AUTOMATIQUEMENT LES SOUSPRODUITS a LA COMMANDE - if (getDolGlobalString('PRODUIT_SOUSPRODUITS')) { - $prod = new Product($this->db); - $prod->fetch($idproduct); - $prod -> get_sousproduits_arbo(); - $prods_arbo = $prod->get_arbo_each_prod(); - if(count($prods_arbo) > 0) - { - foreach($prods_arbo as $key => $value) - { - // print "id : ".$value[1].' :qty: '.$value[0].'
'; - if not in lines { - $this->add_product($value[1], $value[0]); - } - } - } + * if (getDolGlobalString('PRODUIT_SOUSPRODUITS')) { + * $prod = new Product($this->db); + * $prod->fetch($idproduct); + * $prod -> get_sousproduits_arbo(); + * $prods_arbo = $prod->get_arbo_each_prod(); + * if(count($prods_arbo) > 0) + * { + * foreach($prods_arbo as $key => $value) + * { + * // print "id : ".$value[1].' :qty: '.$value[0].'
'; + * if not in lines { + * $this->add_product($value[1], $value[0]); + * } + * } + * } **/ } } @@ -2130,7 +2130,7 @@ class Commande extends CommonOrder $sql .= ' l.fk_unit,'; $sql .= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,'; $sql .= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label, p.tosell as product_tosell, p.tobuy as product_tobuy, p.tobatch as product_tobatch, p.barcode as product_barcode,'; - $sql .= ' p.weight, p.weight_units, p.volume, p.volume_units'; + $sql .= ' p.weight, p.weight_units, p.volume, p.volume_units, p.packaging'; $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line.' as l'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON (p.rowid = l.fk_product)'; $sql .= ' WHERE l.fk_commande = '.((int) $this->id); @@ -2205,10 +2205,7 @@ class Commande extends CommonOrder $line->weight_units = $objp->weight_units; $line->volume = $objp->volume; $line->volume_units = $objp->volume_units; - - if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $line->packaging = $objp->packaging; - } + $line->packaging = $objp->packaging; $line->date_start = $this->db->jdate($objp->date_start); $line->date_end = $this->db->jdate($objp->date_end); diff --git a/htdocs/commande/class/orderline.class.php b/htdocs/commande/class/orderline.class.php index 10519dd0cf2..ec78db8e44d 100644 --- a/htdocs/commande/class/orderline.class.php +++ b/htdocs/commande/class/orderline.class.php @@ -174,10 +174,8 @@ class OrderLine extends CommonOrderLine $sql .= ' cd.fk_unit,'; $sql .= ' cd.fk_multicurrency, cd.multicurrency_code, cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc,'; $sql .= ' p.ref as product_ref, p.label as product_label, p.description as product_desc, p.tobatch as product_tobatch,'; + $sql .= ' p.packaging,'; $sql .= ' cd.date_start, cd.date_end, cd.vat_src_code'; - if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $sql .= ', p.packaging'; - } $sql .= ' FROM '.MAIN_DB_PREFIX.'commandedet as cd'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid'; $sql .= ' WHERE cd.rowid = '.((int) $rowid); @@ -231,10 +229,7 @@ class OrderLine extends CommonOrderLine $this->product_desc = $objp->product_desc; $this->product_tobatch = $objp->product_tobatch; $this->fk_unit = $objp->fk_unit; - - if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $this->packaging = $objp->packaging; - } + $this->packaging = $objp->packaging; $this->date_start = $this->db->jdate($objp->date_start); $this->date_end = $this->db->jdate($objp->date_end); diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index ebede310b25..6120fcc9fa4 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -891,11 +891,29 @@ if (empty($reshook)) { if ($line->product_type < 9 && $line->total_ht != 0) { // Remove lines with product_type greater than or equal to 9 and no need to create discount if amount is null $keyforvatrate = $line->tva_tx.($line->vat_src_code ? ' ('.$line->vat_src_code.')' : ''); + if (!isset($amount_ht[$keyforvatrate])) { + $amount_ht[$keyforvatrate]=0; + } $amount_ht[$keyforvatrate] += $line->total_ht; + if (!isset($amount_tva[$keyforvatrate])) { + $amount_tva[$keyforvatrate]=0; + } $amount_tva[$keyforvatrate] += $line->total_tva; + if (!isset($amount_ttc[$keyforvatrate])) { + $amount_ttc[$keyforvatrate]=0; + } $amount_ttc[$keyforvatrate] += $line->total_ttc; + if (!isset($multicurrency_amount_ht[$keyforvatrate])) { + $multicurrency_amount_ht[$keyforvatrate]=0; + } $multicurrency_amount_ht[$keyforvatrate] += $line->multicurrency_total_ht; + if (!isset($multicurrency_amount_tva[$keyforvatrate])) { + $multicurrency_amount_tva[$keyforvatrate]=0; + } $multicurrency_amount_tva[$keyforvatrate] += $line->multicurrency_total_tva; + if (!isset($multicurrency_amount_ttc[$keyforvatrate])) { + $multicurrency_amount_ttc[$keyforvatrate]=0; + } $multicurrency_amount_ttc[$keyforvatrate] += $line->multicurrency_total_ttc; $i++; } diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 09dddafbbd5..5d22fb3f0fe 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -20,7 +20,7 @@ * Copyright (C) 2022 Sylvain Legrand * Copyright (C) 2023 Gauthier VERDOL * Copyright (C) 2023 Nick Fragoulis - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024-2025 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -174,7 +174,6 @@ class Facture extends CommonInvoice public $resteapayer; /** - * * @var int<0,1> 1 if invoice paid COMPLETELY, 0 otherwise * @deprecated * Use statut and close_code) */ @@ -4000,14 +3999,14 @@ class Facture extends CommonInvoice $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $product = new Product($this->db); - $result = $product->fetch($fk_product); - if ($qty < $product->packaging) { - $qty = $product->packaging; + $tmpproduct = new Product($this->db); + $result = $tmpproduct->fetch($fk_product); + if (abs($qty) < $tmpproduct->packaging) { + $qty = (float) $tmpproduct->packaging; } else { - if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { - $coeff = intval((float) $qty / $product->packaging) + 1; - $qty = (float) $product->packaging * $coeff; + if (!empty($tmpproduct->packaging) && $qty > $tmpproduct->packaging) { + $coeff = intval(abs($qty) / $tmpproduct->packaging) + 1; + $qty = price2num((float) $tmpproduct->packaging * $coeff, 'MS'); setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); } } diff --git a/htdocs/compta/facture/class/factureligne.class.php b/htdocs/compta/facture/class/factureligne.class.php index c397b5ddf00..c0b69cb14d3 100644 --- a/htdocs/compta/facture/class/factureligne.class.php +++ b/htdocs/compta/facture/class/factureligne.class.php @@ -215,10 +215,8 @@ class FactureLigne extends CommonInvoiceLine $sql .= ' fd.multicurrency_total_ht,'; $sql .= ' fd.multicurrency_total_tva,'; $sql .= ' fd.multicurrency_total_ttc,'; - $sql .= ' p.ref as product_ref, p.label as product_label, p.description as product_desc'; - if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $sql .= ', p.packaging'; - } + $sql .= ' p.ref as product_ref, p.label as product_label, p.description as product_desc,'; + $sql .= ' p.packaging'; $sql .= ' FROM '.MAIN_DB_PREFIX.'facturedet as fd'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON fd.fk_product = p.rowid'; $sql .= ' WHERE fd.rowid = '.((int) $rowid); @@ -285,9 +283,7 @@ class FactureLigne extends CommonInvoiceLine $this->multicurrency_total_tva = $objp->multicurrency_total_tva; $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc; - if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $this->packaging = $objp->packaging; - } + $this->packaging = $objp->packaging; $this->fetch_optionals(); diff --git a/htdocs/contrat/class/contratligne.class.php b/htdocs/contrat/class/contratligne.class.php index 5039a0e655c..9b2184c8b03 100644 --- a/htdocs/contrat/class/contratligne.class.php +++ b/htdocs/contrat/class/contratligne.class.php @@ -494,7 +494,7 @@ class ContratLigne extends CommonObjectLine $sql .= " t.label,"; // This field is not used. Only label of product $sql .= " p.ref as product_ref,"; $sql .= " p.label as product_label,"; - $sql .= " p.description as product_desc,"; + $sql .= " p.description as product_description,"; $sql .= " p.fk_product_type as product_type,"; $sql .= " t.description,"; $sql .= " t.date_commande,"; diff --git a/htdocs/contrat/services_list.php b/htdocs/contrat/services_list.php index fb32ec1747e..72fe0e4e0a7 100644 --- a/htdocs/contrat/services_list.php +++ b/htdocs/contrat/services_list.php @@ -409,6 +409,13 @@ if (!empty($filter_opcloture) && $filter_opcloture == ' BETWEEN ') { // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; +// Add where from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; + +$sql .= $db->order($sortfield, $sortorder); + //print $sql; // Count total nb of records @@ -524,6 +531,10 @@ if ($filter_datecloture_start != '') { } // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; +// Add $param from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +$param .= $hookmanager->resPrint; // List of mass actions available $arrayofmassactions = array( diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 3aa18de36e9..18dfa4645f5 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1500,14 +1500,14 @@ abstract class CommonObject $sql = "SELECT ec.rowid, ec.statut as statuslink, ec.fk_socpeople as id, ec.fk_c_type_contact"; // This field contains id of llx_socpeople or id of llx_user if ($source == 'internal') { - $sql .= ", '-1' as socid, t.statut as statuscontact, t.login, t.photo, t.gender"; + $sql .= ", '-1' as socid, t.statut as statuscontact, t.login, t.photo, t.gender, t.fk_country as country_id"; } if ($source == 'external' || $source == 'thirdparty') { - $sql .= ", t.fk_soc as socid, t.statut as statuscontact"; + $sql .= ", t.fk_soc as socid, t.statut as statuscontact, t.fk_pays as country_id"; } - $sql .= ", t.civility as civility, t.lastname as lastname, t.firstname, t.email"; + $sql .= ", t.civility as civility, t.lastname as lastname, t.firstname, t.email, t.address, t.zip, t.town"; if (empty($arrayoftcids)) { - $sql .= ", tc.source, tc.element, tc.code, tc.libelle as type_label"; + $sql .= ", tc.source, tc.element, tc.code, tc.libelle as type_label, co.label as country"; } $sql .= " FROM"; if (empty($arrayoftcids)) { @@ -1516,9 +1516,11 @@ abstract class CommonObject $sql .= " ".$this->db->prefix()."element_contact as ec"; if ($source == 'internal') { // internal contact (user) $sql .= " LEFT JOIN ".$this->db->prefix()."user as t on ec.fk_socpeople = t.rowid"; + $sql .= " LEFT JOIN ".$this->db->prefix()."c_country as co ON co.rowid = t.fk_country"; } if ($source == 'external' || $source == 'thirdparty') { // external contact (socpeople) $sql .= " LEFT JOIN ".$this->db->prefix()."socpeople as t on ec.fk_socpeople = t.rowid"; + $sql .= " LEFT JOIN ".$this->db->prefix()."c_country as co ON co.rowid = t.fk_pays"; } $sql .= " WHERE ec.element_id = ".((int) $this->id); if (empty($arrayoftcids)) { @@ -1566,6 +1568,11 @@ abstract class CommonObject 'lastname' => $obj->lastname, 'firstname' => $obj->firstname, 'email' => $obj->email, + 'address' => $obj->address, + 'zip' => $obj->zip, + 'town' => $obj->town, + 'country_id' => $obj->country_id, + 'country' => $obj->country, 'login' => (empty($obj->login) ? '' : $obj->login), 'photo' => (empty($obj->photo) ? '' : $obj->photo), 'gender' => (empty($obj->gender) ? '' : $obj->gender), @@ -7450,16 +7457,15 @@ abstract class CommonObject * Return HTML string to put an input field into a page * Code very similar with showInputField of extra fields * - * @param ?array{type:string,label:string,enabled:int<0,2>|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array,comment?:string} $val Array of properties for field to show (used only if ->fields not defined) - * Array of properties of field to show - * @param string $key Key of attribute - * @param string|string[] $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) - * @param string $moreparam To add more parameters on html input tag - * @param string $keysuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) - * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names) - * @param string|int $morecss Value for css to define style/length of field. May also be a numeric. - * @param int<0,1> $nonewbutton Force to not show the new button on field that are links to object - * @return string + * @param ?array{type:string,label:string,enabled:int<0,2>|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array,comment?:string} $val Array of properties for field to show (used only if ->fields not defined, so try to keep this null) + * @param string $key Key of attribute + * @param string|string[] $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $moreparam To add more parameters on html input tag + * @param string $keysuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string|int $morecss Value for css to define style/length of field. May also be a numeric. + * @param int<0,1> $nonewbutton Force to not show the new button on field that are links to object + * @return string */ public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0) { @@ -8269,7 +8275,17 @@ abstract class CommonObject } } } - $objectfield = $this->element.($this->module ? '@'.$this->module : '').':'.$key.$keysuffix; + + // $param_list_array[0] can be the name of object (Example 'User' the field is linked to). Not as taking the information from the record in ->fields found from $objectfield. + + // $valparent is a string 'dataobject@module:keyoffieldinfieldsarray' to find the record field to link to. + // $valparent = $this->element.($this->module ? '@'.$this->module : '').':'.$key.$keysuffix; + + // $val is already the record field found at same place than found by $valparent but already loaded and may have been modified by parent caller. + + //$objectfield = $valparent; + $objectfield = $val; // Is better than using old method $valparent + $out = $form->selectForForms($param_list_array[0], $keyprefix.$key.$keysuffix, $value, $showempty, '', '', $morecss, $moreparam, 0, (empty($val['disabled']) ? 0 : 1), '', $objectfield); if (!empty($param_list_array[2])) { // If the entry into $fields is set, we must add a create button diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 752a1527f5b..f03f3dfe15d 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -773,7 +773,7 @@ class ExtraFields $sql = "ALTER TABLE ".$this->db->prefix().$table." ADD UNIQUE INDEX uk_".$table."_".$this->db->sanitize($attrname)." (".$this->db->sanitize($attrname).")"; } else { dol_syslog(get_class($this).'::update_common', LOG_DEBUG); - $sql = "ALTER TABLE ".$this->db->prefix().$table." DROP INDEX IF EXISTS uk_".$table."_".$this->db->sanitize($attrname); + $sql = "ALTER TABLE ".$this->db->prefix().$table." DROP INDEX uk_".$table."_".$this->db->sanitize($attrname); } dol_syslog(get_class($this).'::update', LOG_DEBUG); $resql = $this->db->query($sql, 1, 'dml'); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 4f82a134dae..5dee9316b1e 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -107,9 +107,9 @@ class Form * @param object $object Object (on the page we show) * @param int<0,1> $perm Permission to allow button to edit parameter. Set it to 0 to have a not edited field. * @param string $typeofdata Type of data ('string' by default, 'email', 'amount:99', 'numeric:99', 'text' or 'textarea:rows:cols', 'datepicker' ('day' do not work, don't know why), 'dayhour' or 'datehourpicker' 'checkbox:ckeditor:dolibarr_zzz:width:height:savemethod:1:rows:cols', 'select;xxx[:class]'...) - * @param string $moreparam More param to add on a href URL. - * @param int $fieldrequired 1 if we want to show field as mandatory using the "fieldrequired" CSS. - * @param int<0,3> $notabletag 1=Do not output table tags but output a ':', 2=Do not output table tags and no ':', 3=Do not output table tags but output a ' ' + * @param string $moreparam More param to add on a href URL. + * @param int<0,1> $fieldrequired 1 if we want to show field as mandatory using the "fieldrequired" CSS. + * @param int<0,3> $notabletag 1=Do not output table tags but output a ':', 2=Do not output table tags and no ':', 3=Do not output table tags but output a ' ' * @param string $paramid Key of parameter for id ('id', 'socid') * @param string $help Tooltip help * @return string HTML edit field @@ -333,7 +333,7 @@ class Form $ret .= ''; } //else $ret.='
'; - $ret .= ''; + $ret .= ''; if (preg_match('/ckeditor|textarea/', $typeofdata) && empty($notabletag)) { $ret .= '
' . "\n"; } @@ -624,19 +624,19 @@ class Form * Show a text and picto with tooltip on text or picto. * Can be called by an instancied $form->textwithtooltip or by a static call Form::textwithtooltip * - * @param string $text Text to show - * @param string $htmltext HTML content of tooltip. Must be HTML/UTF8 encoded. - * @param int $tooltipon 1=tooltip on text, 2=tooltip on image, 3=tooltip on both - * @param int $direction -1=image is before, 0=no image, 1=image is after - * @param string $img Html code for image (use img_xxx() function to get it) - * @param string $extracss Add a CSS style to td tags - * @param int $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span - * @param string $incbefore Include code before the text - * @param int $noencodehtmltext Do not encode into html entity the htmltext - * @param string $tooltiptrigger ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key) - * @param int $forcenowrap Force no wrap between text and picto (works with notabs=2 only) - * @return string Code html du tooltip (texte+picto) - * @see textwithpicto() Use textwithpicto() instead of textwithtooltip if you can. + * @param string $text Text to show + * @param string $htmltext HTML content of tooltip. Must be HTML/UTF8 encoded. + * @param int<0,3> $tooltipon 1=tooltip on text, 2=tooltip on image, 3=tooltip on both + * @param int<-1,1> $direction -1=image is before, 0=no image, 1=image is after + * @param string $img Html code for image (use img_xxx() function to get it) + * @param string $extracss Add a CSS style to td tags + * @param int<0,3> $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span + * @param string $incbefore Include code before the text + * @param int<0,1> $noencodehtmltext Do not encode into html entity the htmltext + * @param string $tooltiptrigger ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key) + * @param int<0,1> $forcenowrap Force no wrap between text and picto (works with notabs=2 only) + * @return string Code html du tooltip (texte+picto) + * @see textwithpicto() Use textwithpicto() instead of textwithtooltip if you can. */ public function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img = '', $extracss = '', $notabs = 3, $incbefore = '', $noencodehtmltext = 0, $tooltiptrigger = '', $forcenowrap = 0) { @@ -2205,7 +2205,7 @@ class Form $sql .= " LEFT JOIN " . $this->db->prefix() . "entity as e ON e.rowid = u.entity"; } // Condition here should be the same than into societe->getSalesRepresentatives(). - if ($userissuperadminentityone && $force_entity != 'default') { + if ($userissuperadminentityone && $force_entity !== 'default') { if (!empty($force_entity)) { $sql .= " WHERE u.entity IN (0, " . $this->db->sanitize($force_entity) . ")"; } else { @@ -3109,7 +3109,7 @@ class Form $sql .= $hookmanager->resPrint; // Add criteria on ref/label if ($filterkey != '') { - $sqlSupplierSearch= ''; + $sqlSupplierSearch = ''; $sql .= ' AND ('; $prefix = !getDolGlobalString('PRODUCT_DONOTSEARCH_ANYWHERE') ? '%' : ''; // Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on @@ -3139,7 +3139,7 @@ class Form // include search in supplier ref if (getDolGlobalString('MAIN_SEARCH_PRODUCT_BY_FOURN_REF')) { - $sqlSupplierSearch .= !empty($sqlSupplierSearch) ? ' OR ':''; + $sqlSupplierSearch .= !empty($sqlSupplierSearch) ? ' OR ' : ''; $sqlSupplierSearch .= " pfp.ref_fourn LIKE '" . $this->db->escape($prefix . $crit) . "%'"; } $sql .= ")"; @@ -5648,9 +5648,9 @@ class Form * @param string $title Title * @param string $question Question * @param string $action Action - * @param array}>|string|null $formquestion An array with complementary inputs to add into forms: array(array('label'=> ,'type'=> , 'size'=>, 'morecss'=>, 'moreattr'=>'autofocus' or 'style=...')) - * 'type' can be 'text', 'password', 'checkbox', 'radio', 'date', 'datetime', 'select', 'multiselect', 'morecss', - * 'other', 'onecolumn' or 'hidden'... + * @param array}>|string|null $formquestion An array with complementary inputs to add into forms: array(array('label'=> ,'type'=> , 'size'=>, 'morecss'=>, 'moreattr'=>'autofocus' or 'style=...')) + * 'type' can be 'text', 'password', 'checkbox', 'radio', 'date', 'datetime', 'select', 'multiselect', 'morecss', + * 'other', 'onecolumn' or 'hidden'... * @param int<0,1>|''|'no'|'yes'|'1'|'0' $selectedchoice '' or 'no', or 'yes' or '1', 1, '0' or 0 * @param int<0,2>|string $useajax 0=No, 1=Yes use Ajax to show the popup, 2=Yes and also submit page with &confirm=no if choice is No, 'xxx'=Yes and preoutput confirm box with div id=dialog-confirm-xxx * @param int|string $height Force height of box (0 = auto) @@ -8486,22 +8486,22 @@ class Form /** * Generic method to select a component from a combo list. - * Can use autocomplete with ajax after x key pressed or a full combo, depending on setup. + * Can use autocomplete with ajax after x key pressed (if $objecttmp->element.'_USE_SEARCH_TO_SELECT' is set) or a full combo, depending on setup. * This is the generic method that will replace all specific existing methods. * - * @param string $objectdesc 'ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]'. For hard coded custom needs. Try to prefer method using $objectfield instead of $objectdesc. - * @param string $htmlname Name of HTML select component - * @param int $preSelectedValue Preselected value (ID of element) + * @param string $objectdesc 'ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]'. For hard coded custom needs. Try to prefer method using $objectfield array instead of $objectdesc. + * @param string $htmlname Name of HTML select component + * @param int $preSelectedValue Preselected value (ID of element) * @param string|int<0,1> $showempty ''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...) - * @param string $searchkey Search criteria - * @param string $placeholder Place holder - * @param string $morecss More CSS - * @param string $moreparams More params provided to ajax call - * @param int $forcecombo Force to load all values and output a standard combobox (with no beautification) - * @param int<0,1> $disabled 1=Html component is disabled - * @param string $selected_input_value Value of preselected input text (for use with ajax) - * @param string $objectfield Object:Field that contains the definition of parent (in table $fields or $extrafields). Example: 'Object:xxx' or 'Object@module:xxx' (old syntax 'Module_Object:xxx') or 'Object:options_xxx' or 'Object@module:options_xxx' (old syntax 'Module_Object:options_xxx') - * @return string Return HTML string + * @param string $searchkey Search criteria + * @param string $placeholder Place holder + * @param string $morecss More CSS + * @param string $moreparams More params provided to ajax call + * @param int $forcecombo Force to load all values and output a standard combobox (with no beautification) + * @param int<0,1> $disabled 1=Html component is disabled + * @param string $selected_input_value Value of preselected input text (for use with ajax) + * @param string|array{type:string,label:string,enabled:int<0,2>|string,position:int,notnull?:int,visible:int<-5,5>|string,alwayseditable?:int<0,1>,noteditable?:int<0,1>,default?:string,index?:int,foreignkey?:string,searchall?:int<0,1>,isameasure?:int<0,1>,css?:string,csslist?:string,help?:string,showoncombobox?:int<0,4>,disabled?:int<0,1>,arrayofkeyval?:array,autofocusoncreate?:int<0,1>,comment?:string,copytoclipboard?:int<1,2>,validate?:int<0,1>,showonheader?:int<0,1>} $objectfield 'Object:Field' that contains the definition of parent (in table $fields or $extrafields). Example: 'Object:xxx' or 'Object@module:xxx' or 'Object:options_xxx' or 'Object@module:options_xxx' or, better, the full entry array in ->fields + * @return string Return HTML string * @see selectForFormsList(), select_thirdparty_list() */ public function selectForForms($objectdesc, $htmlname, $preSelectedValue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0, $disabled = 0, $selected_input_value = '', $objectfield = '') @@ -8511,14 +8511,16 @@ class Form // Example of common usage for a link to a thirdparty // We got this in a modulebuilder form of "MyObject" of module "mymodule". - // ->fields is array( ... "fk_soc" => array("type"=>"integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))" ...) + // When ->fields is array( ... "fk_soc" => array("type"=>"integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))" ...), we have // $objectdesc = 'Societe' - // $objectfield = 'myobject@mymodule:fk_soc' ('fk_soc' is code to retrieve myobject->fields['fk_soc']) + // $objectfield = 'myobject@mymodule:fk_soc' ('fk_soc' is code to retrieve myobject->fields['fk_soc']) or it can be an array that is directly + // array("type"=>"integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))" ...) // We got this when showing an extrafields on resource that is a link to societe - // extrafields 'link_to_societe' of Resource is 'link' to 'Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))" ...)' + // When extrafields 'link_to_societe' of Resource is 'link' to 'Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))" ...)', we have // $objectdesc = 'Societe' - // $objectfield = 'resource:options_link_to_societe' + // $objectfield = 'resource:options_link_to_societe' or it can be an array that is directly + // array("type"=>'Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))" ...) // With old usage: // $objectdesc = 'Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))' @@ -8534,7 +8536,10 @@ class Form $filter = ''; // Ensure filter has value (for static analysis) $sortfield = ''; // Ensure filter has value (for static analysis) - if ($objectfield) { // We must retrieve the objectdesc from the field or extrafield + if (is_array($objectfield)) { + $objectdesc = $objectfield['type']; + $objectdesc = preg_replace('/^integer[^:]*:/', '', $objectdesc); + } elseif ($objectfield) { // We must retrieve the objectdesc from the field or extrafield. Deprecated, it is better to provide the array record directly. // Example: $objectfield = 'product:options_package' or 'myobject@mymodule:options_myfield' $tmparray = explode(':', $objectfield); diff --git a/htdocs/core/class/html.formcontract.class.php b/htdocs/core/class/html.formcontract.class.php index b9be63dee34..11eca55e4b6 100644 --- a/htdocs/core/class/html.formcontract.class.php +++ b/htdocs/core/class/html.formcontract.class.php @@ -1,5 +1,6 @@ + * Copyright (C) 2025 MDW * * 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 @@ -180,17 +181,17 @@ class FormContract /** * Show a form to select a contract * - * @param int $page Page + * @param string $page Page * @param int $socid Id third party (-1=all, 0=only contracts not linked to a third party, id=contracts not linked or linked to third party id) * @param int $selected Id contract preselected * @param string $htmlname Nom de la zone html * @param int $maxlength Maximum length of label * @param int $showempty Show empty line * @param int $showRef Show customer and supplier reference on each contract (when found) - * @param int $noouput 1=Return the output instead of display + * @param int<0,1> $nooutput 1=Return the output instead of display * @return string|void html string */ - public function formSelectContract($page, $socid = -1, $selected = 0, $htmlname = 'contrattid', $maxlength = 16, $showempty = 1, $showRef = 0, $noouput = 0) + public function formSelectContract($page, $socid = -1, $selected = 0, $htmlname = 'contrattid', $maxlength = 16, $showempty = 1, $showRef = 0, $nooutput = 0) { global $langs; @@ -201,7 +202,7 @@ class FormContract $ret .= ''; $ret .= ''; - if ($noouput) { + if ($nooutput) { return $ret; } diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index 1005cc70941..897a6f5711d 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -1013,6 +1013,274 @@ function num_public_holiday($timestampStart, $timestampEnd, $country_code = '', return $nbFerie; } +/** + * Return the list of public holidays including Friday, Saturday and Sunday (or not) between 2 dates in timestamp. + * Dates must be UTC with hour, min, sec to 0. + * TODO Not used yet. Must be shared with num_public_holiday() + * + * @param int $timestampStart Timestamp start (UTC with hour, min, sec = 0) + * @param int $timestampEnd Timestamp end (UTC with hour, min, sec = 0) + * @param string $country_code Country code + * @param int $lastday Last day is included, 0: no, 1:yes + * @param int $excludesaturday Exclude saturday as non working day (-1=use setup, 0=no, 1=yes) + * @param int $excludesunday Exclude sunday as non working day (-1=use setup, 0=no, 1=yes) + * @param int $excludefriday Exclude friday as non working day (-1=use setup, 0=no, 1=yes) + * @param int $excludemonday Exclude monday as non working day (-1=use setup, 0=no, 1=yes) + * @return string|int[] List of public holidays timestamps or error message string if error + * @see num_public_holiday(), num_open_day() + */ +function listPublicHoliday($timestampStart, $timestampEnd, $country_code = '', $lastday = 0, $excludesaturday = -1, $excludesunday = -1, $excludefriday = -1, $excludemonday = -1) +{ + global $conf, $db, $mysoc; + + // Check to ensure we use correct parameters + if (($timestampEnd - $timestampStart) % 86400 != 0) { + return 'Error Dates must use same hours and must be GMT dates'; + } + + if (empty($country_code)) { + $country_code = $mysoc->country_code; + } + if ($excludemonday < 0) { + $excludemonday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_MONDAY', 0); + } + if ($excludefriday < 0) { + $excludefriday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_FRIDAY', 0); + } + if ($excludesaturday < 0) { + $excludesaturday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY', 1); + } + if ($excludesunday < 0) { + $excludesunday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY', 1); + } + + $country_id = dol_getIdFromCode($db, $country_code, 'c_country', 'code', 'rowid'); + + if (empty($conf->cache['arrayOfActivePublicHolidays_' . $country_id])) { + // Loop on public holiday defined into hrm_public_holiday for the day, month and year analyzed + $tmpArrayOfPublicHolidays = array(); + $sql = "SELECT id, code, entity, fk_country, dayrule, year, month, day, active"; + $sql .= " FROM " . MAIN_DB_PREFIX . "c_hrm_public_holiday"; + $sql .= " WHERE active = 1 and fk_country IN (0" . ($country_id > 0 ? ", " . $country_id : 0) . ")"; + $sql .= " AND entity IN (0," . getEntity('holiday') . ")"; + + $resql = $db->query($sql); + if ($resql) { + $num_rows = $db->num_rows($resql); + $i = 0; + while ($i < $num_rows) { + $obj = $db->fetch_object($resql); + $tmpArrayOfPublicHolidays[$obj->id] = array('dayrule' => $obj->dayrule, 'year' => $obj->year, 'month' => $obj->month, 'day' => $obj->day); + $i++; + } + } else { + dol_syslog($db->lasterror(), LOG_ERR); + return 'Error sql ' . $db->lasterror(); + } + + //var_dump($tmpArrayOfPublicHolidays); + $conf->cache['arrayOfActivePublicHolidays_' . $country_id] = $tmpArrayOfPublicHolidays; + } + + $arrayOfPublicHolidays = $conf->cache['arrayOfActivePublicHolidays_' . $country_id]; + $listFeries = []; + $i = 0; + while ((($lastday == 0 && $timestampStart < $timestampEnd) || ($lastday && $timestampStart <= $timestampEnd)) + && ($i < 50000)) { // Loop end when equals (Test on i is a security loop to avoid infinite loop) + $nonWorkingDay = false; + $ferie = false; + $specialdayrule = array(); + + $jour = (int) gmdate("d", $timestampStart); + $mois = (int) gmdate("m", $timestampStart); + $annee = (int) gmdate("Y", $timestampStart); + + // If we have to exclude Friday, Saturday and Sunday + if ($excludefriday || $excludesaturday || $excludesunday) { + $jour_julien = unixtojd($timestampStart); + $jour_semaine = jddayofweek($jour_julien, 0); + if ($excludefriday) { //Friday (5), Saturday (6) and Sunday (0) + if ($jour_semaine == 5) { + $nonWorkingDay = true; + } + } + if ($excludesaturday) { //Friday (5), Saturday (6) and Sunday (0) + if ($jour_semaine == 6) { + $nonWorkingDay = true; + } + } + if ($excludesunday) { //Friday (5), Saturday (6) and Sunday (0) + if ($jour_semaine == 0) { + $nonWorkingDay = true; + } + } + } + //print "ferie=".$nonWorkingDay."\n"; + + if (!$nonWorkingDay) { + //print "jour=".$jour." month=".$mois." year=".$annee." includesaturday=".$excludesaturday." includesunday=".$excludesunday."\n"; + foreach ($arrayOfPublicHolidays as $entrypublicholiday) { + if (!empty($entrypublicholiday['dayrule']) && $entrypublicholiday['dayrule'] != 'date') { // For example 'easter', '...' + $specialdayrule[$entrypublicholiday['dayrule']] = $entrypublicholiday['dayrule']; + } else { + $match = 1; + if (!empty($entrypublicholiday['year']) && $entrypublicholiday['year'] != $annee) { + $match = 0; + } + if ($entrypublicholiday['month'] != $mois) { + $match = 0; + } + if ($entrypublicholiday['day'] != $jour) { + $match = 0; + } + + if ($match) { + $ferie = true; + $listFeries[] = $timestampStart; + } + } + + $i++; + } + //var_dump($specialdayrule)."\n"; + //print "ferie=".$nonWorkingDay."\n"; + } + + if (!$nonWorkingDay && !$ferie) { + // Special dayrules + if (in_array('easter', $specialdayrule)) { + // Calculation for easter date + $date_paques = getGMTEasterDatetime($annee); + $jour_paques = gmdate("d", $date_paques); + $mois_paques = gmdate("m", $date_paques); + if ($jour_paques == $jour && $mois_paques == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // Easter (sunday) + } + + if (in_array('eastermonday', $specialdayrule)) { + // Calculation for the monday of easter date + $date_paques = getGMTEasterDatetime($annee); + //print 'PPP'.$date_paques.' '.dol_print_date($date_paques, 'dayhour', 'gmt')." "; + $date_lundi_paques = $date_paques + (3600 * 24); + $jour_lundi_paques = gmdate("d", $date_lundi_paques); + $mois_lundi_paques = gmdate("m", $date_lundi_paques); + if ($jour_lundi_paques == $jour && $mois_lundi_paques == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // Easter (monday) + //print 'annee='.$annee.' $jour='.$jour.' $mois='.$mois.' $jour_lundi_paques='.$jour_lundi_paques.' $mois_lundi_paques='.$mois_lundi_paques."\n"; + } + + //Good Friday + if (in_array('goodfriday', $specialdayrule)) { + // Pulls the date of Easter + $easter = getGMTEasterDatetime($annee); + + // Calculates the date of Good Friday based on Easter + $date_good_friday = $easter - (2 * 3600 * 24); + $dom_good_friday = gmdate("d", $date_good_friday); + $month_good_friday = gmdate("m", $date_good_friday); + + if ($dom_good_friday == $jour && $month_good_friday == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + } + + if (in_array('ascension', $specialdayrule)) { + // Calcul du jour de l'ascension (39 days after easter day) + $date_paques = getGMTEasterDatetime($annee); + $date_ascension = $date_paques + (3600 * 24 * 39); + $jour_ascension = gmdate("d", $date_ascension); + $mois_ascension = gmdate("m", $date_ascension); + if ($jour_ascension == $jour && $mois_ascension == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // Ascension (thursday) + } + + if (in_array('pentecost', $specialdayrule)) { + // Calculation of "Pentecote" (49 days after easter day) + $date_paques = getGMTEasterDatetime($annee); + $date_pentecote = $date_paques + (3600 * 24 * 49); + $jour_pentecote = gmdate("d", $date_pentecote); + $mois_pentecote = gmdate("m", $date_pentecote); + if ($jour_pentecote == $jour && $mois_pentecote == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // "Pentecote" (sunday) + } + + if (in_array('pentecotemonday', $specialdayrule)) { + // Calculation of "Pentecote" (49 days after easter day) + $date_paques = getGMTEasterDatetime($annee); + $date_pentecote = $date_paques + (3600 * 24 * 50); + $jour_pentecote = gmdate("d", $date_pentecote); + $mois_pentecote = gmdate("m", $date_pentecote); + if ($jour_pentecote == $jour && $mois_pentecote == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // "Pentecote" (monday) + } + + if (in_array('viernessanto', $specialdayrule)) { + // Viernes Santo + $date_paques = getGMTEasterDatetime($annee); + $date_viernes = $date_paques - (3600 * 24 * 2); + $jour_viernes = gmdate("d", $date_viernes); + $mois_viernes = gmdate("m", $date_viernes); + if ($jour_viernes == $jour && $mois_viernes == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + //Viernes Santo + } + + if (in_array('fronleichnam', $specialdayrule)) { + // Fronleichnam (60 days after easter sunday) + $date_paques = getGMTEasterDatetime($annee); + $date_fronleichnam = $date_paques + (3600 * 24 * 60); + $jour_fronleichnam = gmdate("d", $date_fronleichnam); + $mois_fronleichnam = gmdate("m", $date_fronleichnam); + if ($jour_fronleichnam == $jour && $mois_fronleichnam == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // Fronleichnam + } + + if (in_array('genevafast', $specialdayrule)) { + // Geneva fast in Switzerland (Thursday after the first sunday in September) + $date_1sunsept = strtotime('next thursday', strtotime('next sunday', mktime(0, 0, 0, 9, 1, $annee))); + $jour_1sunsept = date("d", $date_1sunsept); + $mois_1sunsept = date("m", $date_1sunsept); + if ($jour_1sunsept == $jour && $mois_1sunsept == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // Geneva fast in Switzerland + } + } + //print "ferie=".$nonWorkingDay."\n"; + + // Increase number of days (on go up into loop) + $timestampStart = dol_time_plus_duree($timestampStart, 1, 'd'); + //var_dump($jour.' '.$mois.' '.$annee.' '.$timestampStart); + + $i++; + } + + //print "nbFerie=".$nbFerie."\n"; + return $listFeries; +} + /** * Function to return number of days between two dates (date must be UTC date !) * Example: 2012-01-01 2012-01-02 => 1 if lastday=0, 2 if lastday=1 diff --git a/htdocs/core/lib/fichinter.lib.php b/htdocs/core/lib/fichinter.lib.php index 64b91da0206..2eeb365cc62 100644 --- a/htdocs/core/lib/fichinter.lib.php +++ b/htdocs/core/lib/fichinter.lib.php @@ -232,7 +232,7 @@ function fichinter_rec_prepare_head($object) $head = array(); $head[$h][0] = DOL_URL_ROOT.'/fichinter/card-rec.php?id='.$object->id; - $head[$h][1] = $langs->trans("CardFichinter"); + $head[$h][1] = $langs->trans("InterventionCard"); $head[$h][2] = 'card'; $h++; diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index b6eb5421d53..345d170ff2d 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1588,6 +1588,7 @@ function dol_delete_file($file, $disableglob = 0, $nophperrors = 0, $nohook = 0, } } } else { + $ok = false; // to avoid false positive dol_syslog("No files to delete found", LOG_DEBUG); } } else { @@ -3564,9 +3565,19 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, dol_print_error(null, 'Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); exit; } - if ($fuser->hasRight($tmpmodule, $lire) || preg_match('/^specimen/i', $original_file)) { + + // Check fuser->rights->modulepart->myobject->read and fuser->rights->modulepart->read + $partsofdirinoriginalfile = explode('/', $original_file); + if (!empty($partsofdirinoriginalfile[1])) { // If original_file is xxx/filename (xxx is a part we will use) + $partofdirinoriginalfile = $partsofdirinoriginalfile[0]; + if (($partofdirinoriginalfile && $fuser->hasRight($tmpmodule, $partofdirinoriginalfile, 'read')) || preg_match('/^specimen/i', $original_file)) { + $accessallowed = 1; + } + } + if ($fuser->hasRight($tmpmodule, $read) || preg_match('/^specimen/i', $original_file)) { $accessallowed = 1; } + $original_file = $conf->$tmpmodule->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } else { if (empty($conf->$modulepart->dir_output)) { // modulepart not supported diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 0a8cab279a9..23780903360 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6052,7 +6052,7 @@ function info_admin($text, $infoonimgalt = 0, $nodiv = 0, $admin = '1', $morecss if ($picto == 'warning') { $fa = 'exclamation-triangle'; } - $result = ($nodiv ? '' : '
').' '; + $result = ($nodiv ? '' : '
').' '; $result .= dol_escape_htmltag($text, 1, 0, 'div,span,b,br,a'); $result .= ($nodiv ? '' : '
'); diff --git a/htdocs/core/lib/functionsnumtoword.lib.php b/htdocs/core/lib/functionsnumtoword.lib.php index 77df277209a..06f87c2820d 100644 --- a/htdocs/core/lib/functionsnumtoword.lib.php +++ b/htdocs/core/lib/functionsnumtoword.lib.php @@ -52,7 +52,7 @@ function dol_convertToWord($num, $langs, $currency = '', $centimes = false) } else { $TNum = explode('.', (string) $num); - $num = (int) $TNum[0]; + $num = abs((int) $TNum[0]); $words = array(); $list1 = array( '', diff --git a/htdocs/core/lib/price.lib.php b/htdocs/core/lib/price.lib.php index 11df59e893a..ec5ff384592 100644 --- a/htdocs/core/lib/price.lib.php +++ b/htdocs/core/lib/price.lib.php @@ -48,7 +48,7 @@ * @param string $price_base_type 'HT'=Unit price parameter $pu is HT, 'TTC'=Unit price parameter $pu is TTC (HT+VAT but not Localtax. TODO Add also mode 'INCT' when pu is price HT+VAT+LT1+LT2) * @param int $info_bits Miscellaneous information on line * @param int<0,1> $type 0/1=Product/service - * @param string|Societe|string $seller Third party seller (we need $seller->country_id property). Provided only if seller is the supplier, otherwise $seller will be $mysoc. + * @param string|Societe|null $seller Third party seller (we need $seller->country_id property). Provided only if seller is the supplier, otherwise $seller will be $mysoc. * @param array{0:string,1:int|string,2:string,3:string}|array{0:string,1:int|string,2:string,3:int|string,4:string,5:string} $localtaxes_array Array with localtaxes info array('0'=>type1,'1'=>rate1,'2'=>type2,'3'=>rate2) (loaded by getLocalTaxesFromRate(vatrate, 0, ...) function). * @param float $progress Situation invoices progress (value from 0 to 100, 100 by default) * @param float $multicurrency_tx Currency rate (1 by default) @@ -87,7 +87,7 @@ * * @phan-suppress PhanTypeMismatchDefault */ -function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller = '', $localtaxes_array = [], $progress = 100, $multicurrency_tx = 1, $pu_devise = 0, $multicurrency_code = '') // @phpstan-ignore-line +function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller = null, $localtaxes_array = [], $progress = 100, $multicurrency_tx = 1, $pu_devise = 0, $multicurrency_code = '') // @phpstan-ignore-line { global $conf, $mysoc, $db; diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index 697d3f5674d..00de6abe9ae 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -779,13 +779,13 @@ function getStructuredData($type, $data = array()) $pageurl = $websitepage->pageurl; $title = $websitepage->title; - $image = $websitepage->image; + $image = getImageFromHtmlContent($websitepage->content); $companyname = $mysoc->name; $description = $websitepage->description; $pageurl = str_replace('__WEBSITE_KEY__', $website->ref, $pageurl); $title = str_replace('__WEBSITE_KEY__', $website->ref, $title); - $image = '/medias'.(preg_match('/^\//', $image) ? '' : '/').str_replace('__WEBSITE_KEY__', $website->ref, $image); + $imagepath = '/medias'.(preg_match('/^\//', $image) ? '' : '/').str_replace('__WEBSITE_KEY__', $website->ref, $image); $companyname = str_replace('__WEBSITE_KEY__', $website->ref, $companyname); $description = str_replace('__WEBSITE_KEY__', $website->ref, $description); @@ -798,10 +798,14 @@ function getStructuredData($type, $data = array()) "@type": "WebPage", "@id": "'.dol_escape_json($pageurl).'" }, - "headline": "'.dol_escape_json($title).'", + "headline": "'.dol_escape_json($title).'",'; + if ($image) { + $ret .= ' "image": [ - "'.dol_escape_json($image).'" - ], + "'.dol_escape_json($imagepath).'" + ],'; + } + $ret .= ' "dateCreated": "'.dol_print_date($websitepage->date_creation, 'dayhourrfc').'", "datePublished": "'.dol_print_date($websitepage->date_creation, 'dayhourrfc').'", "dateModified": "'.dol_print_date($websitepage->date_modification, 'dayhourrfc').'", @@ -814,7 +818,7 @@ function getStructuredData($type, $data = array()) "name": "'.dol_escape_json($companyname).'", "logo": { "@type": "ImageObject", - "url": "/wrapper.php?modulepart=mycompany&file=logos%2F'.urlencode($mysoc->logo).'" + "url": "/wrapper.php?modulepart=mycompany&file='.urlencode('logos/'.$mysoc->logo).'" } },'."\n"; if ($websitepage->keywords) { diff --git a/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php b/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php index 69ce92b45d3..72788ca6ce3 100644 --- a/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php +++ b/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php @@ -287,7 +287,7 @@ class pdf_soleil extends ModelePDFFicheinter $desc = dol_htmlentitiesbr($text, 1); //print $outputlangs->convToOutputCharset($desc); exit; - $pdf->writeHTMLCell(180, 3, 10, $tab_top + 5, $outputlangs->convToOutputCharset($desc), 0, 1); + $pdf->writeHTMLCell(180, 3, $this->posxdesc - 1, $tab_top + 5, $outputlangs->convToOutputCharset($desc), 0, 1); $nexY = $pdf->GetY(); $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY); diff --git a/htdocs/core/modules/modProjet.class.php b/htdocs/core/modules/modProjet.class.php index 3019a0f590d..87bca4805ff 100644 --- a/htdocs/core/modules/modProjet.class.php +++ b/htdocs/core/modules/modProjet.class.php @@ -232,6 +232,7 @@ class modProjet extends DolibarrModules 'p.rowid'=>"Numeric", 'p.ref'=>"Text", 'p.title'=>"Text", 'p.usage_opportunity'=>'Boolean', 'p.usage_task'=>'Boolean', 'p.usage_bill_time'=>'Boolean', 'p.datec'=>"Date", 'p.dateo'=>"Date", 'p.datee'=>"Date", 'p.fk_statut'=>'Status', 'cls.code'=>"Text", 'p.opp_percent'=>'Numeric', 'p.opp_amount'=>'Numeric', 'p.description'=>"Text", 'p.entity'=>'Numeric', 'p.budget_amount'=>'Numeric', + 'p.note_public'=>'Text', 'p.note_private'=>'Text', 'pt.rowid'=>'Numeric', 'pt.ref'=>'Text', 'pt.label'=>'Text', 'pt.dateo'=>"Date", 'pt.datee'=>"Date", 'pt.duration_effective'=>"Duree", 'pt.planned_workload'=>"Numeric", 'pt.progress'=>"Numeric", 'pt.description'=>"Text", 'ptt.rowid'=>'Numeric', 'ptt.element_date'=>'Date', 'ptt.element_duration'=>"Duree", 'ptt.fk_user'=>"FormSelect:select_dolusers", 'ptt.note'=>"Text" ); @@ -244,7 +245,8 @@ class modProjet extends DolibarrModules 's.phone'=>'Phone', 's.email'=>'Email', 's.siren'=>'ProfId1', 's.siret'=>'ProfId2', 's.ape'=>'ProfId3', 's.idprof4'=>'ProfId4', 's.code_compta'=>'CustomerAccountancyCode', 's.code_compta_fournisseur'=>'SupplierAccountancyCode', 'p.rowid'=>"ProjectId", 'p.ref'=>"RefProject", 'p.title'=>'ProjectLabel', 'p.usage_opportunity'=>'ProjectFollowOpportunity', 'p.usage_task'=>'ProjectFollowTasks', 'p.usage_bill_time'=>'BillTime', - 'p.datec'=>"DateCreation", 'p.dateo'=>"DateStart", 'p.datee'=>"DateEnd", 'p.fk_statut'=>'ProjectStatus', 'cls.code'=>'OpportunityStatus', 'p.opp_percent'=>'OpportunityProbability', 'p.opp_amount'=>'OpportunityAmount', 'p.budget_amount'=>'Budget', 'p.description'=>"Description" + 'p.datec'=>"DateCreation", 'p.dateo'=>"DateStart", 'p.datee'=>"DateEnd", 'p.fk_statut'=>'ProjectStatus', 'cls.code'=>'OpportunityStatus', 'p.opp_percent'=>'OpportunityProbability', 'p.opp_amount'=>'OpportunityAmount', 'p.description'=>"Description", 'p.budget_amount'=>'Budget', + 'p.note_public'=>'NotePublic', 'p.note_private'=>'NotePrivate', ); // Add multicompany field if (getDolGlobalString('MULTICOMPANY_ENTITY_IN_EXPORT_IF_SHARED')) { diff --git a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php index 30771eba7b0..a0c7210392a 100644 --- a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php +++ b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php @@ -473,6 +473,14 @@ class doc_generic_task_odt extends ModelePDFTask return -1; } + // Add odtgeneration hook + if (!is_object($hookmanager)) { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + $hookmanager->initHooks(array('odtgeneration')); + global $action; + if (!is_object($outputlangs)) { $outputlangs = $langs; } diff --git a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php index b95f709c55a..e7d5c2c4220 100644 --- a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php +++ b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php @@ -228,6 +228,7 @@ class doc_generic_odt extends ModeleThirdPartyDoc $hookmanager = new HookManager($this->db); } $hookmanager->initHooks(array('odtgeneration')); + global $action; if (!is_object($outputlangs)) { $outputlangs = $langs; diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php index f643229c7d3..1c8c0104b43 100644 --- a/htdocs/core/tpl/extrafields_view.tpl.php +++ b/htdocs/core/tpl/extrafields_view.tpl.php @@ -167,6 +167,9 @@ if (empty($reshook) && !empty($object->table_element) && isset($extrafields->att if ($object->element == 'product') { $keyforperm = 'produit'; } + if ($object->element == 'project') { + $keyforperm = 'projet'; + } if (isset($user->rights->$keyforperm)) { $permok = $user->hasRight($keyforperm, 'creer') || $user->hasRight($keyforperm, 'create') || $user->hasRight($keyforperm, 'write'); } diff --git a/htdocs/ecm/dir_card.php b/htdocs/ecm/dir_card.php index fcfff57f74a..cf7d8c159c9 100644 --- a/htdocs/ecm/dir_card.php +++ b/htdocs/ecm/dir_card.php @@ -1,6 +1,7 @@ * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -85,7 +86,7 @@ $ecmdir = new EcmDirectory($db); if ($module == 'ecm') { // $section should be an int except if it is dir not yet created into EcmDirectory - $result = $ecmdir->fetch($section); + $result = preg_match('/^\d+$/', $section) ? $ecmdir->fetch((int) $section) : 0; if ($result > 0) { $relativepath = $ecmdir->getRelativePath(); $upload_dir = $conf->ecm->dir_output.'/'.$relativepath; @@ -199,6 +200,7 @@ if ($action == 'confirm_deletedir' && $confirm == 'yes' && $permissiontoupload) // Update dirname or description if ($action == 'update' && !GETPOST('cancel', 'alpha') && $permissiontoadd) { $error = 0; + $oldlabel = ''; if ($module == 'ecm') { $oldlabel = $ecmdir->label; diff --git a/htdocs/ecm/index.php b/htdocs/ecm/index.php index 0f3e5cd7c24..213d60c4a17 100644 --- a/htdocs/ecm/index.php +++ b/htdocs/ecm/index.php @@ -2,6 +2,7 @@ /* Copyright (C) 2008-2017 Laurent Destailleur * Copyright (C) 2008-2010 Regis Houssin * Copyright (C) 2024 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -109,10 +110,11 @@ $permissiontodeletedir = $user->hasRight('ecm', 'setup'); //$backtopage = $_SERVER["PHP_SELF"].'?file_manager=1&website='.$websitekey.'&pageid='.$pageid; // used after a confirm_deletefile into actions_linkedfiles.inc.php //include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; +$relativepath = ''; + // Upload file (code similar but different than actions_linkedfiles.inc.php) if (GETPOST("sendit", 'alphanohtml') && getDolGlobalString('MAIN_UPLOAD_DOC') && $permissiontocreate) { // Define relativepath and upload_dir - $relativepath = ''; if ($ecmdir->id) { $relativepath = $ecmdir->getRelativePath(); } else { @@ -277,11 +279,11 @@ if ($action == 'refreshmanual' && $permissiontoread) { //print $ecmdirtmp->cachenbofdoc."
\n";exit; $id = $ecmdirtmp->create($user); if ($id > 0) { - $newdirsql = array('id'=>$id, - 'id_mere'=>$ecmdirtmp->fk_parent, - 'label'=>$ecmdirtmp->label, - 'description'=>$ecmdirtmp->description, - 'fullrelativename'=>$relativepathmissing); + $newdirsql = array('id' => $id, + 'id_mere' => $ecmdirtmp->fk_parent, + 'label' => $ecmdirtmp->label, + 'description' => $ecmdirtmp->description, + 'fullrelativename' => $relativepathmissing); $sqltree[] = $newdirsql; // We complete fulltree for following loops //var_dump($sqltree); $adirwascreated = 1; diff --git a/htdocs/eventorganization/conferenceorbooth_card.php b/htdocs/eventorganization/conferenceorbooth_card.php index 69162c5fca8..2a35ceb8dfb 100644 --- a/htdocs/eventorganization/conferenceorbooth_card.php +++ b/htdocs/eventorganization/conferenceorbooth_card.php @@ -3,7 +3,7 @@ * Copyright (C) 2021 Florian Henry * Copyright (C) 2024 Alexandre Spangaro * Copyright (C) 2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -187,7 +187,7 @@ $help_url = 'EN:Module_Event_Organization'; llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-eventorganization page-card'); if ($action == 'create') { - $result = $projectstatic->fetch(GETPOST('fk_project')); + $result = $projectstatic->fetch(GETPOSTINT('fk_project')); } else { $result = $projectstatic->fetch($object->fk_project); } @@ -351,7 +351,7 @@ if (!empty($withproject)) { $htmltext = $langs->trans("AllowUnknownPeopleSuggestConfHelp"); print $form->editfieldkey('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', '', $projectstatic, 0, $typeofdata, '', 0, 0, 'projectid', $htmltext); print ''; - print $form->editfieldval('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', '1', $projectstatic, 0, $typeofdata, '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', '1', $projectstatic, 0, $typeofdata, '', null, null, '', 0, '', 'projectid'); print ""; print ''; @@ -359,25 +359,25 @@ if (!empty($withproject)) { $htmltext = $langs->trans("AllowUnknownPeopleSuggestBoothHelp"); print $form->editfieldkey('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', '', $projectstatic, 0, $typeofdata, '', 0, 0, 'projectid', $htmltext); print ''; - print $form->editfieldval('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', '1', $projectstatic, 0, $typeofdata, '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', '1', $projectstatic, 0, $typeofdata, '', null, null, '', 0, '', 'projectid'); print ""; print ''; print $form->editfieldkey($form->textwithpicto($langs->trans('PriceOfBooth'), $langs->trans("PriceOfBoothHelp")), 'price_booth', '', $projectstatic, 0, 'amount', '', 0, 0, 'projectid'); print ''; - print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfBooth'), $langs->trans("PriceOfBoothHelp")), 'price_booth', $projectstatic->price_booth, $projectstatic, 0, 'amount', '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfBooth'), $langs->trans("PriceOfBoothHelp")), 'price_booth', $projectstatic->price_booth, $projectstatic, 0, 'amount', '', null, null, '', 0, '', 'projectid'); print ""; print ''; print $form->editfieldkey($form->textwithpicto($langs->trans('PriceOfRegistration'), $langs->trans("PriceOfRegistrationHelp")), 'price_registration', '', $projectstatic, 0, 'amount', '', 0, 0, 'projectid'); print ''; - print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfRegistration'), $langs->trans("PriceOfRegistrationHelp")), 'price_registration', $projectstatic->price_registration, $projectstatic, 0, 'amount', '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfRegistration'), $langs->trans("PriceOfRegistrationHelp")), 'price_registration', $projectstatic->price_registration, $projectstatic, 0, 'amount', '', null, null, '', 0, '', 'projectid'); print ""; print ''; print $form->editfieldkey($form->textwithpicto($langs->trans('MaxNbOfAttendees'), ''), 'max_attendees', '', $projectstatic, $permissiontoadd, 'integer:3', '', 0, 0, 'projectid'); print ''; - print $form->editfieldval($form->textwithpicto($langs->trans('MaxNbOfAttendees'), ''), 'max_attendees', $projectstatic->max_attendees, $projectstatic, $permissiontoadd, 'integer:3', '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval($form->textwithpicto($langs->trans('MaxNbOfAttendees'), ''), 'max_attendees', $projectstatic->max_attendees, $projectstatic, $permissiontoadd, 'integer:3', '', null, null, '', 0, '', 'projectid'); print ""; print ''.$langs->trans("EventOrganizationICSLink").''; diff --git a/htdocs/eventorganization/conferenceorbooth_list.php b/htdocs/eventorganization/conferenceorbooth_list.php index 46bb260a6be..c3ce87e7aed 100644 --- a/htdocs/eventorganization/conferenceorbooth_list.php +++ b/htdocs/eventorganization/conferenceorbooth_list.php @@ -3,6 +3,7 @@ * Copyright (C) 2021 Florian Henry * Copyright (C) 2023-2024 Frédéric France * Copyright (C) 2024 Alexandre Spangaro + * Copyright (C) 2025 MDW * * 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 @@ -385,17 +386,6 @@ if ($projectid > 0) { print ''; } - // Visibility - print ''.$langs->trans("Visibility").''; - if ($project->public == 0) { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans("PrivateProject"); - } else { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans("SharedProject"); - } - print ''; - // Budget print ''.$langs->trans("Budget").''; if (strcmp($project->budget_amount, '')) { @@ -432,6 +422,17 @@ if ($projectid > 0) { print $project->location; print ''; + // Visibility + print ''.$langs->trans("Visibility").''; + if ($project->public == 0) { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans("PrivateProject"); + } else { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans("SharedProject"); + } + print ''; + // Other attributes $cols = 2; $objectconf = $object; @@ -447,11 +448,6 @@ if ($projectid > 0) { print ''; - // Description - print ''; - // Categories if (isModEnabled('category')) { print '"; } + // Description + print ''; + if ($project->description) { + print ''; + } + print ''; if (!$i) { diff --git a/htdocs/eventorganization/conferenceorboothattendee_card.php b/htdocs/eventorganization/conferenceorboothattendee_card.php index b7010dadaf5..899debd01d4 100644 --- a/htdocs/eventorganization/conferenceorboothattendee_card.php +++ b/htdocs/eventorganization/conferenceorboothattendee_card.php @@ -1,7 +1,7 @@ * Copyright (C) 2024 Alexandre Spangaro - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -75,6 +75,8 @@ $diroutputmassaction = $conf->eventorganization->dir_output.'/temp/massgeneratio $hookmanager->initHooks(array('conferenceorboothattendeecard', 'globalcard')); // Note that conf->hooks_modules contains array +$confOrBooth = null; + if ($conf_or_booth_id > 0) { $confOrBooth = new ConferenceOrBooth($db); $result = $confOrBooth->fetch($id > 0 ? $id : $conf_or_booth_id); @@ -221,7 +223,7 @@ $help_url = 'EN:Module_Event_Organization'; llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-eventorganization page-attendee-card'); -$result = $projectstatic->fetch(empty($confOrBooth->fk_project) ? $fk_project : $confOrBooth->fk_project); +$result = $projectstatic->fetch(($confOrBooth === null || empty($confOrBooth->fk_project)) ? $fk_project : $confOrBooth->fk_project); if (getDolGlobalString('PROJECT_ALLOW_COMMENT_ON_PROJECT') && method_exists($projectstatic, 'fetchComments') && empty($projectstatic->comments)) { $projectstatic->fetchComments(); } @@ -357,7 +359,7 @@ if (!empty($withproject)) { $htmltext = $langs->trans("AllowUnknownPeopleSuggestConfHelp"); print $form->editfieldkey('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', '', $projectstatic, 0, $typeofdata, '', 0, 0, 'projectid', $htmltext); print '"; print '"; print '"; print '"; print ''; } - // Visibility - print ''; - // Budget print ''; + // Visibility + print ''; + // Location event print ''; @@ -413,9 +413,9 @@ if ($id > 0 || !empty($ref)) { print '
'.$langs->trans("Description").''; - print dol_htmlentitiesbr($project->description); - print '
'.$langs->trans("Categories").''; @@ -459,6 +455,16 @@ if ($projectid > 0) { print "
'.$langs->trans("Description").'
'; + print '
'; + print dolPrintHTML($project->description); + print '
'; + print '
'; $typeofdata = 'checkbox:'.($project->accept_conference_suggestions ? ' checked="checked"' : ''); $htmltext = $langs->trans("AllowUnknownPeopleSuggestConfHelp"); @@ -880,7 +886,7 @@ foreach ($object->fields as $key => $val) { } elseif ($key == 'lang') { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; $formadmin = new FormAdmin($db); - print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth100imp maxwidth125', 2); + print $formadmin->select_language($search[$key], 'search_lang', 0, array(), 1, 0, 0, 'minwidth100imp maxwidth125', 2); } else { print ''; } @@ -1032,7 +1038,7 @@ while ($i < $imaxinloop) { if (!empty($arrayfields['t.'.$key]['checked'])) { print '$key)) { - print ' title="'.dol_escape_htmltag($object->$key).'"'; + print ' title="'.dol_escape_htmltag((string) $object->$key).'"'; } print '>'; if ($key == 'status') { @@ -1040,7 +1046,7 @@ while ($i < $imaxinloop) { } elseif ($key == 'ref') { print $object->getNomUrl(1, 0, '', (($projectid > 0) ? 'withproject' : '')); } else { - print $object->showOutputField($val, $key, $object->$key, ''); + print $object->showOutputField($val, $key, (string) $object->$key, ''); } print ''; - print $form->editfieldval('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', '1', $projectstatic, 0, $typeofdata, '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', '1', $projectstatic, 0, $typeofdata, '', null, null, '', 0, '', 'projectid'); print "
'; @@ -365,19 +367,19 @@ if (!empty($withproject)) { $htmltext = $langs->trans("AllowUnknownPeopleSuggestBoothHelp"); print $form->editfieldkey('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', '', $projectstatic, 0, $typeofdata, '', 0, 0, 'projectid', $htmltext); print ''; - print $form->editfieldval('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', '1', $projectstatic, 0, $typeofdata, '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', '1', $projectstatic, 0, $typeofdata, '', null, null, '', 0, '', 'projectid'); print "
'; print $form->editfieldkey($form->textwithpicto($langs->trans('PriceOfBooth'), $langs->trans("PriceOfBoothHelp")), 'price_booth', '', $projectstatic, 0, 'amount', '', 0, 0, 'projectid'); print ''; - print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfBooth'), $langs->trans("PriceOfBoothHelp")), 'price_booth', $projectstatic->price_booth, $projectstatic, 0, 'amount', '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfBooth'), $langs->trans("PriceOfBoothHelp")), 'price_booth', $projectstatic->price_booth, $projectstatic, 0, 'amount', '', null, null, '', 0, '', 'projectid'); print "
'; print $form->editfieldkey($form->textwithpicto($langs->trans('PriceOfRegistration'), $langs->trans("PriceOfRegistrationHelp")), 'price_registration', '', $projectstatic, 0, 'amount', '', 0, 0, 'projectid'); print ''; - print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfRegistration'), $langs->trans("PriceOfRegistrationHelp")), 'price_registration', $projectstatic->price_registration, $projectstatic, 0, 'amount', '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfRegistration'), $langs->trans("PriceOfRegistrationHelp")), 'price_registration', $projectstatic->price_registration, $projectstatic, 0, 'amount', '', null, null, '', 0, '', 'projectid'); print "
'.$langs->trans("EventOrganizationICSLink").''; @@ -439,7 +441,7 @@ if (!empty($withproject)) { } // Part to create -if ($action == 'create') { +if ($action == 'create' && $confOrBooth !== null) { print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("ConferenceOrBoothAttendee")), '', 'object_'.$object->picto); @@ -484,7 +486,7 @@ if ($action == 'create') { } // Part to edit record -if (($id || $ref) && $action == 'edit') { +if (($id || $ref) && $action == 'edit' && $confOrBooth !== null) { print load_fiche_titre($langs->trans("ConferenceOrBoothAttendee"), '', 'object_'.$object->picto); print '
'; @@ -527,7 +529,7 @@ if (($id || $ref) && $action == 'edit') { } // Part to show record -if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { +if ($confOrBooth !== null && $object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { $object->fetch_optionals(); $moreparam = ''; diff --git a/htdocs/eventorganization/conferenceorboothattendee_list.php b/htdocs/eventorganization/conferenceorboothattendee_list.php index c5934e13ecd..14d85080c0b 100644 --- a/htdocs/eventorganization/conferenceorboothattendee_list.php +++ b/htdocs/eventorganization/conferenceorboothattendee_list.php @@ -3,6 +3,7 @@ * Copyright (C) 2021 Florian Henry * Copyright (C) 2024 Alexandre Spangaro * Copyright (C) 2024 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -484,17 +485,6 @@ if ($projectstatic->id > 0 || $confOrBooth > 0) { print '
'.$langs->trans("Visibility").''; - if ($projectstatic->public == 0) { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans("PrivateProject"); - } else { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans("SharedProject"); - } - print '
'.$langs->trans("Budget").''; if (strcmp($projectstatic->budget_amount, '')) { @@ -526,6 +516,17 @@ if ($projectstatic->id > 0 || $confOrBooth > 0) { } print '
'.$langs->trans("Visibility").''; + if ($projectstatic->public == 0) { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans("PrivateProject"); + } else { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans("SharedProject"); + } + print '
'.$langs->trans("Location").''; print $projectstatic->location; @@ -547,11 +548,6 @@ if ($projectstatic->id > 0 || $confOrBooth > 0) { print ''; - // Description - print ''; - // Categories if (isModEnabled('category')) { print '"; } + // Description + print ''; + if ($projectstatic->description) { + print ''; + } + print '"; print '"; print '"; print '"; print '"; - // Link to ICS for the event - print '"; + // Show message + $message = ''.$langs->trans('DownloadICSLink').img_picto('', 'download', 'class="paddingleft"').''; + print $message; + print ""; print ''; if (!$i) { diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 1b74583596c..a19523f9d7b 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -14,7 +14,7 @@ * Copyright (C) 2018-2024 Frédéric France * Copyright (C) 2020 Lenin Rivas * Copyright (C) 2022 Josep Lluís Amador - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -388,7 +388,7 @@ if (empty($reshook)) { } // Extrafields - $array_options[$i] = $extrafields->getOptionalsFromPost($object->table_element_line, $i); + $array_options[$i] = $extrafields->getOptionalsFromPost($object->table_element_line, (string) $i); // Unset extrafield if (isset($extrafields->attributes[$object->table_element_line]['label']) && is_array($extrafields->attributes[$object->table_element_line]['label'])) { // Get extra fields @@ -528,7 +528,7 @@ if (empty($reshook)) { } } elseif ($action == 'confirm_cancel' && $confirm == 'yes' && $user->hasRight('expedition', 'supprimer')) { $also_update_stock = (GETPOST('alsoUpdateStock', 'alpha') ? 1 : 0); - $result = $object->cancel(0, $also_update_stock); + $result = $object->cancel(0, (bool) $also_update_stock); if ($result > 0) { $result = $object->setStatut(-1); } else { @@ -536,7 +536,7 @@ if (empty($reshook)) { } } elseif ($action == 'confirm_delete' && $confirm == 'yes' && $user->hasRight('expedition', 'supprimer')) { $also_update_stock = (GETPOST('alsoUpdateStock', 'alpha') ? 1 : 0); - $result = $object->delete($user, 0, $also_update_stock); + $result = $object->delete($user, 0, (bool) $also_update_stock); if ($result > 0) { header("Location: ".DOL_URL_ROOT.'/expedition/index.php'); exit; @@ -1035,7 +1035,7 @@ if ($action == 'create') { print ''; print ''; print ''; @@ -1081,7 +1081,7 @@ if ($action == 'create') { print ''; @@ -1094,7 +1094,7 @@ if ($action == 'create') { print ' x '; print ' x '; print ' '; - $text = $formproduct->selectMeasuringUnits("size_units", "size", GETPOSTINT('size_units'), 0, 2); + $text = $formproduct->selectMeasuringUnits("size_units", "size", (string) GETPOSTINT('size_units'), 0, 2); $htmltext = $langs->trans("KeepEmptyForAutoCalculation"); print $form->textwithpicto($text, $htmltext); print ''; @@ -1277,7 +1277,7 @@ if ($action == 'create') { $text .= ' - '.(!empty($line->label) ? $line->label : $line->product_label); $description = ($showdescinproductdesc ? '' : dol_htmlentitiesbr($line->desc)); - print $form->textwithtooltip($text, $description, 3, 0, '', $i); + print $form->textwithtooltip($text, $description, 3, 0, '', (string) $i); // Show range print_date_range($db->jdate($line->date_start), $db->jdate($line->date_end)); @@ -1298,7 +1298,7 @@ if ($action == 'create') { if (!empty($line->label)) { $text .= ' '.$line->label.''; - print $form->textwithtooltip($text, $line->desc, 3, 0, '', $i); + print $form->textwithtooltip($text, $line->desc, 3, 0, '', (string) $i); } else { print $text.' '.nl2br($line->desc); } @@ -1856,7 +1856,7 @@ if ($action == 'create') { $expLine->array_options = array_merge($expLine->array_options, $srcLine->array_options); - print $expLine->showOptionals($extrafields, 'edit', array('style' => 'class="drag drop oddeven"', 'colspan' => $colspan), $indiceAsked, '', 1); + print $expLine->showOptionals($extrafields, 'edit', array('style' => 'class="drag drop oddeven"', 'colspan' => $colspan), (string) $indiceAsked, '', '1'); } } @@ -2003,7 +2003,7 @@ if ($action == 'create') { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, (string) $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($objectsrc) && !empty($objectsrc->fk_project)) { $proj = new Project($db); @@ -2107,13 +2107,13 @@ if ($action == 'create') { print ''; print ''; print ''; - print $formproduct->selectMeasuringUnits("weight_units", "weight", $object->weight_units, 0, 2, 'maxwidth125 valignmiddle'); + print $formproduct->selectMeasuringUnits("weight_units", "weight", (string) $object->weight_units, 0, 2, 'maxwidth125 valignmiddle'); print ' '; print ' '; print ''; } else { print $object->trueWeight; - print ($object->trueWeight && $object->weight_units != '') ? ' '.measuringUnitString(0, "weight", $object->weight_units) : ''; + print ($object->trueWeight && $object->weight_units != '') ? ' '.measuringUnitString(0, "weight", (string) $object->weight_units) : ''; } // Calculated @@ -2228,7 +2228,7 @@ if ($action == 'create') { } else { if ($object->shipping_method_id > 0) { // Get code using getLabelFromKey - $code = $langs->getLabelFromKey($db, $object->shipping_method_id, 'c_shipment_mode', 'rowid', 'code'); + $code = $langs->getLabelFromKey($db, (string) $object->shipping_method_id, 'c_shipment_mode', 'rowid', 'code'); print $langs->trans("SendingMethod".strtoupper($code)); } } @@ -2462,7 +2462,7 @@ if ($action == 'create') { $text = $product_static->getNomUrl(1); $text .= ' - '.$label; $description = (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE') ? '' : dol_htmlentitiesbr($lines[$i]->description)); - print $form->textwithtooltip($text, $description, 3, 0, '', $i); + print $form->textwithtooltip($text, $description, 3, 0, '', (string) $i); print_date_range(!empty($lines[$i]->date_start) ? $lines[$i]->date_start : '', !empty($lines[$i]->date_end) ? $lines[$i]->date_end : ''); if (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE')) { print (!empty($lines[$i]->description) && $lines[$i]->description != $lines[$i]->product) ? '
'.dol_htmlentitiesbr($lines[$i]->description) : ''; @@ -2478,7 +2478,7 @@ if ($action == 'create') { if (!empty($lines[$i]->label)) { $text .= ' '.$lines[$i]->label.''; - print $form->textwithtooltip($text, $lines[$i]->description, 3, 0, '', $i); + print $form->textwithtooltip($text, $lines[$i]->description, 3, 0, '', (string) $i); } else { print $text.' '.nl2br($lines[$i]->description); } @@ -2489,7 +2489,7 @@ if ($action == 'create') { $unit_order = ''; if (getDolGlobalString('PRODUCT_USE_UNITS')) { - $unit_order = measuringUnitString($lines[$i]->fk_unit); + $unit_order = measuringUnitString((int) $lines[$i]->fk_unit); } // Qty ordered @@ -2529,7 +2529,7 @@ if ($action == 'create') { } } } - print $form->textwithpicto($qtyalreadysent, $htmltooltip, 1, 'info', '', 0, 3, 'tooltip'.$lines[$i]->id); + print $form->textwithpicto((string) $qtyalreadysent, $htmltooltip, 1, 'info', '', 0, 3, 'tooltip'.$lines[$i]->id); print ''; } @@ -2738,9 +2738,9 @@ if ($action == 'create') { // TODO Show all in same line by setting $display_type = 'line' if ($action == 'editline' && $line->id == $line_id) { - print $lines[$i]->showOptionals($extrafields, 'edit', array('colspan' => $colspan), !empty($indiceAsked) ? $indiceAsked : '', '', 0, 'card'); + print $lines[$i]->showOptionals($extrafields, 'edit', array('colspan' => $colspan), !empty($indiceAsked) ? $indiceAsked : '', '', '', 'card'); } else { - print $lines[$i]->showOptionals($extrafields, 'view', array('colspan' => $colspan), !empty($indiceAsked) ? $indiceAsked : '', '', 0, 'card'); + print $lines[$i]->showOptionals($extrafields, 'view', array('colspan' => $colspan), !empty($indiceAsked) ? $indiceAsked : '', '', '', 'card'); } } } diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 61e50c14373..b46fd85ccfd 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -13,7 +13,7 @@ * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2018-2025 Frédéric France * Copyright (C) 2020 Lenin Rivas - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 William Mead * * This program is free software; you can redistribute it and/or modify @@ -306,7 +306,6 @@ class Expedition extends CommonObject * Closed status * -> parcel was received by customer / end of process * prev status : validated or shipment_in_progress - * */ const STATUS_CLOSED = 2; @@ -1476,10 +1475,10 @@ class Expedition extends CommonObject * Delete shipment. * Warning, do not delete a shipment if a delivery is linked to (with table llx_element_element) * - * @param User $user User making the deletion - * @param int $notrigger Disable triggers - * @param bool $also_update_stock true if the stock should be increased back (false by default) - * @return int >0 if OK, 0 if deletion done but failed to delete files, <0 if KO + * @param ?User $user User making the deletion + * @param int<0,1> $notrigger Disable triggers + * @param bool $also_update_stock true if the stock should be increased back (false by default) + * @return int >0 if OK, 0 if deletion done but failed to delete files, <0 if KO */ public function delete($user = null, $notrigger = 0, $also_update_stock = false) { @@ -1609,6 +1608,13 @@ class Expedition extends CommonObject $error++; } + if (!$error) { + // Delete linked contacts + $res = $this->delete_linked_contact(); + if ($res < 0) { + $error++; + } + } if (!$error) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."expedition"; $sql .= " WHERE rowid = ".((int) $this->id); @@ -2437,7 +2443,6 @@ class Expedition extends CommonObject * @param string $labelmovement Label of movement * @return int Return integer <0 if KO, >0 if OK * @throws Exception - * */ private function manageStockMvtOnEvt($user, $labelmovement = 'ShipmentClassifyClosedInDolibarr') { diff --git a/htdocs/expedition/contact.php b/htdocs/expedition/contact.php index 3818847e84e..534515a84f6 100644 --- a/htdocs/expedition/contact.php +++ b/htdocs/expedition/contact.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2023 Christian Foellmann * Copyright (C) 2024 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -52,6 +53,7 @@ $id = GETPOSTINT('id'); $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); +$typeobject = null; $object = new Expedition($db); if ($id > 0 || !empty($ref)) { $object->fetch($id, $ref); @@ -85,7 +87,7 @@ $result = restrictedArea($user, 'expedition', $object->id, ''); * Actions */ -$parameters = array('id'=>$id); +$parameters = array('id' => $id); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); @@ -172,7 +174,7 @@ if ($id > 0 || !empty($ref)) { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, (string) $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($objectsrc) && !empty($objectsrc->fk_project)) { $proj = new Project($db); diff --git a/htdocs/expedition/dispatch.php b/htdocs/expedition/dispatch.php index e1340a8b0d7..67c30c5ff95 100644 --- a/htdocs/expedition/dispatch.php +++ b/htdocs/expedition/dispatch.php @@ -9,7 +9,7 @@ * Copyright (C) 2017-2022 Ferran Marcet * Copyright (C) 2018-2024 Frédéric France * Copyright (C) 2019-2020 Christophe Battarel - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -141,6 +141,7 @@ if ($action == 'updatelines' && $usercancreate) { $reg = array(); if (preg_match('/^product_.*([0-9]+)_([0-9]+)$/i', $key, $reg)) { $pos++; + $modebatch = null; if (preg_match('/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) { $modebatch = "barcode"; } elseif (preg_match('/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg)) { // With batchmode enabled @@ -156,7 +157,7 @@ if ($action == 'updatelines' && $usercancreate) { $qty = "qty_".$reg[1].'_'.$reg[2]; $ent = "entrepot_".$reg[1].'_'.$reg[2]; $fk_commandedet = "fk_commandedet_".$reg[1].'_'.$reg[2]; - $idline = GETPOST("idline_".$reg[1].'_'.$reg[2]); + $idline = GETPOSTINT("idline_".$reg[1].'_'.$reg[2]); $warehouse_id = GETPOSTINT($ent); $prod_id = GETPOSTINT($prod); //$pu = "pu_".$reg[1].'_'.$reg[2]; // This is unit price including discount @@ -245,6 +246,7 @@ if ($action == 'updatelines' && $usercancreate) { $sqlsearchdet .= " AND batch = '".$db->escape($lot)."'"; $resqlsearchdet = $db->query($sqlsearchdet); + $objsearchdet = null; if ($resqlsearchdet) { $objsearchdet = $db->fetch_object($resqlsearchdet); } else { @@ -384,6 +386,7 @@ $warehouse_static = new Entrepot($db); $title = $object->ref." - ".$langs->trans('ShipmentDistribution'); $help_url = 'EN:Module_Shipments|FR:Module_Expéditions|ES:Módulo_Expediciones|DE:Modul_Lieferungen'; $morejs = array('/expedition/js/lib_dispatch.js.php'); +$typeobject = null; llxHeader('', $title, $help_url, '', 0, 0, $morejs, '', '', 'mod-expedition page-card_dispatch'); @@ -459,7 +462,7 @@ if ($object->id > 0 || !empty($object->ref)) { if ($action != 'classify' && $permissiontoadd) { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, (!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') ? $object->socid : -1), $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, (!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') ? $object->socid : -1), (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($objectsrc) && !empty($objectsrc->fk_project)) { $proj = new Project($db); @@ -546,6 +549,11 @@ if ($object->id > 0 || !empty($object->ref)) { $entrepot = new Entrepot($db); $listwarehouses = $entrepot->list_array(1); + $nbfreeproduct = 0; // Nb of lines of free products/services + $nbproduct = 0; // Nb of predefined product lines to dispatch (already done or not) if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is off (default) + // or nb of line that remain to dispatch if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is on. + + print '
'; @@ -683,10 +691,6 @@ if ($object->id > 0 || !empty($object->ref)) { print "\n"; } - $nbfreeproduct = 0; // Nb of lines of free products/services - $nbproduct = 0; // Nb of predefined product lines to dispatch (already done or not) if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is off (default) - // or nb of line that remain to dispatch if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is on. - $conf->cache['product'] = array(); // Loop on each line of origin order diff --git a/htdocs/expedition/document.php b/htdocs/expedition/document.php index f8b1cc3ad85..4dc74e52a72 100644 --- a/htdocs/expedition/document.php +++ b/htdocs/expedition/document.php @@ -6,6 +6,7 @@ * Copyright (C) 2013 Cédric Salvador * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2024 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -79,6 +80,7 @@ if ($id > 0 || !empty($ref)) { $object->fetch($id, $ref); $object->fetch_thirdparty(); + $typeobject = null; if (!empty($object->origin)) { $typeobject = $object->origin; $origin = $object->origin; @@ -159,7 +161,7 @@ if ($id > 0 || !empty($ref)) { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, (string) $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($objectsrc->fk_project)) { $proj = new Project($db); diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index b45450396bc..03a6a11db5d 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -6,7 +6,7 @@ * Copyright (C) 2019 Nicolas ZABOURI * Copyright (C) 2020 Thibault FOUCART * Copyright (C) 2023 Christophe Battarel - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Benjamin Falière * Copyright (C) 2024 Vincent Maury * Copyright (C) 2024 William Mead @@ -557,9 +557,6 @@ if (empty($reshook)) { if ($search_company) { $param .= "&search_company=".urlencode($search_company); } - if ($search_shipping_method_id) { - $param .= "&search_shipping_method_id=".urlencode($search_shipping_method_id); - } if ($search_tracking) { $param .= "&search_tracking=".urlencode($search_tracking); } @@ -1089,7 +1086,7 @@ if ($massaction == 'createbills') { print $langs->trans('DateInvoice'); print ''; print '
'; print ''; print ''; @@ -1106,7 +1103,7 @@ if ($massaction == 'createbills') { print ''; print ''; } // Town @@ -1353,7 +1350,7 @@ if (!empty($arrayfields['e.signed_status']['checked'])) { // Status billed if (!empty($arrayfields['e.billed']['checked'])) { print ''; } // Action column @@ -1649,7 +1646,7 @@ while ($i < $imaxinloop) { } if (!empty($arrayfields['e.fk_shipping_method']['checked'])) { // Get code using getLabelFromKey - $code = $langs->getLabelFromKey($db, $object->shipping_method_id, 'c_shipment_mode', 'rowid', 'code'); + $code = $langs->getLabelFromKey($db, (string) $object->shipping_method_id, 'c_shipment_mode', 'rowid', 'code'); print '
'.$langs->trans("Description").''; - print dol_htmlentitiesbr($projectstatic->description); - print '
'.$langs->trans("Categories").''; @@ -559,12 +555,22 @@ if ($projectstatic->id > 0 || $confOrBooth > 0) { print "
'.$langs->trans("Description").'
'; + print '
'; + print dolPrintHTML($projectstatic->description); + print '
'; + print '
'; $typeofdata = 'checkbox:'.($projectstatic->accept_conference_suggestions ? ' checked="checked"' : ''); $htmltext = $langs->trans("AllowUnknownPeopleSuggestConfHelp"); print $form->editfieldkey('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', $projectstatic->accept_conference_suggestions ? 1 : 0, $projectstatic, 0, $typeofdata, '', 0, 0, 'projectid', $htmltext); print ''; - print $form->editfieldval('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', $projectstatic->accept_conference_suggestions ? 1 : 0, $projectstatic, 0, $typeofdata, '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', $projectstatic->accept_conference_suggestions ? 1 : 0, $projectstatic, 0, $typeofdata, '', null, null, '', 0, '', 'projectid'); print "
'; @@ -572,39 +578,39 @@ if ($projectstatic->id > 0 || $confOrBooth > 0) { $htmltext = $langs->trans("AllowUnknownPeopleSuggestBoothHelp"); print $form->editfieldkey('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', $projectstatic->accept_booth_suggestions ? 1 : 0, $projectstatic, 0, $typeofdata, '', 0, 0, 'projectid', $htmltext); print ''; - print $form->editfieldval('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', $projectstatic->accept_booth_suggestions ? 1 : 0, $projectstatic, 0, $typeofdata, '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', $projectstatic->accept_booth_suggestions ? 1 : 0, $projectstatic, 0, $typeofdata, '', null, null, '', 0, '', 'projectid'); print "
'; print $form->editfieldkey($form->textwithpicto($langs->trans('PriceOfBooth'), $langs->trans("PriceOfBoothHelp")), 'price_booth', '', $projectstatic, 0, 'amount', '', 0, 0, 'projectid'); print ''; - print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfBooth'), $langs->trans("PriceOfBoothHelp")), 'price_booth', $projectstatic->price_booth, $projectstatic, 0, 'amount', '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfBooth'), $langs->trans("PriceOfBoothHelp")), 'price_booth', $projectstatic->price_booth, $projectstatic, 0, 'amount', '', null, null, '', 0, '', 'projectid'); print "
'; print $form->editfieldkey($form->textwithpicto($langs->trans('PriceOfRegistration'), $langs->trans("PriceOfRegistrationHelp")), 'price_registration', '', $projectstatic, 0, 'amount', '', 0, 0, 'projectid'); print ''; - print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfRegistration'), $langs->trans("PriceOfRegistrationHelp")), 'price_registration', $projectstatic->price_registration, $projectstatic, 0, 'amount', '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfRegistration'), $langs->trans("PriceOfRegistrationHelp")), 'price_registration', $projectstatic->price_registration, $projectstatic, 0, 'amount', '', null, null, '', 0, '', 'projectid'); print "
'; print $form->editfieldkey($form->textwithpicto($langs->trans('MaxNbOfAttendees'), ''), 'max_attendees', '', $projectstatic, $permissiontoadd, 'integer:3', '&withproject=1', 0, 0, 'projectid'); print ''; - print $form->editfieldval($form->textwithpicto($langs->trans('MaxNbOfAttendees'), ''), 'max_attendees', $projectstatic->max_attendees, $projectstatic, $permissiontoadd, 'integer:3', '', null, 0, '&withproject=1', 0, '', 'projectid'); + print $form->editfieldval($form->textwithpicto($langs->trans('MaxNbOfAttendees'), ''), 'max_attendees', $projectstatic->max_attendees, $projectstatic, $permissiontoadd, 'integer:3', '', null, null, '&withproject=1', 0, '', 'projectid'); print "
'.$langs->trans("EventOrganizationICSLinkProject").''; + // Link to ICS for the event + print '
'.$langs->trans("EventOrganizationICSLinkProject").''; // Define $urlwithroot - $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); - $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; + $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); + $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; - // Show message - $message = ''.$langs->trans('DownloadICSLink').img_picto('', 'download', 'class="paddingleft"').''; - print $message; - print "
'.$langs->trans("EventOrganizationICSLink").''; // Define $urlwithroot @@ -870,7 +876,7 @@ foreach ($object->fields as $key => $val) { } elseif ($key == 'lang') { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; $formadmin = new FormAdmin($db); - print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth100imp maxwidth125', 2); + print $formadmin->select_language($search[$key], 'search_lang', 0, array(), 1, 0, 0, 'minwidth100imp maxwidth125', 2); } else { print ''; } @@ -1021,7 +1027,7 @@ while ($i < $imaxinloop) { if (!empty($arrayfields['t.'.$key]['checked'])) { print '$key)) { - print ' title="'.dol_escape_htmltag($object->$key).'"'; + print ' title="'.dol_escape_htmltag((string) $object->$key).'"'; } print '>'; if ($key == 'status') { @@ -1033,7 +1039,7 @@ while ($i < $imaxinloop) { } print $object->getNomUrl(1, $optionLink); } else { - print $object->showOutputField($val, $key, $object->$key, ''); + print $object->showOutputField($val, $key, (string) $object->$key, ''); } print '
'.$langs->trans("Project").''; print img_picto('', 'project', 'class="pictofixedwidth"'); - $numprojet = $formproject->select_projects($soc->id, $projectid, 'projectid', 0); + $numprojet = $formproject->select_projects($soc->id, (string) $projectid, 'projectid', 0); print ' id).'">'; print '
'; print img_picto('', 'fa-balance-scale', 'class="pictofixedwidth"'); print ' '; - $text = $formproduct->selectMeasuringUnits("weight_units", "weight", GETPOSTINT('weight_units'), 0, 2); + $text = $formproduct->selectMeasuringUnits("weight_units", "weight", (string) GETPOSTINT('weight_units'), 0, 2); $htmltext = $langs->trans("KeepEmptyForAutoCalculation"); print $form->textwithpicto($text, $htmltext); print '
'; - print $form->selectDate('', '', '', '', '', '', 1, 1); + print $form->selectDate('', '', 0, 0, 0, '', 1, 1); print '
'; if (!empty($conf->stock->enabled) && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) { - print $form->selectyesno('validate_invoices', 0, 1, 1); + print $form->selectyesno('validate_invoices', 0, 1, true); $langs->load("errors"); print ' ('.$langs->trans("WarningAutoValNotPossibleWhenStockIsDecreasedOnInvoiceVal").')'; } else { @@ -1152,7 +1149,7 @@ if ($user->hasRight('user', 'user', 'lire')) { $moreforfilter .= '
'; $tmptitle = $langs->trans('LinkedToSpecificUsers'); $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"'); - $moreforfilter .= $form->select_dolusers($search_user, 'search_user', $tmptitle, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth200'); + $moreforfilter .= $form->select_dolusers($search_user, 'search_user', $tmptitle, null, 0, '', '', '0', 0, 0, '', 0, '', 'maxwidth200'); $moreforfilter .= '
'; } // If the user can view prospects other than his' @@ -1190,7 +1187,7 @@ if (!empty($moreforfilter)) { } $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; -$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); +$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); // @phan-suppress-current-line PhanTypeMismatchArgument if ($massactionbutton) { $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); // This also change content of $arrayfields } @@ -1223,7 +1220,7 @@ if (!empty($arrayfields['e.ref_customer']['checked'])) { // Thirdparty if (!empty($arrayfields['s.nom']['checked'])) { print '
'; - print ''; + print ''; print ''; - print $form->selectyesno('search_billed', $search_billed, 1, 0, 1); + print $form->selectyesno('search_billed', $search_billed, 1, false, 1); print ''; if ($object->shipping_method_id > 0) { print $langs->trans("SendingMethod".strtoupper($code)); diff --git a/htdocs/expedition/note.php b/htdocs/expedition/note.php index 862253ba2ce..f2186c1be04 100644 --- a/htdocs/expedition/note.php +++ b/htdocs/expedition/note.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Florian Henry * Copyright (C) 2024 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -54,6 +55,7 @@ if ($id > 0 || !empty($ref)) { $object->fetch($id, $ref); $object->fetch_thirdparty(); + $typeobject = null; if (!empty($object->origin)) { $typeobject = $object->origin; $origin = $object->origin; @@ -128,7 +130,7 @@ if ($id > 0 || !empty($ref)) { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, (string) $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($objectsrc) && !empty($objectsrc->fk_project)) { $proj = new Project($db); diff --git a/htdocs/expedition/shipment.php b/htdocs/expedition/shipment.php index 89930ef944c..c0d84059027 100644 --- a/htdocs/expedition/shipment.php +++ b/htdocs/expedition/shipment.php @@ -5,7 +5,7 @@ * Copyright (C) 2012-2015 Juanjo Menent * Copyright (C) 2018-2024 Frédéric France * Copyright (C) 2018-2022 Philippe Grand - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -146,7 +146,7 @@ if (empty($reshook)) { if ($action == 'setavailability' && $permissiontoadd) { $object->fetch($id); - $result = $object->availability(GETPOST('availability_id')); + $result = $object->availability(GETPOSTINT('availability_id')); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); } @@ -154,7 +154,7 @@ if (empty($reshook)) { if ($action == 'setdemandreason' && $permissiontoadd) { $object->fetch($id); - $result = $object->demand_reason(GETPOST('demand_reason_id')); + $result = $object->demand_reason(GETPOSTINT('demand_reason_id')); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); } @@ -301,7 +301,7 @@ if ($id > 0 || !empty($ref)) { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, (string) $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($objectsrc) && !empty($objectsrc->fk_project)) { $proj = new Project($db); @@ -336,8 +336,8 @@ if ($id > 0 || !empty($ref)) { print '
'.$langs->trans('Discounts').''; - $absolute_discount = $soc->getAvailableDiscounts('', $filterabsolutediscount); - $absolute_creditnote = $soc->getAvailableDiscounts('', $filtercreditnote); + $absolute_discount = $soc->getAvailableDiscounts(null, $filterabsolutediscount); + $absolute_creditnote = $soc->getAvailableDiscounts(null, $filtercreditnote); $absolute_discount = price2num($absolute_discount, 'MT'); $absolute_creditnote = price2num($absolute_creditnote, 'MT'); @@ -396,9 +396,9 @@ if ($id > 0 || !empty($ref)) { print '
'; print '
'; if ($action == 'editavailability') { - $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, $object->availability_id, 'availability_id', 1); + $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->availability_id, 'availability_id', 1); } else { - $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, $object->availability_id, 'none', 1); + $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->availability_id, 'none', 1); } print '
'; print ''; if ($action == 'editshippingmethod') { - $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'shipping_method_id', 1); + $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->shipping_method_id, 'shipping_method_id', 1); } else { - $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'none'); + $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->shipping_method_id, 'none'); } print ''; print ''; @@ -453,9 +453,9 @@ if ($id > 0 || !empty($ref)) { print ''; print ''; if ($action == 'editdemandreason') { - $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, $object->demand_reason_id, 'demand_reason_id', 1); + $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->demand_reason_id, 'demand_reason_id', 1); } else { - $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, $object->demand_reason_id, 'none'); + $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->demand_reason_id, 'none'); } // Terms of payment @@ -620,6 +620,9 @@ if ($id > 0 || !empty($ref)) { $sql .= " WHERE cd.fk_commande = ".((int) $object->id); $sql .= " ORDER BY cd.rang, cd.rowid"; + $toBeShipped = array(); + $toBeShippedTotal = 0; + //print $sql; dol_syslog("shipment.php", LOG_DEBUG); $resql = $db->query($sql); @@ -643,8 +646,6 @@ if ($id > 0 || !empty($ref)) { print "\n"; print ''; - $toBeShipped = array(); - $toBeShippedTotal = 0; while ($i < $num) { $objp = $db->fetch_object($resql); @@ -733,7 +734,7 @@ if ($id > 0 || !empty($ref)) { $text .= ' - '.$label; $description = (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE') ? '' : dol_htmlentitiesbr($objp->description)).'
'; $description .= $product_static->show_photos('product', $conf->product->multidir_output[$product_static->entity], 1, 1, 0, 0, 0, 80); - print $form->textwithtooltip($text, $description, 3, '', '', $i); + print $form->textwithtooltip($text, $description, 3, 0, '', (string) $i); // Show range print_date_range($db->jdate($objp->date_start), $db->jdate($objp->date_end)); @@ -754,7 +755,7 @@ if ($id > 0 || !empty($ref)) { if (!empty($objp->label)) { $text .= ' '.$objp->label.''; - print $form->textwithtooltip($text, $objp->description, 3, '', '', $i); + print $form->textwithtooltip($text, $objp->description, 3, 0, '', (string) $i); } else { print $text.' '.nl2br($objp->description); } diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index e0cd273c028..d931c854afb 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -5,7 +5,7 @@ * Copyright (C) 2015-2023 Alexandre Spangaro * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -234,6 +234,7 @@ if (empty($reshook)) { // Action clone object if ($action == 'confirm_clone' && $confirm == 'yes' && $permissiontoadd) { + // @phan-suppress-next-line PhanPluginBothLiteralsBinaryOp if (1 == 0 && !GETPOST('clone_content', 'alpha') && !GETPOST('clone_receivers', 'alpha')) { setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors'); } else { @@ -1358,7 +1359,7 @@ if (empty($reshook)) { if (!$error) { // TODO Use update method of ExpenseReportLine - $result = $object->updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $id, $fk_c_exp_tax_cat, $fk_ecm_files); + $result = $object->updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, (float) $qty, (float) $value_unit, $date, $id, $fk_c_exp_tax_cat, $fk_ecm_files); if ($result >= 0) { if ($result > 0) { // Define output language @@ -1431,6 +1432,7 @@ $paymentexpensereportstatic = new PaymentExpenseReport($db); $bankaccountstatic = new Account($db); $ecmfilesstatic = new EcmFiles($db); $formexpensereport = new FormExpenseReport($db); +$remaintopay = 0; // Create if ($action == 'create') { @@ -1474,7 +1476,7 @@ if ($action == 'create') { if (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('expensereport', 'writeall_advance')) { $include_users = array(); } - $s = $form->select_dolusers($defaultselectuser, "fk_user_author", 0, "", 0, $include_users, '', '0,'.$conf->entity); + $s = $form->select_dolusers($defaultselectuser, "fk_user_author", 0, null, 0, $include_users, '', '0,'.$conf->entity); print $s; print ''; print ''; @@ -1495,7 +1497,7 @@ if ($action == 'create') { if (GETPOSTINT('fk_user_validator') > 0) { $defaultselectuser = GETPOSTINT('fk_user_validator'); } - $s = $form->select_dolusers($defaultselectuser, "fk_user_validator", 1, "", ((empty($defaultselectuser) || !getDolGlobalString('EXPENSEREPORT_DEFAULT_VALIDATOR_UNCHANGEABLE')) ? 0 : 1), $include_users); + $s = $form->select_dolusers($defaultselectuser, "fk_user_validator", 1, null, ((empty($defaultselectuser) || !getDolGlobalString('EXPENSEREPORT_DEFAULT_VALIDATOR_UNCHANGEABLE')) ? 0 : 1), $include_users); print $form->textwithpicto($s, $langs->trans("AnyOtherInThisListCanValidate")); } print ''; @@ -1552,6 +1554,7 @@ if ($action == 'create') { print ''; } elseif ($id > 0 || $ref) { + $userauthor = null; $result = $object->fetch($id, $ref); if ($result > 0) { @@ -1624,7 +1627,7 @@ if ($action == 'create') { print ''; print ''.$langs->trans("ModePaiement").''; print ''; - $form->select_types_paiements($object->fk_c_paiement, 'fk_c_paiement'); + $form->select_types_paiements((string) $object->fk_c_paiement, 'fk_c_paiement'); print ''; print ''; } @@ -1634,7 +1637,7 @@ if ($action == 'create') { print ''.$langs->trans("VALIDATOR").''; // Approbator print ''; $include_users = $object->fetch_users_approver_expensereport(); - $s = $form->select_dolusers($object->fk_user_validator, "fk_user_validator", 1, "", 0, $include_users); + $s = $form->select_dolusers($object->fk_user_validator, "fk_user_validator", 1, null, 0, $include_users); print $form->textwithpicto($s, $langs->trans("AnyOtherInThisListCanValidate")); print ''; print ''; @@ -2225,7 +2228,7 @@ if ($action == 'create') { print ''.price($line->value_unit).''; - print ''.dol_escape_htmltag($line->qty).''; + print ''.dol_escape_htmltag((string) $line->qty).''; if ($action != 'editline') { print ''.price($line->total_ht).''; @@ -2400,7 +2403,7 @@ if ($action == 'create') { // Select project if (isModEnabled('project')) { print ''; - $formproject->select_projects(-1, $line->fk_project, 'fk_project', 0, 0, $projectRequired ? 0 : 1, 1, 0, 0, 0, '', 0, 0, 'maxwidth300'); + $formproject->select_projects(-1, (string) $line->fk_project, 'fk_project', 0, 0, $projectRequired ? 0 : 1, 1, 0, 0, 0, '', 0, 0, 'maxwidth300'); print ''; } @@ -2412,7 +2415,7 @@ if ($action == 'create') { if (getDolGlobalString('MAIN_USE_EXPENSE_IK')) { print ''; $params = array('fk_expense' => $object->id, 'fk_expense_det' => $line->id, 'date' => $line->date); - print $form->selectExpenseCategories($line->fk_c_exp_tax_cat, 'fk_c_exp_tax_cat', 1, array(), 'fk_c_type_fees', $userauthor->default_c_exp_tax_cat, $params); + print $form->selectExpenseCategories($line->fk_c_exp_tax_cat, 'fk_c_exp_tax_cat', 1, array(), 'fk_c_type_fees', (string) $userauthor->default_c_exp_tax_cat, $params); print ''; } @@ -2424,7 +2427,7 @@ if ($action == 'create') { // VAT $selectedvat = price2num($line->vatrate).(!empty($line->vat_src_code) ? ' ('.$line->vat_src_code.')' : ''); print ''; - print $form->load_tva('vatrate', (GETPOSTISSET("vatrate") ? GETPOST("vatrate") : $selectedvat), $mysoc, '', 0, 0, '', false, 1, 2); + print $form->load_tva('vatrate', (GETPOSTISSET("vatrate") ? GETPOST("vatrate") : $selectedvat), $mysoc, null, 0, 0, '', false, 1, 2); print ''; // Unit price @@ -2439,7 +2442,7 @@ if ($action == 'create') { // Quantity print ''; - print ''; // We must be able to enter decimal qty + print ''; // We must be able to enter decimal qty print ''; //print ''.$langs->trans('AmountHT').''; @@ -2455,7 +2458,7 @@ if ($action == 'create') { print ''; print ''; - print $form->buttonsSaveCancel('Save', 'Cancel', array(), 0, 'small'); + print $form->buttonsSaveCancel('Save', 'Cancel', array(), false, 'small'); print ''; print ''; @@ -2582,7 +2585,7 @@ if ($action == 'create') { // Select project if (isModEnabled('project')) { print ''; - $formproject->select_projects(-1, !empty($fk_project) ? $fk_project : 0, 'fk_project', 0, 0, $projectRequired ? 0 : 1, -1, 0, 0, 0, '', 0, 0, 'maxwidth300'); + $formproject->select_projects(-1, !empty($fk_project) ? (string) $fk_project : '0', 'fk_project', 0, 0, $projectRequired ? 0 : 1, -1, 0, 0, 0, '', 0, 0, 'maxwidth300'); print ''; } @@ -2610,7 +2613,7 @@ if ($action == 'create') { // If option to have no default VAT on expense report is on, we force MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS = 'none'; } - print $form->load_tva('vatrate', (!empty($vatrate) ? $vatrate : $defaultvat), $mysoc, '', 0, 0, '', false, 1); + print $form->load_tva('vatrate', (!empty($vatrate) ? $vatrate : $defaultvat), $mysoc, null, 0, 0, '', false, 1); print ''; // Unit price net @@ -2638,7 +2641,7 @@ if ($action == 'create') { } print ''; - print $form->buttonsSaveCancel("Add", '', '', 1, 'reposition'); + print $form->buttonsSaveCancel("Add", '', array(), true, 'reposition'); print ''; print ''; @@ -2938,7 +2941,7 @@ if ($action != 'presend') { // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, 'expensereport', null); + $somethingshown = $formactions->showactions($object, 'expensereport', 0); print '
'; } diff --git a/htdocs/expensereport/payment/card.php b/htdocs/expensereport/payment/card.php index bd58dbaad93..9aa1c990e47 100644 --- a/htdocs/expensereport/payment/card.php +++ b/htdocs/expensereport/payment/card.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -130,6 +130,7 @@ print ''.$langs->trans('Amount').''.price($object->amount, 0, $ print ''.$langs->trans('Note').''.dol_string_onlythesehtmltags(dol_htmlentitiesbr($object->note_public)).''; $disable_delete = 0; +$title_button = ''; // Bank account if (isModEnabled("bank")) { if ($object->bank_account) { diff --git a/htdocs/expensereport/payment/info.php b/htdocs/expensereport/payment/info.php index cb83c850443..5b6fa16191c 100644 --- a/htdocs/expensereport/payment/info.php +++ b/htdocs/expensereport/payment/info.php @@ -4,6 +4,7 @@ * Copyright (C) 2013 Marcos García * Copyright (C) 2015 Alexandre Spangaro * Copyright (C) 2024 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -42,7 +43,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/expensereport.lib.php'; // Load translation files required by the page $langs->loadLangs(array('bills', 'trips')); -$id = GETPOST('id'); +$id = GETPOSTINT('id'); $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); diff --git a/htdocs/expensereport/payment/payment.php b/htdocs/expensereport/payment/payment.php index 2c69d7af7c9..b0045757bab 100644 --- a/htdocs/expensereport/payment/payment.php +++ b/htdocs/expensereport/payment/payment.php @@ -2,7 +2,7 @@ /* Copyright (C) 2015 Alexandre Spangaro * Copyright (C) 2015 Laurent Destailleur * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -225,6 +225,7 @@ if ($action == 'create' || empty($action)) { $sql .= " FROM ".MAIN_DB_PREFIX."payment_expensereport as p, ".MAIN_DB_PREFIX."expensereport as e"; $sql .= " WHERE p.fk_expensereport = e.rowid AND p.fk_expensereport = ".((int) $id); $sql .= ' AND e.entity IN ('.getEntity('expensereport').')'; + $sumpaid = 0; $resql = $db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); diff --git a/htdocs/expensereport/stats/index.php b/htdocs/expensereport/stats/index.php index 0ddaee0be92..e5bb55b9438 100644 --- a/htdocs/expensereport/stats/index.php +++ b/htdocs/expensereport/stats/index.php @@ -2,8 +2,8 @@ /* Copyright (C) 2003-2006 Rodolphe Quiedeville * Copyright (c) 2004-2012 Laurent Destailleur * Copyright (C) 2012 Marcos García - * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2018-2024 Frédéric France + * Copyright (C) 2024-2025 MDW * * 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 @@ -159,6 +159,7 @@ if (!$mesg) { $data = $stats->getAverageByMonthWithPrevYear($endyear, $startyear); +$fileurl_avg = null; if (!$user->hasRight('societe', 'client', 'voir')) { $filename_avg = $dir.'/ordersaverage-'.$user->id.'-'.$year.'.png'; if ($mode == 'customer') { @@ -179,7 +180,7 @@ if (!$user->hasRight('societe', 'client', 'voir')) { $px3 = new DolGraph(); $mesg = $px3->isGraphKo(); -if (!$mesg) { +if (!$mesg && $fileurl_avg !== null) { $px3->SetData($data); $i = $startyear; $legend = array(); @@ -190,7 +191,7 @@ if (!$mesg) { $px3->SetLegend($legend); $px3->SetYLabel($langs->trans("AmountAverage")); $px3->SetMaxValue($px3->GetCeilMaxValue()); - $px3->SetMinValue($px3->GetFloorMinValue()); + $px3->SetMinValue((int) $px3->GetFloorMinValue()); $px3->SetWidth($WIDTH); $px3->SetHeight($HEIGHT); $px3->SetShading(3); @@ -248,7 +249,7 @@ if (!$user->hasRight('expensereport', 'readall') && !$user->hasRight('expenserep $include = 'hierarchy'; } print img_picto('', 'user', 'class="pictofixedwidth"'); -print $form->select_dolusers($userid, 'userid', 1, '', 0, $include, '', 0, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300'); +print $form->select_dolusers($userid, 'userid', 1, null, 0, $include, '', '', 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300'); print ''; // Status print ''.$langs->trans("Status").''; diff --git a/htdocs/expensereport/tpl/expensereport_addfile.tpl.php b/htdocs/expensereport/tpl/expensereport_addfile.tpl.php index ff2fd3d4285..b0442bd9a10 100644 --- a/htdocs/expensereport/tpl/expensereport_addfile.tpl.php +++ b/htdocs/expensereport/tpl/expensereport_addfile.tpl.php @@ -1,4 +1,13 @@ + */ + +/** + * @var int $colspan + */ +' +@phan-var-force int $colspan +'; // Add line to upload new file print ''."\n"; diff --git a/htdocs/expensereport/tpl/expensereport_linktofile.tpl.php b/htdocs/expensereport/tpl/expensereport_linktofile.tpl.php index 2e02e7b8808..c565fe32894 100644 --- a/htdocs/expensereport/tpl/expensereport_linktofile.tpl.php +++ b/htdocs/expensereport/tpl/expensereport_linktofile.tpl.php @@ -1,6 +1,12 @@ +/* Copyright (C) 2024-2025 MDW */ +/** + * @var int $colspan + */ +' +@phan-var-force int $colspan +'; // Add line to select existing file if (!getDolGlobalString('EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES')) { @@ -29,6 +35,7 @@ if (!getDolGlobalString('EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES')) { $maxheightmini = 48; $relativepath = (!empty($object->ref) ? dol_sanitizeFileName($object->ref) : '').'/'; $filei = 0; + $minifile = null; // Loop on each attached file foreach ($arrayoffiles as $file) { $urlforhref = array(); @@ -95,7 +102,8 @@ if (!getDolGlobalString('EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES')) { } print '
'; - print $thumbshown ? $thumbshown : img_mime($minifile); + // TODO: Check that $minifile has a proper value here (set in true part of if, not else part). + print $thumbshown ? $thumbshown : ($minifile ? img_mime($minifile) : null); print '
'; if (empty($urlforhref) || empty($thumbshown)) { diff --git a/htdocs/fichinter/card-rec.php b/htdocs/fichinter/card-rec.php index 93b6157ea19..8ad1c46c169 100644 --- a/htdocs/fichinter/card-rec.php +++ b/htdocs/fichinter/card-rec.php @@ -10,7 +10,7 @@ * Copyright (C) 2016-2018 Charlie Benke * Copyright (C) 2018-2024 Frédéric France * Copyright (C) 2024 William Mead - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -121,7 +121,7 @@ $result = restrictedArea($user, 'ficheinter', $id, $objecttype); $permissiontoadd = $user->hasRight('ficheinter', 'creer'); $permissiontodelete = $user->hasRight('ficheinter', 'supprimer'); - +$objp = null; /* * Actions @@ -215,7 +215,7 @@ if ($action == 'add' && $permissiontoadd) { } $newinter->entity = $object->entity; - $newinter->duree = $object->duree; + $newinter->duration = $object->duration; $newinter->description = $object->description; $newinter->note_private = $object->note_private; @@ -254,7 +254,7 @@ if ($action == 'add' && $permissiontoadd) { } elseif ($action == 'setfrequency' && $permissiontoadd) { // Set frequency and unit frequency $object->fetch($id); - $object->setFrequencyAndUnit(GETPOST('frequency', 'int'), GETPOST('unit_frequency', 'alpha')); + $object->setFrequencyAndUnit(GETPOSTINT('frequency'), GETPOST('unit_frequency', 'alpha')); } elseif ($action == 'setdate_when' && $permissiontoadd) { // Set next date of execution $object->fetch($id); @@ -280,6 +280,8 @@ llxHeader('', $langs->trans("RepeatableIntervention"), $help_url, '', 0, 0, '', $form = new Form($db); $fichinterrecstatic = new FichinterRec($db); $companystatic = new Societe($db); +$contratstatic = null; +$projectstatic = null; if (isModEnabled('contract')) { $contratstatic = new Contrat($db); } @@ -508,7 +510,7 @@ if ($action == 'create') { $object->fetch_thirdparty(); $author = new User($db); - $author->fetch($object->user_author); + $author->fetch((int) $object->user_author); $head = fichinter_rec_prepare_head($object); @@ -535,11 +537,11 @@ if ($action == 'create') { $morehtmlref .= '
'; $morehtmlref .= ''; $morehtmlref .= ''; - $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref .= $formproject->select_projects($object->socid, (string) $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); $morehtmlref .= ''; $morehtmlref .= '
'; } else { - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); } } else { if (!empty($object->fk_project)) { @@ -577,7 +579,7 @@ if ($action == 'create') { print ''.$langs->trans("Description").''.nl2br($object->description).""; // Contract - if (isModEnabled('contract')) { + if (isModEnabled('contract') && $contratstatic !== null) { $langs->load('contracts'); print ''; print ''; @@ -599,7 +601,7 @@ if ($action == 'create') { if ($object->fk_contrat) { $contratstatic = new Contrat($db); $contratstatic->fetch($object->fk_contrat); - print $contratstatic->getNomUrl(0, '', 1); + print $contratstatic->getNomUrl(0, 0, 1); } else { print " "; } @@ -666,7 +668,7 @@ if ($action == 'create') { // Max period / Rest period print ''; if ($user->hasRight('ficheinter', 'creer') && ($action == 'nb_gen_max' || $object->frequency > 0)) { - print $form->editfieldkey($langs->trans("MaxPeriodNumber"), 'nb_gen_max', $object->nb_gen_max, $object, $user->hasRight('facture', 'creer')); + print $form->editfieldkey($langs->trans("MaxPeriodNumber"), 'nb_gen_max', (string) $object->nb_gen_max, $object, $user->hasRight('facture', 'creer')); } else { print $langs->trans("MaxPeriodNumber"); } @@ -743,7 +745,8 @@ if ($action == 'create') { $type = $object->lines[$i]->product_type; } // else { $object->lines[$i]->fk_product_type; } - if (isset($objp) && is_object($objp)) { + // TODO: $objp is not set here, so why test? + if (isset($objp) && is_object($objp)) { // $objp always null @phpstan-ignore-line // Try to enhance type detection using date_start and date_end for free lines when type // was not saved. if (!empty($objp->date_start)) { @@ -871,7 +874,7 @@ if ($action == 'create') { print ''.$langs->trans("None").''; } - if (isModEnabled('contract')) { + if (isModEnabled('contract') && $contratstatic !== null) { print ''; if ($objp->fk_contrat > 0) { $contratstatic->fetch($objp->fk_contrat); @@ -879,7 +882,7 @@ if ($action == 'create') { } print ''; } - if (isModEnabled('project')) { + if (isModEnabled('project') && $projectstatic !== null) { print ''; if ($objp->fk_project > 0) { $projectstatic->fetch($objp->fk_project); diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index 07311a5ca20..f3c6ca5250f 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -11,7 +11,7 @@ * Copyright (C) 2020-2024 Frédéric France * Copyright (C) 2023 Benjamin Grembi * Copyright (C) 2023-2024 William Mead - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify @@ -937,7 +937,7 @@ if ($action == 'create') { $classname = ucfirst($subelement); $objectsrc = new $classname($db); '@phan-var-force Commande|Propal|Contrat $objectsrc'; - $objectsrc->fetch(GETPOST('originid')); + $objectsrc->fetch(GETPOSTINT('originid')); if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines')) { $objectsrc->fetch_lines(); $lines = $objectsrc->lines; @@ -1048,7 +1048,7 @@ if ($action == 'create') { print ''; print ''.$langs->trans('NotePublic').''; print ''; - $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%'); + $doleditor = new DolEditor('note_public', (string) $note_public, '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%'); print $doleditor->Create(1); //print ''; print ''; @@ -1058,7 +1058,7 @@ if ($action == 'create') { print ''; print ''.$langs->trans('NotePrivate').''; print ''; - $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%'); + $doleditor = new DolEditor('note_private', (string) $note_private, '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%'); print $doleditor->Create(1); //print ''; print ''; @@ -1316,7 +1316,7 @@ if ($action == 'create') { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($object->fk_project)) { $proj = new Project($db); @@ -1509,13 +1509,11 @@ if ($action == 'create') { $extrafields->fetch_name_optionals_label($objectline->table_element); - if (!empty($extrafields)) { - $temps = $objectline->showOptionals($extrafields, 'view', array(), '', '', 1, 'line'); - if (!empty($temps)) { - print '
'; - print $temps; - print '
'; - } + $temps = $objectline->showOptionals($extrafields, 'view', array(), '', '', '1', 'line'); + if (!empty($temps)) { + print '
'; + print $temps; + print '
'; } print ''; @@ -1581,13 +1579,11 @@ if ($action == 'create') { $extrafields->fetch_name_optionals_label($objectline->table_element); - if (!empty($extrafields)) { - $temps = $objectline->showOptionals($extrafields, 'edit', array(), '', '', 1, 'line'); - if (!empty($temps)) { - print '
'; - print $temps; - print '
'; - } + $temps = $objectline->showOptionals($extrafields, 'edit', array(), '', '', '1', 'line'); + if (!empty($temps)) { + print '
'; + print $temps; + print '
'; } print ''; @@ -1663,7 +1659,7 @@ if ($action == 'create') { $extrafields->fetch_name_optionals_label($objectline->table_element); if (is_object($objectline)) { - $temps = $objectline->showOptionals($extrafields, 'create', array(), '', '', 1, 'line'); + $temps = $objectline->showOptionals($extrafields, 'create', array(), '', '', '1', 'line'); if (!empty($temps)) { print '
'; diff --git a/htdocs/fichinter/class/api_interventions.class.php b/htdocs/fichinter/class/api_interventions.class.php index 08697cc34c2..7a86225622e 100644 --- a/htdocs/fichinter/class/api_interventions.class.php +++ b/htdocs/fichinter/class/api_interventions.class.php @@ -1,6 +1,7 @@ * Copyright (C) 2016 Laurent Destailleur + * Copyright (C) 2025 MDW * * 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 @@ -35,25 +36,25 @@ require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php'; class Interventions extends DolibarrApi { /** - * @var array $FIELDS Mandatory fields, checked when create and update object + * @var string[] Mandatory fields, checked when create and update object */ public static $FIELDS = array( - 'socid', - 'fk_project', - 'description', + 'socid', + 'fk_project', + 'description', ); /** - * @var array $FIELDS Mandatory fields, checked when create and update object + * @var string[] Mandatory fields, checked when create and update object */ public static $FIELDSLINE = array( - 'description', - 'date', - 'duree', + 'description', + 'date', + 'duree', ); /** - * @var Fichinter $fichinter {@type fichinter} + * @var Fichinter {@type fichinter} */ public $fichinter; @@ -107,6 +108,8 @@ class Interventions extends DolibarrApi * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" * @param string $properties Restrict the data returned to these properties. Ignored if empty. Comma separated list of properties names * @return array Array of order objects + * @phan-return array + * @phpstan-return array * * @throws RestException */ @@ -186,6 +189,8 @@ class Interventions extends DolibarrApi * Create intervention object * * @param array $request_data Request data + * @phan-param ?array $request_data + * @phpstan-param ?array $request_data * @return int ID of intervention */ public function post($request_data = null) @@ -251,6 +256,8 @@ class Interventions extends DolibarrApi * * @param int $id Id of intervention to update * @param array $request_data Request data + * @phan-param ?array $request_data + * @phpstan-param ?array $request_data * * @url POST {id}/lines * @@ -287,7 +294,7 @@ class Interventions extends DolibarrApi $id, $this->fichinter->description, $this->fichinter->date, - $this->fichinter->duree + $this->fichinter->duration ); if ($updateRes > 0) { @@ -302,6 +309,8 @@ class Interventions extends DolibarrApi * * @param int $id Order ID * @return array + * @phan-return array + * @phpstan-return array */ public function delete($id) { @@ -411,8 +420,8 @@ class Interventions extends DolibarrApi /** * Validate fields before create or update object * - * @param array $data Data to validate - * @return array + * @param ?array $data Data to validate + * @return array * * @throws RestException */ @@ -450,8 +459,8 @@ class Interventions extends DolibarrApi /** * Validate fields before create or update object * - * @param array $data Data to validate - * @return array + * @param array $data Data to validate + * @return array Return array with validated mandatory fields and their value * * @throws RestException */ diff --git a/htdocs/fichinter/class/fichinterrec.class.php b/htdocs/fichinter/class/fichinterrec.class.php index a623c2d7237..bcd1916c744 100644 --- a/htdocs/fichinter/class/fichinterrec.class.php +++ b/htdocs/fichinter/class/fichinterrec.class.php @@ -9,7 +9,7 @@ * Copyright (C) 2016-2018 Charlie Benke * Copyright (C) 2024 William Mead * Copyright (C) 2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -91,7 +91,7 @@ class FichinterRec extends Fichinter public $date_last_gen; /** - * @var datetime|string + * @var int|string */ public $date_when; @@ -255,7 +255,7 @@ class FichinterRec extends Fichinter $fichintsrc->lines[$i]->product_type, $fichintsrc->lines[$i]->special_code, !empty($fichintsrc->lines[$i]->label) ? $fichintsrc->lines[$i]->label : "", - $fichintsrc->lines[$i]->fk_unit + (string) $fichintsrc->lines[$i]->fk_unit ); if ($result_insert < 0) { @@ -527,7 +527,7 @@ class FichinterRec extends Fichinter // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. - $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, 0, 0, 0, $price_base_type, $info_bits, $type, $mysoc); + $tabprice = calcul_price_total($qty, (float) $pu, (float) $remise_percent, $txtva, 0, 0, 0, $price_base_type, $info_bits, $type, $mysoc); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; @@ -609,7 +609,7 @@ class FichinterRec extends Fichinter // phpcs:enable if ($user->hasRight('fichinter', 'creer')) { $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter_rec "; - $sql .= " SET frequency='".$this->db->escape($freq)."'"; + $sql .= " SET frequency='".$this->db->escape((string) $freq)."'"; $sql .= ", date_last_gen='".$this->db->escape($courant)."'"; $sql .= " WHERE rowid = ".((int) $this->id); @@ -749,7 +749,7 @@ class FichinterRec extends Fichinter } $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' SET frequency = '.($frequency ? $this->db->escape($frequency) : 'null'); + $sql .= ' SET frequency = '.($frequency ? $this->db->escape((string) $frequency) : 'null'); if (!empty($unit)) { $sql .= ', unit_frequency = "'.$this->db->escape($unit).'"'; } @@ -771,8 +771,8 @@ class FichinterRec extends Fichinter /** * Update the next date of execution * - * @param datetime $date date of execution - * @param int $increment_nb_gen_done 0 do nothing more, >0 increment nb_gen_done + * @param int $date date of execution + * @param int<0,max> $increment_nb_gen_done 0 do nothing more, >0 increment nb_gen_done * @return int Return integer <0 if KO, >0 if OK */ public function setNextDate($date, $increment_nb_gen_done = 0) diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index a2270349bab..308af88fce9 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -9,7 +9,7 @@ * Copyright (C) 2021-2024 Frédéric France * Copyright (C) 2022 Charlène Benke * Copyright (C) 2024 William Mead - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Benjamin Falière * * This program is free software; you can redistribute it and/or modify @@ -139,29 +139,29 @@ if (getDolGlobalString('FICHINTER_DISABLE_DETAILS')) { // Definition of fields for list $arrayfields = array( - 'f.ref' => array('label' => 'Ref', 'checked' => 1), - 'f.ref_client' => array('label' => 'RefCustomer', 'checked' => 1), - 's.nom' => array('label' => 'ThirdParty', 'checked' => 1), - 'pr.ref' => array('label' => 'Project', 'checked' => 1, 'enabled' => (!isModEnabled('project') ? 0 : 1)), - 'c.ref' => array('label' => 'Contract', 'checked' => 1, 'enabled' => (empty($conf->contrat->enabled) ? 0 : 1)), - 'f.description' => array('label' => 'Description', 'checked' => 1), - 'f.datec' => array('label' => 'DateCreation', 'checked' => 0, 'position' => 500), - 'f.tms' => array('label' => 'DateModificationShort', 'checked' => 0, 'position' => 500), - 'f.note_public' => array('label' => 'NotePublic', 'checked' => 0, 'position' => 510, 'enabled' => (!getDolGlobalInt('MAIN_LIST_HIDE_PUBLIC_NOTES'))), - 'f.note_private' => array('label' => 'NotePrivate', 'checked' => 0, 'position' => 511, 'enabled' => (!getDolGlobalInt('MAIN_LIST_HIDE_PRIVATE_NOTES'))), - 'f.fk_statut' => array('label' => 'Status', 'checked' => 1, 'position' => 1000), - 'f.signed_status' => array('label' => 'SignedStatus', 'checked' => 0, 'position' => 1001), - 'fd.description' => array('label' => "DescriptionOfLine", 'checked' => 1, 'enabled' => getDolGlobalString('FICHINTER_DISABLE_DETAILS') != '1' ? 1 : 0), - 'fd.date' => array('label' => 'DateOfLine', 'checked' => 1, 'enabled' => getDolGlobalString('FICHINTER_DISABLE_DETAILS') != '1' ? 1 : 0), - 'fd.duree' => array('label' => 'DurationOfLine', 'type' => 'duration', 'checked' => 1, 'enabled' => !getDolGlobalString('FICHINTER_DISABLE_DETAILS') ? 1 : 0), //type duration is here because in database, column 'duree' is double + 'f.ref' => array('label' => 'Ref', 'checked' => '1'), + 'f.ref_client' => array('label' => 'RefCustomer', 'checked' => '1'), + 's.nom' => array('label' => 'ThirdParty', 'checked' => '1'), + 'pr.ref' => array('label' => 'Project', 'checked' => '1', 'enabled' => (!isModEnabled('project') ? '0' : '1')), + 'c.ref' => array('label' => 'Contract', 'checked' => '1', 'enabled' => (empty($conf->contrat->enabled) ? '0' : '1')), + 'f.description' => array('label' => 'Description', 'checked' => '1'), + 'f.datec' => array('label' => 'DateCreation', 'checked' => '0', 'position' => 500), + 'f.tms' => array('label' => 'DateModificationShort', 'checked' => '0', 'position' => 500), + 'f.note_public' => array('label' => 'NotePublic', 'checked' => '0', 'position' => 510, 'enabled' => (string) (!getDolGlobalInt('MAIN_LIST_HIDE_PUBLIC_NOTES'))), + 'f.note_private' => array('label' => 'NotePrivate', 'checked' => '0', 'position' => 511, 'enabled' => (string) (!getDolGlobalInt('MAIN_LIST_HIDE_PRIVATE_NOTES'))), + 'f.fk_statut' => array('label' => 'Status', 'checked' => '1', 'position' => 1000), + 'f.signed_status' => array('label' => 'SignedStatus', 'checked' => '0', 'position' => 1001), + 'fd.description' => array('label' => "DescriptionOfLine", 'checked' => '1', 'enabled' => getDolGlobalString('FICHINTER_DISABLE_DETAILS') != '1' ? '1' : '0'), + 'fd.date' => array('label' => 'DateOfLine', 'checked' => '1', 'enabled' => getDolGlobalString('FICHINTER_DISABLE_DETAILS') != '1' ? '1' : '0'), + 'fd.duree' => array('label' => 'DurationOfLine', 'type' => 'duration', 'checked' => '1', 'enabled' => !getDolGlobalString('FICHINTER_DISABLE_DETAILS') ? '1' : '0'), //type duration is here because in database, column 'duree' is double ); -'@phan-var-force array{label:string,type?:string,checked:int,position?:int,enabled?:int,langfile?:string,help:string} $arrayfields'; +'@phan-var-force array{label:string,type?:string,checked:string,position?:int,enabled?:string,langfile?:string,help:string} $arrayfields'; // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; $object->fields = dol_sort_array($object->fields, 'position'); $arrayfields = dol_sort_array($arrayfields, 'position'); -'@phan-var-force array,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan +'@phan-var-force array{label:string,type?:string,checked:string,position?:int,enabled?:string,langfile?:string,help:string} $arrayfields'; // dol_sort_array looses type for Phan // Security check $id = GETPOSTINT('id'); @@ -237,6 +237,8 @@ $form = new Form($db); $formfile = new FormFile($db); $objectstatic = new Fichinter($db); $companystatic = new Societe($db); +$projetstatic = null; +$contratstatic = null; if (isModEnabled('project')) { $projetstatic = new Project($db); } @@ -921,7 +923,7 @@ while ($i < $imaxinloop) { } } // Project ref - if (!empty($arrayfields['pr.ref']['checked'])) { + if (!empty($arrayfields['pr.ref']['checked']) && $projetstatic !== null) { print ''; $projetstatic->id = $obj->projet_id; $projetstatic->ref = $obj->projet_ref; @@ -935,14 +937,14 @@ while ($i < $imaxinloop) { } } // Contract - if (!empty($arrayfields['c.ref']['checked'])) { + if (!empty($arrayfields['c.ref']['checked']) && $contratstatic !== null) { print ''; $contratstatic->id = $obj->contrat_id; $contratstatic->ref = $obj->contrat_ref; $contratstatic->ref_customer = $obj->contrat_ref_customer; $contratstatic->ref_supplier = $obj->contrat_ref_supplier; if ($contratstatic->id > 0) { - print $contratstatic->getNomUrl(1, ''); + print $contratstatic->getNomUrl(1, 0); print ''; } if (!$i) { diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index aa03bc81bd9..abba0355be6 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -205,10 +205,19 @@ if (!$result && !empty($_SERVER["GATEWAY_INTERFACE"])) { // If install not do } // Force PHP error_reporting setup (Dolibarr may report warning without this) -if (!empty($dolibarr_strict_mode)) { - error_reporting(E_ALL | E_STRICT); +if (version_compare(phpversion(), '8.4', '<')) { + if (!empty($dolibarr_strict_mode)) { + error_reporting(E_ALL | E_STRICT); + } else { + error_reporting(E_ALL & ~(E_STRICT | E_NOTICE | E_DEPRECATED)); + } } else { - error_reporting(E_ALL & ~(E_STRICT | E_NOTICE | E_DEPRECATED)); + // E_STRICT is deprecated since PHP 8.4 + if (!empty($dolibarr_strict_mode)) { + error_reporting(E_ALL); + } else { + error_reporting(E_ALL & ~(E_NOTICE | E_DEPRECATED)); + } } // Disable php display errors diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index 026901afa32..b42f5a557ef 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -8,7 +8,7 @@ * Copyright (C) 2015 Marcos García * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2021-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify @@ -363,9 +363,9 @@ if ($object->id > 0) { print ''; print ''; if ($action == 'editconditions') { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->cond_reglement_supplier_id, 'cond_reglement_supplier_id', 1); + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, (string) $object->cond_reglement_supplier_id, 'cond_reglement_supplier_id', 1); } else { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->cond_reglement_supplier_id, 'none'); + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, (string) $object->cond_reglement_supplier_id, 'none'); } print ""; print ''; @@ -381,9 +381,9 @@ if ($object->id > 0) { print ''; print ''; if ($action == 'editmode') { - $form->form_modes_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->mode_reglement_supplier_id, 'mode_reglement_supplier_id', 'DBIT', 1, 1); + $form->form_modes_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, (string) $object->mode_reglement_supplier_id, 'mode_reglement_supplier_id', 'DBIT', 1, 1); } else { - $form->form_modes_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->mode_reglement_supplier_id, 'none'); + $form->form_modes_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, (string) $object->mode_reglement_supplier_id, 'none'); } print ""; print ''; @@ -400,9 +400,9 @@ if ($object->id > 0) { print ''; print ''; if ($action == 'editbankaccount') { - $form->formSelectAccount($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->fk_account, 'fk_account', 1); + $form->formSelectAccount($_SERVER['PHP_SELF'].'?socid='.$object->id, (string) $object->fk_account, 'fk_account', 1); } else { - $form->formSelectAccount($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->fk_account, 'none'); + $form->formSelectAccount($_SERVER['PHP_SELF'].'?socid='.$object->id, (string) $object->fk_account, 'none'); } print ""; print ''; @@ -432,7 +432,7 @@ if ($object->id > 0) { print ''; print ''; print ''; - $amount_discount = $object->getAvailableDiscounts('', '', 0, 1); + $amount_discount = $object->getAvailableDiscounts(null, '', 0, 1); if ($amount_discount < 0) { dol_print_error($db, $object->error); } @@ -474,7 +474,7 @@ if ($object->id > 0) { print ''.$langs->trans("LinkedToDolibarrMember").''; print ''; $adh = new Adherent($db); - $result = $adh->fetch('', '', $object->id); + $result = $adh->fetch(0, '', $object->id); if ($result > 0) { $adh->ref = $adh->getFullName($langs); print $adh->getNomUrl(1); @@ -493,7 +493,7 @@ if ($object->id > 0) { $boxstat = ''; // Nbre max d'elements des petites listes - $MAXLIST = getDolGlobalString('MAIN_SIZE_SHORTLIST_LIMIT'); + $MAXLIST = getDolGlobalInt('MAIN_SIZE_SHORTLIST_LIMIT'); print '
'; print '
'; @@ -614,7 +614,7 @@ if ($object->id > 0) { print $boxstat; - $MAXLIST = getDolGlobalString('MAIN_SIZE_SHORTLIST_LIMIT'); + $MAXLIST = getDolGlobalInt('MAIN_SIZE_SHORTLIST_LIMIT'); /* @@ -762,6 +762,7 @@ if ($object->id > 0) { * Latest supplier orders */ $orderstatic = new CommandeFournisseur($db); + $orders2invoice = 0; if ($user->hasRight("fournisseur", "commande", "lire")) { // TODO move to DAO class @@ -775,7 +776,7 @@ if ($object->id > 0) { $sql2 .= ' AND s.rowid = '.((int) $object->id); // Show orders we can bill if (!getDolGlobalString('SUPPLIER_ORDER_TO_INVOICE_STATUS')) { - $sql2 .= " AND c.fk_statut IN (".$db->sanitize(CommandeFournisseur::STATUS_RECEIVED_COMPLETELY).")"; // Must match filter in htdocs/fourn/commande/list.php + $sql2 .= " AND c.fk_statut IN (".$db->sanitize((string) CommandeFournisseur::STATUS_RECEIVED_COMPLETELY).")"; // Must match filter in htdocs/fourn/commande/list.php } else { // CommandeFournisseur::STATUS_ORDERSENT.", ".CommandeFournisseur::STATUS_RECEIVED_PARTIALLY.", ".CommandeFournisseur::STATUS_RECEIVED_COMPLETELY $sql2 .= " AND c.fk_statut IN (".$db->sanitize(getDolGlobalString('SUPPLIER_ORDER_TO_INVOICE_STATUS')).")"; diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 9ad00e00bc2..e8576c94002 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2460,35 +2460,52 @@ class CommandeFournisseur extends CommonOrder } $main = $this->db->prefix().'commande_fournisseurdet'; - $ef = $main."_extrafields"; - $sql = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_commande = ".((int) $this->id).")"; - dol_syslog(get_class($this)."::delete extrafields lines", LOG_DEBUG); - if (!$this->db->query($sql)) { - $this->error = $this->db->lasterror(); - $this->errors[] = $this->db->lasterror(); - $error++; + + if (!$error) { + $sql1 = "UPDATE ".$this->db->prefix()."commandedet SET fk_commandefourndet = NULL WHERE fk_commandefourndet IN (SELECT rowid FROM ".$main." WHERE fk_commande = ".((int) $this->id).")"; + dol_syslog(__METHOD__." linked order lines", LOG_DEBUG); + if (!$this->db->query($sql1)) { + $error++; + $this->error = $this->db->lasterror(); + $this->errors[] = $this->db->lasterror(); + } } - $sql = "DELETE FROM ".$this->db->prefix()."commande_fournisseurdet WHERE fk_commande =".((int) $this->id); - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - if (!$this->db->query($sql)) { - $this->error = $this->db->lasterror(); - $this->errors[] = $this->db->lasterror(); - $error++; - } - - $sql = "DELETE FROM ".$this->db->prefix()."commande_fournisseur WHERE rowid =".((int) $this->id); - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - if ($resql = $this->db->query($sql)) { - if ($this->db->affected_rows($resql) < 1) { + if (!$error) { + $ef = $main."_extrafields"; + $sql = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_commande = ".((int) $this->id).")"; + dol_syslog(get_class($this)."::delete extrafields lines", LOG_DEBUG); + if (!$this->db->query($sql)) { + $this->error = $this->db->lasterror(); + $this->errors[] = $this->db->lasterror(); + $error++; + } + } + + if (!$error) { + $sql = "DELETE FROM ".$this->db->prefix()."commande_fournisseurdet WHERE fk_commande =".((int) $this->id); + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + if (!$this->db->query($sql)) { + $this->error = $this->db->lasterror(); + $this->errors[] = $this->db->lasterror(); + $error++; + } + } + + if (!$error) { + $sql = "DELETE FROM ".$this->db->prefix()."commande_fournisseur WHERE rowid =".((int) $this->id); + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + if ($resql = $this->db->query($sql)) { + if ($this->db->affected_rows($resql) < 1) { + $this->error = $this->db->lasterror(); + $this->errors[] = $this->db->lasterror(); + $error++; + } + } else { $this->error = $this->db->lasterror(); $this->errors[] = $this->db->lasterror(); $error++; } - } else { - $this->error = $this->db->lasterror(); - $this->errors[] = $this->db->lasterror(); - $error++; } // Remove extrafields diff --git a/htdocs/hrm/class/position.class.php b/htdocs/hrm/class/position.class.php index 50705c1ece5..2059a1d4ff5 100644 --- a/htdocs/hrm/class/position.class.php +++ b/htdocs/hrm/class/position.class.php @@ -207,7 +207,7 @@ class Position extends CommonObject */ public function __construct(DoliDB $db) { - global $conf, $langs; + global $langs; $this->db = $db; @@ -873,7 +873,7 @@ class Position extends CommonObject * Return HTML string to put an input field into a page * Code very similar with showInputField of extra fields * - * @param ?array{type:string,label:string,enabled:int|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array,comment?:string} $val Array of properties for field to show + * @param ?array{type:string,label:string,enabled:int|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array,comment?:string} $val Array of properties for field to show. If ->fields is defined, keep this null. * @param string $key Key of attribute * @param string $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value) * @param string $moreparam To add more parameters on html input tag @@ -890,7 +890,7 @@ class Position extends CommonObject if ($key == 'fk_user') { $vacantId = $keyprefix.$key.'vacant'.$keysuffix; - $out = parent::showInputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss); + $out = parent::showInputField(null, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss); $out .= ''; ?>