diff --git a/.github/changed-lines-count-labeler.yml b/.github/changed-lines-count-labeler.yml new file mode 100644 index 00000000000..39e663821fb --- /dev/null +++ b/.github/changed-lines-count-labeler.yml @@ -0,0 +1,3 @@ +# Add this tag for any changes for more than 1 line +"Pending analysis of PR (maintenance team)": + min: 1 diff --git a/.github/workflows/pr-18-autolabel.yaml b/.github/workflows/pr-18-autolabel.yaml new file mode 100644 index 00000000000..feb9ee17c97 --- /dev/null +++ b/.github/workflows/pr-18-autolabel.yaml @@ -0,0 +1,21 @@ +name: "Set label for v18" +on: + pull_request: + types: [opened, synchronize, reopened] + branches: + - "18.0" + push: + branches: + - "18.0" + +jobs: + changed-lines-count-labeler: + runs-on: ubuntu-latest + name: An action for automatically labelling pull requests based on the changed lines count + steps: + - name: Set a label + uses: vkirilichev/changed-lines-count-labeler@v0.2 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + configuration-path: .github/changed-lines-count-labeler.yml + continue-on-error: true diff --git a/.github/workflows/pr-18.yaml b/.github/workflows/pr-18.yaml index b8b18169b58..67075183b60 100644 --- a/.github/workflows/pr-18.yaml +++ b/.github/workflows/pr-18.yaml @@ -1,3 +1,4 @@ +name: Set reviewer for v18 on: pull_request: types: [opened, synchronize, reopened] @@ -7,15 +8,13 @@ on: branches: - "18.0" -permissions: write-all - jobs: - run: + pr18: runs-on: ubuntu-latest - env: - # GH_TOKEN: ${{ secrets.GH_TOKEN }} - GH_TOKEN: ${{ github.token }} + #env: + # GH_TOKEN: ${{ github.token }} + # GH_TOKENS: ${{ secrets.GITHUB_TOKEN }} steps: - name: Checkout repository @@ -26,20 +25,31 @@ jobs: sudo apt update sudo apt install gh -y - #- name: Authenticate GitHub CLI - # run: | - # echo "GH_TOKEN=$GH_TOKEN" - # gh auth login --with-token <<< "$GH_TOKEN" - - name: Assign reviewer env: #REVIEWER: "eldy,lvessiller-opendsi,rycks" # Remplacez par le nom d'utilisateur GitHub du reviewer REVIEWER: "rycks" # Remplacez par le nom d'utilisateur GitHub du reviewer run: | # shellcheck disable=2086 - echo "GH_TOKEN=$GH_TOKEN" + echo "Run action by ${{ github.actor }}" + # shellcheck disable=2086 + echo "github.token=${{ github.token }}" + # shellcheck disable=2086 + echo "secrets.GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" + # shellcheck disable=2086 + echo "GITHUB_EVENT_PATH=$GITHUB_EVENT_PATH" + # shellcheck disable=2086 + echo Get the pr_number # shellcheck disable=2086 pr_number=$(jq --raw-output .number < $GITHUB_EVENT_PATH) # shellcheck disable=2086 + echo "pr_number=$pr_number" + # shellcheck disable=2086 + echo Authenticate login gh + # shellcheck disable=2086 + gh auth login --with-token <<< "${{ secrets.GITHUB_TOKEN }}" + # shellcheck disable=2086 + gh auth setup-git + # shellcheck disable=2086 gh pr edit $pr_number --add-reviewer "$REVIEWER" continue-on-error: true diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index cf263dd0b57..dc0bfbdf63c 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,3 +1,4 @@ +name: Test github actions on: workflow_dispatch: pull_request: @@ -5,7 +6,13 @@ on: branches: - "18.0" -permissions: write-all +env: + ENVGHT: ${{ secrets.GITHUB_TOKEN }} + ENVGHU: ${{ github.token }} + VARAAA: ${{ vars.AAA }} + SECBBB: ${{ secrets.BBB }} + VARREPORGCCC: ${{ vars.CCC }} + ENVFIX: "abc" jobs: testjob: @@ -13,7 +20,19 @@ jobs: steps: - name: Log run: | + echo "Run action by ${{ github.actor }}" + echo "github.token=${{ github.token }}" + echo "secrets.GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" + echo "GITHUB_EVENT_PATH=$GITHUB_EVENT_PATH" + echo "repo-token: ${{secrets.GITHUB_TOKEN}}" echo "variable org: ${{vars.AAA}}" echo "env prg: ${{env.AAA}}" + echo "env prg: ${{env.VARAAA}}" echo "secret org: ${{secrets.BBB}}" echo "variable repository of orga: ${{vars.CCC}}" + echo "ENVGHT: ${{env.ENVGHT}}" + echo "ENVGHU: ${{env.ENVGHU}}" + echo "VARAAA: ${{vars.AAA}}" + echo "ENVAAA: ${{env.VARAAA}}" + echo "VARREPORGCCC: ${{env.VARREPORGCCC}}" + echo "ENVFIX: ${{env.ENVFIX}}" diff --git a/.gitignore b/.gitignore index 830429de679..0a6e4cf6655 100644 --- a/.gitignore +++ b/.gitignore @@ -90,3 +90,6 @@ phpstan_custom.neon /.php-cs-fixer.cache /.php_cs.cache /.cache + +# ignore .htaccess files +.htaccess diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e6953f04578..5f75f64fc16 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: # git commit -a -m "My message" --no-verify # (Recommendation: run git commit -a .. once, then with `--no-verify`) - id: no-commit-to-branch - args: [--branch, develop, --pattern, \d+.0] + args: [--branch, develop, --pattern, \d+.0$] # This checks that xml files are correct - id: check-xml exclude: | diff --git a/build/phpstan/bootstrap_action.php b/build/phpstan/bootstrap_action.php index 2bcc70dd965..f1a6a638f91 100644 --- a/build/phpstan/bootstrap_action.php +++ b/build/phpstan/bootstrap_action.php @@ -27,6 +27,7 @@ if (!defined("NOHTTPSREDIRECT")) { } // Defined some constants and load Dolibarr env to reduce PHPStan bootstrap that fails to load a lot of things. +$dolibarr_main_document_root = __DIR__ . '/../../htdocs'; define('DOL_DOCUMENT_ROOT', __DIR__ . '/../../htdocs'); define('DOL_DATA_ROOT', __DIR__ . '/../../documents'); define('DOL_URL_ROOT', '/'); @@ -42,6 +43,7 @@ define('MAIN_DB_PREFIX', 'llx_'); * @var User $user */ - global $conf, $db, $hookmanager, $langs, $mysoc, $user; +global $conf, $db, $hookmanager, $langs, $mysoc, $user; +global $dolibarr_main_document_root; // include_once DOL_DOCUMENT_ROOT . '/../../htdocs/main.inc.php'; diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index 0cc40cf71d2..a00105a79b3 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -463,7 +463,7 @@ parameters: path: ../../htdocs/accountancy/class/accountingaccount.class.php - - message: '#^Call to function array_key_exists\(\) with ''error'' and array\{ref\: mixed, label\: mixed, acquisition_value_ht\: mixed, depreciation\: non\-empty\-array\\}\>, disposal\?\: array\{date\: mixed, amount\: mixed, subject_to_vat\: bool\}\} will always evaluate to false\.$#' + message: '#^Call to function array_key_exists\(\) with ''error'' and array\{ref\: mixed, label\: mixed, acquisition_value_ht\: mixed, depreciation\: non\-empty\-array\\}\>, disposal\?\: array\{date\: mixed, amount\: mixed, subject_to_vat\: bool\}\} will always evaluate to false\.$#' identifier: function.impossibleType count: 1 path: ../../htdocs/accountancy/class/accountingjournal.class.php @@ -625,7 +625,7 @@ parameters: path: ../../htdocs/accountancy/class/lettering.class.php - - message: '#^Parameter \#1 \$link_by_element of method Lettering\:\:getGroupElements\(\) expects array\\>, array\\> given\.$#' + message: '#^Parameter \#1 \$link_by_element of method Lettering\:\:getGroupElements\(\) expects array\\>, array\\> given\.$#' identifier: argument.type count: 1 path: ../../htdocs/accountancy/class/lettering.class.php @@ -882,60 +882,6 @@ parameters: count: 1 path: ../../htdocs/adherents/admin/member.php - - - message: '#^Cannot access property \$control on mixed\.$#' - identifier: property.nonObject - count: 23 - path: ../../htdocs/adherents/canvas/default/tpl/adherentcard_create.tpl.php - - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/adherents/canvas/default/tpl/adherentcard_create.tpl.php - - - - message: '#^Variable \$this might not be defined\.$#' - identifier: variable.undefined - count: 23 - path: ../../htdocs/adherents/canvas/default/tpl/adherentcard_create.tpl.php - - - - message: '#^Cannot access property \$control on mixed\.$#' - identifier: property.nonObject - count: 27 - path: ../../htdocs/adherents/canvas/default/tpl/adherentcard_edit.tpl.php - - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/adherents/canvas/default/tpl/adherentcard_edit.tpl.php - - - - message: '#^Variable \$this might not be defined\.$#' - identifier: variable.undefined - count: 26 - path: ../../htdocs/adherents/canvas/default/tpl/adherentcard_edit.tpl.php - - - - message: '#^Cannot access property \$control on mixed\.$#' - identifier: property.nonObject - count: 30 - path: ../../htdocs/adherents/canvas/default/tpl/adherentcard_view.tpl.php - - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../htdocs/adherents/canvas/default/tpl/adherentcard_view.tpl.php - - - - message: '#^Variable \$this might not be defined\.$#' - identifier: variable.undefined - count: 28 - path: ../../htdocs/adherents/canvas/default/tpl/adherentcard_view.tpl.php - - message: '#^Negated boolean expression is always true\.$#' identifier: booleanNot.alwaysTrue @@ -948,10 +894,16 @@ parameters: count: 1 path: ../../htdocs/adherents/card.php + - + message: '#^Call to function is_array\(\) with array will always evaluate to true\.$#' + identifier: function.alreadyNarrowedType + count: 1 + path: ../../htdocs/adherents/class/adherent.class.php + - message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType - count: 2 + count: 1 path: ../../htdocs/adherents/class/adherent.class.php - @@ -1230,18 +1182,6 @@ parameters: count: 2 path: ../../htdocs/admin/agenda.php - - - message: '#^Variable \$label might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/admin/agenda_other.php - - - - message: '#^Variable \$label might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/admin/agenda_reminder.php - - message: '#^Variable \$errorsaved in empty\(\) always exists and is always falsy\.$#' identifier: empty.variable @@ -1638,24 +1578,6 @@ parameters: count: 1 path: ../../htdocs/admin/oauthlogintokens.php - - - message: '#^Negated boolean expression is always false\.$#' - identifier: booleanNot.alwaysFalse - count: 5 - path: ../../htdocs/admin/openid_connect.php - - - - message: '#^Negated boolean expression is always true\.$#' - identifier: booleanNot.alwaysTrue - count: 5 - path: ../../htdocs/admin/openid_connect.php - - - - message: '#^Variable \$bc might not be defined\.$#' - identifier: variable.undefined - count: 10 - path: ../../htdocs/admin/openid_connect.php - - message: '#^Negated boolean expression is always true\.$#' identifier: booleanNot.alwaysTrue @@ -1686,30 +1608,6 @@ parameters: count: 1 path: ../../htdocs/admin/security_file.php - - - message: '#^Parameter \#4 \$deliveryreceipt of class CSMSFile constructor expects int, array\\|string given\.$#' - identifier: argument.type - count: 1 - path: ../../htdocs/admin/sms.php - - - - message: '#^Parameter \#5 \$deferred of class CSMSFile constructor expects int, array\\|string given\.$#' - identifier: argument.type - count: 1 - path: ../../htdocs/admin/sms.php - - - - message: '#^Parameter \#6 \$priority of class CSMSFile constructor expects int, array\\|string given\.$#' - identifier: argument.type - count: 1 - path: ../../htdocs/admin/sms.php - - - - message: '#^Parameter \#7 \$class of class CSMSFile constructor expects int, array\\|string given\.$#' - identifier: argument.type - count: 1 - path: ../../htdocs/admin/sms.php - - message: '#^Variable \$smsfile might not be defined\.$#' identifier: variable.undefined @@ -1830,18 +1728,6 @@ parameters: count: 1 path: ../../htdocs/admin/system/security.php - - - message: '#^Variable \$arrayofstreamtodisable might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/admin/system/security.php - - - - message: '#^Variable \$conffile might not be defined\.$#' - identifier: variable.undefined - count: 4 - path: ../../htdocs/admin/system/security.php - - message: '#^Variable \$dolibarr_main_document_root might not be defined\.$#' identifier: variable.undefined @@ -2658,42 +2544,12 @@ parameters: count: 1 path: ../../htdocs/asset/tpl/depreciation_options_view.tpl.php - - - message: '#^Variable \$langs might not be defined\.$#' - identifier: variable.undefined - count: 7 - path: ../../htdocs/asset/tpl/depreciation_options_view.tpl.php - - message: '#^Variable \$parameters might not be defined\.$#' identifier: variable.undefined count: 1 path: ../../htdocs/asset/tpl/depreciation_options_view.tpl.php - - - message: '#^Unable to resolve the template type T in call to function dol_sort_array$#' - identifier: argument.templateType - count: 1 - path: ../../htdocs/asset/tpl/depreciation_view.tpl.php - - - - message: '#^Variable \$assetdepreciationoptions might not be defined\.$#' - identifier: variable.undefined - count: 7 - path: ../../htdocs/asset/tpl/depreciation_view.tpl.php - - - - message: '#^Variable \$db might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/asset/tpl/depreciation_view.tpl.php - - - - message: '#^Variable \$langs might not be defined\.$#' - identifier: variable.undefined - count: 7 - path: ../../htdocs/asset/tpl/depreciation_view.tpl.php - - message: '#^Variable \$parameters might not be defined\.$#' identifier: variable.undefined @@ -2748,12 +2604,6 @@ parameters: count: 1 path: ../../htdocs/blockedlog/class/blockedlog.class.php - - - message: '#^Variable \$aaa might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/blockedlog/class/blockedlog.class.php - - message: '#^Property BOM\:\:\$status \(int\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -2952,72 +2802,12 @@ parameters: count: 1 path: ../../htdocs/bom/tpl/objectline_edit.tpl.php - - - message: '#^Cannot access property \$db on mixed\.$#' - identifier: property.nonObject - count: 1 - path: ../../htdocs/bom/tpl/objectline_edit.tpl.php - - - - message: '#^Variable \$action might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/bom/tpl/objectline_edit.tpl.php - - - - message: '#^Variable \$buyer might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/bom/tpl/objectline_edit.tpl.php - - message: '#^Variable \$dateSelector might not be defined\.$#' identifier: variable.undefined count: 1 path: ../../htdocs/bom/tpl/objectline_edit.tpl.php - - - message: '#^Variable \$hookmanager might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/bom/tpl/objectline_edit.tpl.php - - - - message: '#^Variable \$i might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/bom/tpl/objectline_edit.tpl.php - - - - message: '#^Variable \$langs might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/bom/tpl/objectline_edit.tpl.php - - - - message: '#^Variable \$line might not be defined\.$#' - identifier: variable.undefined - count: 20 - path: ../../htdocs/bom/tpl/objectline_edit.tpl.php - - - - message: '#^Variable \$seller might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/bom/tpl/objectline_edit.tpl.php - - - - message: '#^Variable \$this might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/bom/tpl/objectline_edit.tpl.php - - - - message: '#^Variable \$var might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/bom/tpl/objectline_edit.tpl.php - - message: '#^If condition is always true\.$#' identifier: if.alwaysTrue @@ -3030,12 +2820,6 @@ parameters: count: 1 path: ../../htdocs/bom/tpl/objectline_view.tpl.php - - - message: '#^Variable \$action might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/bom/tpl/objectline_view.tpl.php - - message: '#^If condition is always false\.$#' identifier: if.alwaysFalse @@ -3565,7 +3349,7 @@ parameters: path: ../../htdocs/categories/class/categorie.class.php - - message: '#^Method Categorie\:\:get_full_arbo\(\) should return \-1\|array\ but returns array\\.$#' + message: '#^Method Categorie\:\:get_full_arbo\(\) should return \-1\|array\ but returns array\\.$#' identifier: return.type count: 1 path: ../../htdocs/categories/class/categorie.class.php @@ -3583,7 +3367,7 @@ parameters: path: ../../htdocs/categories/class/categorie.class.php - - message: '#^Property Categorie\:\:\$cats \(array\\) does not accept array\\.$#' + message: '#^Property Categorie\:\:\$cats \(array\\) does not accept array\\.$#' identifier: assign.propertyType count: 2 path: ../../htdocs/categories/class/categorie.class.php @@ -4638,12 +4422,6 @@ parameters: count: 1 path: ../../htdocs/comm/propal/tpl/linkedobjectblock.tpl.php - - - message: '#^Variable \$id might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/comm/recap-client.php - - message: '#^If condition is always false\.$#' identifier: if.alwaysFalse @@ -5286,12 +5064,6 @@ parameters: count: 1 path: ../../htdocs/compta/bank/class/paymentvarious.class.php - - - message: '#^Call to function property_exists\(\) with \$this\(PaymentVarious\) and ''fk_bank'' will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../htdocs/compta/bank/class/paymentvarious.class.php - - message: '#^Property PaymentVarious\:\:\$accountid \(int\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -5496,42 +5268,12 @@ parameters: count: 1 path: ../../htdocs/compta/bank/various_payment/list.php - - - message: '#^Variable \$accountingaccount might not be defined\.$#' - identifier: variable.undefined - count: 5 - path: ../../htdocs/compta/bank/various_payment/list.php - - - - message: '#^Variable \$accountingjournal might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/compta/bank/various_payment/list.php - - - - message: '#^Variable \$accountstatic might not be defined\.$#' - identifier: variable.undefined - count: 7 - path: ../../htdocs/compta/bank/various_payment/list.php - - - - message: '#^Variable \$bankline might not be defined\.$#' - identifier: variable.undefined - count: 4 - path: ../../htdocs/compta/bank/various_payment/list.php - - message: '#^Variable \$contextpage in empty\(\) always exists and is not falsy\.$#' identifier: empty.variable count: 1 path: ../../htdocs/compta/bank/various_payment/list.php - - - message: '#^Variable \$variousstatic might not be defined\.$#' - identifier: variable.undefined - count: 12 - path: ../../htdocs/compta/bank/various_payment/list.php - - message: '#^Loose comparison using \=\= between ''card'' and ''card'' will always evaluate to true\.$#' identifier: equal.alwaysTrue @@ -5575,7 +5317,7 @@ parameters: path: ../../htdocs/compta/cashcontrol/class/cashcontrol.class.php - - message: '#^Call to function is_array\(\) with non\-empty\-array\ will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with non\-empty\-array\<\(float\|int\)\> will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/compta/cashcontrol/report.php @@ -6075,7 +5817,7 @@ parameters: - message: '#^Property Facture\:\:\$ref_client \(string\) in isset\(\) is not nullable\.$#' identifier: isset.property - count: 2 + count: 1 path: ../../htdocs/compta/facture/class/facture.class.php - @@ -6865,7 +6607,7 @@ parameters: path: ../../htdocs/compta/resultat/index.php - - message: '#^Call to function is_array\(\) with non\-empty\-array\\}\> will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with non\-empty\-array\\}\> will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/compta/resultat/result.php @@ -7554,60 +7296,6 @@ parameters: count: 1 path: ../../htdocs/contact/ajax/contact.php - - - message: '#^Cannot access property \$control on mixed\.$#' - identifier: property.nonObject - count: 24 - path: ../../htdocs/contact/canvas/default/tpl/contactcard_create.tpl.php - - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/contact/canvas/default/tpl/contactcard_create.tpl.php - - - - message: '#^Variable \$this might not be defined\.$#' - identifier: variable.undefined - count: 24 - path: ../../htdocs/contact/canvas/default/tpl/contactcard_create.tpl.php - - - - message: '#^Cannot access property \$control on mixed\.$#' - identifier: property.nonObject - count: 31 - path: ../../htdocs/contact/canvas/default/tpl/contactcard_edit.tpl.php - - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/contact/canvas/default/tpl/contactcard_edit.tpl.php - - - - message: '#^Variable \$this might not be defined\.$#' - identifier: variable.undefined - count: 29 - path: ../../htdocs/contact/canvas/default/tpl/contactcard_edit.tpl.php - - - - message: '#^Cannot access property \$control on mixed\.$#' - identifier: property.nonObject - count: 34 - path: ../../htdocs/contact/canvas/default/tpl/contactcard_view.tpl.php - - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../htdocs/contact/canvas/default/tpl/contactcard_view.tpl.php - - - - message: '#^Variable \$this might not be defined\.$#' - identifier: variable.undefined - count: 32 - path: ../../htdocs/contact/canvas/default/tpl/contactcard_view.tpl.php - - message: '#^If condition is always true\.$#' identifier: if.alwaysTrue @@ -8287,7 +7975,7 @@ parameters: path: ../../htdocs/core/actions_linkedfiles.inc.php - - message: '#^Call to function is_array\(\) with non\-empty\-array\ will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with non\-empty\-array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/core/actions_massactions.inc.php @@ -8334,12 +8022,6 @@ parameters: count: 1 path: ../../htdocs/core/actions_massactions.inc.php - - - message: '#^Variable \$action might not be defined\.$#' - identifier: variable.undefined - count: 14 - path: ../../htdocs/core/actions_massactions.inc.php - - message: '#^Variable \$from might not be defined\.$#' identifier: variable.undefined @@ -8358,12 +8040,6 @@ parameters: count: 1 path: ../../htdocs/core/actions_massactions.inc.php - - - message: '#^Variable \$month might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/core/actions_massactions.inc.php - - message: '#^Variable \$newlang in empty\(\) always exists and is always falsy\.$#' identifier: empty.variable @@ -8394,12 +8070,6 @@ parameters: count: 1 path: ../../htdocs/core/actions_massactions.inc.php - - - message: '#^Variable \$year might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/core/actions_massactions.inc.php - - message: '#^Variable \$classfile might not be defined\.$#' identifier: variable.undefined @@ -10873,7 +10543,7 @@ parameters: path: ../../htdocs/core/class/notify.class.php - - message: '#^Call to function is_array\(\) with non\-empty\-array\ will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with non\-empty\-array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/core/class/openid.class.php @@ -12588,12 +12258,6 @@ parameters: count: 1 path: ../../htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php - - - message: '#^Variable \$outputlangsbis might not be defined\.$#' - identifier: variable.undefined - count: 7 - path: ../../htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php - - message: '#^Property mod_asset_standard\:\:\$prefix has no type specified\.$#' identifier: missingType.property @@ -13939,7 +13603,7 @@ parameters: path: ../../htdocs/core/modules/hrm/mod_evaluation_standard.php - - message: '#^Call to function is_array\(\) with non\-empty\-array will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with non\-empty\-list\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/core/modules/import/import_csv.modules.php @@ -14154,12 +13818,6 @@ parameters: count: 2 path: ../../htdocs/core/modules/member/doc/pdf_standard_member.class.php - - - message: '#^Parameter \#1 \$substitutionarray of function complete_substitutions_array expects array\, array\ given\.$#' - identifier: argument.type - count: 1 - path: ../../htdocs/core/modules/member/doc/pdf_standard_member.class.php - - message: '#^Parameter \#6 \$epaisseur of method CommonStickerGenerator\:\:_Croix\(\) expects int, float given\.$#' identifier: argument.type @@ -17532,18 +17190,6 @@ parameters: count: 4 path: ../../htdocs/cron/class/cronjob.class.php - - - message: '#^Variable \$ExecTimeLimit in empty\(\) always exists and is not falsy\.$#' - identifier: empty.variable - count: 1 - path: ../../htdocs/cron/class/cronjob.class.php - - - - message: '#^Variable \$MemoryLimit in empty\(\) always exists and is always falsy\.$#' - identifier: empty.variable - count: 1 - path: ../../htdocs/cron/class/cronjob.class.php - - message: '#^Ternary operator condition is always true\.$#' identifier: ternary.alwaysTrue @@ -23659,7 +23305,7 @@ parameters: path: ../../htdocs/master.inc.php - - message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/modulebuilder/index.php @@ -25548,36 +25194,6 @@ parameters: count: 1 path: ../../htdocs/product/class/product.class.php - - - message: '#^Property Product\:\:\$stats_bom has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../htdocs/product/class/product.class.php - - - - message: '#^Property Product\:\:\$stats_facture_fournisseur has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../htdocs/product/class/product.class.php - - - - message: '#^Property Product\:\:\$stats_facturerec has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../htdocs/product/class/product.class.php - - - - message: '#^Property Product\:\:\$stats_mrptoconsume has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../htdocs/product/class/product.class.php - - - - message: '#^Property Product\:\:\$stats_mrptoproduce has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../htdocs/product/class/product.class.php - - message: '#^Property Product\:\:\$status \(int\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -25608,12 +25224,6 @@ parameters: count: 2 path: ../../htdocs/product/class/product.class.php - - - message: '#^Ternary operator condition is always true\.$#' - identifier: ternary.alwaysTrue - count: 1 - path: ../../htdocs/product/class/product.class.php - - message: '#^Negated boolean expression is always true\.$#' identifier: booleanNot.alwaysTrue @@ -27954,12 +27564,6 @@ parameters: count: 2 path: ../../htdocs/projet/tasks.php - - - message: '#^Variable \$param might not be defined\.$#' - identifier: variable.undefined - count: 17 - path: ../../htdocs/projet/tasks.php - - message: '#^Variable \$permissiontodelete might not be defined\.$#' identifier: variable.undefined @@ -28332,12 +27936,6 @@ parameters: count: 1 path: ../../htdocs/public/bookcal/index.php - - - message: '#^Variable \$db might not be defined\.$#' - identifier: variable.undefined - count: 9 - path: ../../htdocs/public/clicktodial/cidlookup.php - - message: '#^Variable \$langs might not be defined\.$#' identifier: variable.undefined @@ -28350,12 +27948,6 @@ parameters: count: 1 path: ../../htdocs/public/cron/cron_run_jobs_by_url.php - - - message: '#^Variable \$db might not be defined\.$#' - identifier: variable.undefined - count: 5 - path: ../../htdocs/public/cron/cron_run_jobs_by_url.php - - message: '#^Comparison operation "\>\=" between ''0''\|''1'' and 0 is always true\.$#' identifier: greaterOrEqual.alwaysTrue @@ -28380,30 +27972,6 @@ parameters: count: 1 path: ../../htdocs/public/demo/index.php - - - message: '#^Variable \$conf might not be defined\.$#' - identifier: variable.undefined - count: 21 - path: ../../htdocs/public/demo/index.php - - - - message: '#^Variable \$db might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/public/demo/index.php - - - - message: '#^Variable \$hookmanager might not be defined\.$#' - identifier: variable.undefined - count: 4 - path: ../../htdocs/public/demo/index.php - - - - message: '#^Variable \$langs might not be defined\.$#' - identifier: variable.undefined - count: 8 - path: ../../htdocs/public/demo/index.php - - message: '#^Variable \$conf might not be defined\.$#' identifier: variable.undefined @@ -28428,18 +27996,6 @@ parameters: count: 7 path: ../../htdocs/public/donations/donateurs_code.php - - - message: '#^Variable \$db might not be defined\.$#' - identifier: variable.undefined - count: 9 - path: ../../htdocs/public/emailing/mailing-read.php - - - - message: '#^Variable \$db might not be defined\.$#' - identifier: variable.undefined - count: 12 - path: ../../htdocs/public/emailing/mailing-unsubscribe.php - - message: '#^Call to function is_numeric\(\) with int will always evaluate to true\.$#' identifier: function.alreadyNarrowedType @@ -28530,12 +28086,6 @@ parameters: count: 2 path: ../../htdocs/public/fichinter/agendaexport.php - - - message: '#^Call to function is_numeric\(\) with int will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../htdocs/public/members/new.php - - message: '#^Call to preg_quote\(\) is missing delimiter / to be effective\.$#' identifier: argument.invalidPregQuote @@ -28554,12 +28104,6 @@ parameters: count: 1 path: ../../htdocs/public/members/new.php - - - message: '#^Call to function is_numeric\(\) with int will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../htdocs/public/members/public_card.php - - message: '#^Property Adherent\:\:\$photo \(string\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -28578,12 +28122,6 @@ parameters: count: 17 path: ../../htdocs/public/members/public_card.php - - - message: '#^Call to function is_numeric\(\) with int will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../htdocs/public/members/public_list.php - - message: '#^Call to function is_numeric\(\) with int will always evaluate to true\.$#' identifier: function.alreadyNarrowedType @@ -28686,42 +28224,6 @@ parameters: count: 1 path: ../../htdocs/public/payment/newpayment.php - - - message: '#^Variable \$PAYPAL_API_KO might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/public/payment/newpayment.php - - - - message: '#^Variable \$PAYPAL_API_OK might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/public/payment/newpayment.php - - - - message: '#^Variable \$PAYPAL_API_PASSWORD might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/public/payment/newpayment.php - - - - message: '#^Variable \$PAYPAL_API_SANDBOX might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/public/payment/newpayment.php - - - - message: '#^Variable \$PAYPAL_API_SIGNATURE might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/public/payment/newpayment.php - - - - message: '#^Variable \$PAYPAL_API_USER might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/public/payment/newpayment.php - - message: '#^Variable \$attendee might not be defined\.$#' identifier: variable.undefined @@ -30156,12 +29658,6 @@ parameters: count: 1 path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php - - - message: '#^Negated boolean expression is always true\.$#' - identifier: booleanNot.alwaysTrue - count: 2 - path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php - - message: '#^Property CommonObject\:\:\$ismultientitymanaged \(int\<0, 1\>\|string\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -30174,12 +29670,6 @@ parameters: count: 1 path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php - - - message: '#^Variable \$error in empty\(\) always exists and is always falsy\.$#' - identifier: empty.variable - count: 1 - path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php - - message: '#^Parameter \#1 \$object of method CommonDocGenerator\:\:get_substitutionarray_each_var_object\(\) expects array\, RecruitmentJobPosition given\.$#' identifier: argument.type @@ -30228,12 +29718,6 @@ parameters: count: 1 path: ../../htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php - - - message: '#^Variable \$outputlangsbis might not be defined\.$#' - identifier: variable.undefined - count: 7 - path: ../../htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php - - message: '#^Variable \$badgeStatus0 might not be defined\.$#' identifier: variable.undefined @@ -30834,12 +30318,6 @@ parameters: count: 1 path: ../../htdocs/salaries/list.php - - - message: '#^Variable \$resteapayer might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/salaries/list.php - - message: '#^Variable \$selected might not be defined\.$#' identifier: variable.undefined @@ -30858,12 +30336,6 @@ parameters: count: 2 path: ../../htdocs/salaries/paiement_salary.php - - - message: '#^Variable \$sumpaid might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../htdocs/salaries/paiement_salary.php - - message: '#^Negated boolean expression is always false\.$#' identifier: booleanNot.alwaysFalse @@ -30954,24 +30426,6 @@ parameters: count: 1 path: ../../htdocs/societe/ajax/company.php - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/societe/canvas/company/tpl/card_create.tpl.php - - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/societe/canvas/company/tpl/card_edit.tpl.php - - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/societe/canvas/company/tpl/card_view.tpl.php - - message: '#^Variable \$db might not be defined\.$#' identifier: variable.undefined @@ -31008,12 +30462,6 @@ parameters: count: 1 path: ../../htdocs/societe/canvas/individual/tpl/card_edit.tpl.php - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/societe/canvas/individual/tpl/card_view.tpl.php - - message: '#^Variable \$objcanvas might not be defined\.$#' identifier: variable.undefined @@ -31459,7 +30907,7 @@ parameters: path: ../../htdocs/societe/notify/card.php - - message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/societe/paymentmodes.php @@ -32124,18 +31572,6 @@ parameters: count: 1 path: ../../htdocs/takepos/printbox.php - - - message: '#^Path in require\(\) "//takepos/invoice\.php" is not a file or it does not exist\.$#' - identifier: require.fileNotFound - count: 1 - path: ../../htdocs/takepos/public/auto_order.php - - - - message: '#^Path in require\(\) "//takepos/phone\.php" is not a file or it does not exist\.$#' - identifier: require.fileNotFound - count: 1 - path: ../../htdocs/takepos/public/auto_order.php - - message: '#^Parameter \#2 \$addpercent of function vatrate expects bool, int given\.$#' identifier: argument.type @@ -33420,12 +32856,6 @@ parameters: count: 1 path: ../../htdocs/variants/list.php - - - message: '#^Variable \$rowid might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/variants/list.php - - message: '#^Call to function is_numeric\(\) with int will always evaluate to true\.$#' identifier: function.alreadyNarrowedType @@ -34302,30 +33732,6 @@ parameters: count: 1 path: ../../htdocs/zapier/class/api_zapier.class.php - - - message: '#^Variable \$conf might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../scripts/bank/export-bank-receipts.php - - - - message: '#^Variable \$db might not be defined\.$#' - identifier: variable.undefined - count: 27 - path: ../../scripts/bank/export-bank-receipts.php - - - - message: '#^Variable \$hookmanager might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../scripts/bank/export-bank-receipts.php - - - - message: '#^Variable \$langs might not be defined\.$#' - identifier: variable.undefined - count: 9 - path: ../../scripts/bank/export-bank-receipts.php - - message: '#^Variable \$num in isset\(\) always exists and is not nullable\.$#' identifier: isset.variable @@ -34380,84 +33786,6 @@ parameters: count: 1 path: ../../scripts/emailings/reset-invalid-emails.php - - - message: '#^Variable \$db might not be defined\.$#' - identifier: variable.undefined - count: 21 - path: ../../scripts/emailings/reset-invalid-emails.php - - - - message: '#^Variable \$hookmanager might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../scripts/emailings/reset-invalid-emails.php - - - - message: '#^Variable \$conf might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../scripts/invoices/email_unpaid_invoices_to_customers.php - - - - message: '#^Variable \$hookmanager might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../scripts/invoices/email_unpaid_invoices_to_customers.php - - - - message: '#^Variable \$langs might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../scripts/invoices/email_unpaid_invoices_to_customers.php - - - - message: '#^Variable \$conf might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../scripts/invoices/email_unpaid_invoices_to_representatives.php - - - - message: '#^Variable \$db might not be defined\.$#' - identifier: variable.undefined - count: 6 - path: ../../scripts/invoices/email_unpaid_invoices_to_representatives.php - - - - message: '#^Variable \$hookmanager might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../scripts/invoices/email_unpaid_invoices_to_representatives.php - - - - message: '#^Variable \$langs might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../scripts/invoices/email_unpaid_invoices_to_representatives.php - - - - message: '#^Variable \$conf might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../scripts/invoices/rebuild_merge_pdf.php - - - - message: '#^Variable \$db might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../scripts/invoices/rebuild_merge_pdf.php - - - - message: '#^Variable \$hookmanager might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../scripts/invoices/rebuild_merge_pdf.php - - - - message: '#^Variable \$langs might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../scripts/invoices/rebuild_merge_pdf.php - - message: '#^Variable \$user might not be defined\.$#' identifier: variable.undefined diff --git a/dev/tools/apstats.php b/dev/tools/apstats.php index fa27133329a..825257dadbe 100755 --- a/dev/tools/apstats.php +++ b/dev/tools/apstats.php @@ -883,7 +883,7 @@ $html .= '

'.$title_security $html .= '
'."\n"; $html .= '
'."\n"; $html .= ''."\n"; -$html .= ''."\n"; +$html .= ''."\n"; foreach ($arrayofalerts as $key => $alert) { $cve = ''; $yogosha = empty($alert['issueidyogosha']) ? '' : $alert['issueidyogosha']; diff --git a/dev/tools/phan/baseline.txt b/dev/tools/phan/baseline.txt index 220cdb76c5f..6d3df7446b4 100644 --- a/dev/tools/phan/baseline.txt +++ b/dev/tools/phan/baseline.txt @@ -10,43 +10,43 @@ return [ // # Issue statistics: // PhanUndeclaredProperty : 560+ occurrences - // PhanPossiblyUndeclaredGlobalVariable : 350+ occurrences - // PhanUndeclaredGlobalVariable : 300+ occurrences + // PhanPossiblyUndeclaredGlobalVariable : 320+ occurrences + // PhanUndeclaredGlobalVariable : 290+ occurrences // PhanTypeMismatchArgumentProbablyReal : 230+ occurrences // PhanPluginUnknownArrayMethodReturnType : 180+ occurrences - // PhanTypeMismatchProperty : 140+ occurrences + // PhanTypeMismatchProperty : 130+ occurrences // PhanPluginUnknownArrayMethodParamType : 120+ occurrences - // PhanPluginUnknownPropertyType : 120+ occurrences - // PhanPossiblyUndeclaredVariable : 80+ occurrences - // PhanPluginUndeclaredVariableIsset : 60+ occurrences + // PhanPluginUnknownPropertyType : 110+ occurrences + // PhanPossiblyUndeclaredVariable : 65+ occurrences // PhanRedefineFunction : 45+ occurrences // PhanTypeExpectedObjectPropAccess : 45+ occurrences // PhanTypeMismatchArgumentNullableInternal : 40+ occurrences + // PhanPluginSuspiciousParamOrder : 35+ occurrences // PhanTypeInvalidDimOffset : 30+ occurrences // PhanTypeMismatchDimFetch : 30+ occurrences // PhanPluginEmptyStatementIf : 15+ occurrences - // PhanUndeclaredConstant : 15+ occurrences // PhanPluginUnknownObjectMethodCall : 10+ occurrences // PhanTypeComparisonFromArray : 10+ occurrences // PhanTypeMismatchDimFetchNullable : 10+ occurrences // PhanUndeclaredMethod : 10+ occurrences // PhanEmptyForeach : 8 occurrences - // PhanTypeArraySuspiciousNull : 8 occurrences // PhanPluginBothLiteralsBinaryOp : 7 occurrences // PhanPluginDuplicateExpressionBinaryOp : 7 occurrences // PhanPluginSuspiciousParamPosition : 7 occurrences + // PhanTypeArraySuspiciousNull : 6 occurrences + // PhanParamTooMany : 5 occurrences // PhanPossiblyNullTypeMismatchProperty : 5 occurrences - // PhanParamTooMany : 4 occurrences - // PhanPluginDuplicateArrayKey : 4 occurrences // PhanEmptyFQSENInClasslike : 3 occurrences // PhanInvalidFQSENInClasslike : 3 occurrences // PhanTypeMismatchReturn : 3 occurrences // PhanTypeExpectedObjectPropAccessButGotNull : 2 occurrences // PhanTypeMismatchDimAssignment : 2 occurrences // PhanTypeSuspiciousStringExpression : 2 occurrences + // PhanUndeclaredTypeParameter : 2 occurrences // PhanAccessMethodProtected : 1 occurrence // PhanPluginUnknownArrayPropertyType : 1 occurrence // PhanTypeConversionFromArray : 1 occurrence + // PhanTypeMismatchArgumentInternalProbablyReal : 1 occurrence // Currently, file_suppressions and directory_suppressions are the only supported suppressions 'file_suppressions' => [ @@ -60,7 +60,7 @@ return [ 'htdocs/api/class/api_login.class.php' => ['PhanPluginUnknownArrayMethodReturnType'], 'htdocs/api/class/api_setup.class.php' => ['PhanPluginUnknownArrayMethodReturnType'], 'htdocs/api/class/api_status.class.php' => ['PhanPluginUnknownArrayMethodReturnType'], - 'htdocs/asset/class/asset.class.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanTypeInvalidDimOffset'], + 'htdocs/asset/class/asset.class.php' => ['PhanTypeInvalidDimOffset'], 'htdocs/asset/class/assetdepreciationoptions.class.php' => ['PhanTypeInvalidDimOffset'], 'htdocs/asset/class/assetmodel.class.php' => ['PhanUndeclaredProperty'], 'htdocs/asset/tpl/accountancy_codes_edit.tpl.php' => ['PhanTypeMismatchArgumentProbablyReal'], @@ -106,7 +106,6 @@ return [ 'htdocs/compta/bank/various_payment/card.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/compta/bank/various_payment/document.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/compta/bank/various_payment/info.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], - 'htdocs/compta/bank/various_payment/list.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchProperty'], 'htdocs/compta/cashcontrol/cashcontrol_card.php' => ['PhanPluginDuplicateExpressionBinaryOp'], 'htdocs/compta/cashcontrol/cashcontrol_list.php' => ['PhanTypeMismatchProperty'], 'htdocs/compta/clients.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'], @@ -134,13 +133,12 @@ return [ 'htdocs/core/actions_addupdatedelete.inc.php' => ['PhanTypeMismatchDimFetch', 'PhanUndeclaredProperty'], 'htdocs/core/actions_massactions.inc.php' => ['PhanUndeclaredProperty'], 'htdocs/core/actions_printing.inc.php' => ['PhanUndeclaredProperty'], - 'htdocs/core/actions_sendmails.inc.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], + 'htdocs/core/actions_sendmails.inc.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/core/ajax/ajaxdirtree.php' => ['PhanTypeMismatchProperty', 'PhanUndeclaredGlobalVariable'], 'htdocs/core/class/canvas.class.php' => ['PhanParamTooMany', 'PhanUndeclaredMethod'], 'htdocs/core/class/ccountry.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/cgenericdic.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/commonobject.class.php' => ['PhanParamTooMany', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], - 'htdocs/core/class/commonorder.class.php' => ['PhanPluginUnknownPropertyType'], 'htdocs/core/class/commonpeople.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/commonsocialnetworks.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/conf.class.php' => ['PhanPluginUnknownPropertyType', 'PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanTypeMismatchProperty'], @@ -153,6 +151,7 @@ return [ 'htdocs/core/class/html.formcompany.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/html.formfile.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/html.formmail.class.php' => ['PhanUndeclaredProperty'], + 'htdocs/core/class/ldap.class.php' => ['PhanTypeMismatchArgumentInternalProbablyReal'], 'htdocs/core/class/notify.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/smtps.class.php' => ['PhanTypeConversionFromArray'], 'htdocs/core/class/timespent.class.php' => ['PhanUndeclaredMethod', 'PhanUndeclaredProperty'], @@ -170,49 +169,65 @@ return [ 'htdocs/core/lib/project.lib.php' => ['PhanUndeclaredProperty'], 'htdocs/core/lib/xcal.lib.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/core/modules/asset/mod_asset_advanced.php' => ['PhanUndeclaredProperty'], + 'htdocs/core/modules/asset/mod_asset_advanced.php' => ['PhanPluginSuspiciousParamOrder', 'PhanUndeclaredProperty'], 'htdocs/core/modules/barcode/doc/phpbarcode.modules.php' => ['PhanPossiblyNullTypeMismatchProperty', 'PhanPossiblyUndeclaredVariable'], - 'htdocs/core/modules/barcode/mod_barcode_product_standard.php' => ['PhanPluginUnknownPropertyType'], - 'htdocs/core/modules/bom/mod_bom_advanced.php' => ['PhanUndeclaredProperty'], + 'htdocs/core/modules/barcode/mod_barcode_product_standard.php' => ['PhanPluginSuspiciousParamOrder', 'PhanPluginUnknownPropertyType'], + 'htdocs/core/modules/barcode/mod_barcode_thirdparty_standard.php' => ['PhanPluginSuspiciousParamOrder'], + 'htdocs/core/modules/bom/mod_bom_advanced.php' => ['PhanPluginSuspiciousParamOrder', 'PhanUndeclaredProperty'], + 'htdocs/core/modules/cheque/mod_chequereceipt_thyme.php' => ['PhanPluginSuspiciousParamOrder'], 'htdocs/core/modules/commande/doc/pdf_einstein.modules.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], + 'htdocs/core/modules/commande/mod_commande_saphir.php' => ['PhanPluginSuspiciousParamOrder'], 'htdocs/core/modules/commande/modules_commande.php' => ['PhanPluginUnknownPropertyType'], 'htdocs/core/modules/contract/doc/pdf_strato.modules.php' => ['PhanTypeMismatchArgumentNullableInternal'], + 'htdocs/core/modules/contract/mod_contract_magre.php' => ['PhanPluginSuspiciousParamOrder'], 'htdocs/core/modules/delivery/doc/pdf_storm.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/core/modules/delivery/doc/pdf_typhon.modules.php' => ['PhanPluginUnknownPropertyType'], - 'htdocs/core/modules/delivery/mod_delivery_saphir.php' => ['PhanUndeclaredProperty'], + 'htdocs/core/modules/delivery/mod_delivery_saphir.php' => ['PhanPluginSuspiciousParamOrder', 'PhanUndeclaredProperty'], 'htdocs/core/modules/expedition/doc/pdf_merou.modules.php' => ['PhanPluginUnknownPropertyType', 'PhanTypeMismatchArgumentProbablyReal'], + 'htdocs/core/modules/expedition/mod_expedition_ribera.php' => ['PhanPluginSuspiciousParamOrder'], 'htdocs/core/modules/expensereport/doc/pdf_standard_expensereport.modules.php' => ['PhanPluginUnknownPropertyType', 'PhanUndeclaredProperty'], + 'htdocs/core/modules/expensereport/mod_expensereport_sand.php' => ['PhanPluginSuspiciousParamOrder'], 'htdocs/core/modules/facture/doc/pdf_crabe.modules.php' => ['PhanPluginEmptyStatementIf', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/core/modules/facture/doc/pdf_octopus.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], 'htdocs/core/modules/facture/doc/pdf_sponge.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], 'htdocs/core/modules/facture/modules_facture.php' => ['PhanPluginUnknownPropertyType'], + 'htdocs/core/modules/fichinter/mod_arctic.php' => ['PhanPluginSuspiciousParamOrder'], 'htdocs/core/modules/fichinter/mod_pacific.php' => ['PhanPossiblyUndeclaredVariable'], + 'htdocs/core/modules/holiday/mod_holiday_immaculate.php' => ['PhanPluginSuspiciousParamOrder'], 'htdocs/core/modules/hrm/doc/pdf_standard_evaluation.modules.php' => ['PhanPluginUnknownPropertyType', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/hrm/mod_evaluation_advanced.php' => ['PhanUndeclaredProperty'], + 'htdocs/core/modules/hrm/mod_evaluation_advanced.php' => ['PhanPluginSuspiciousParamOrder', 'PhanUndeclaredProperty'], 'htdocs/core/modules/import/import_csv.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchProperty'], 'htdocs/core/modules/import/import_xlsx.modules.php' => ['PhanTypeMismatchProperty'], 'htdocs/core/modules/mailings/contacts1.modules.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/core/modules/mailings/thirdparties.modules.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/core/modules/movement/doc/pdf_standard_movementstock.modules.php' => ['PhanPluginDuplicateExpressionBinaryOp', 'PhanPluginEmptyStatementIf', 'PhanPluginUnknownPropertyType', 'PhanPossiblyUndeclaredVariable'], 'htdocs/core/modules/mrp/doc/pdf_vinci.modules.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/mrp/mod_mo_advanced.php' => ['PhanUndeclaredProperty'], + 'htdocs/core/modules/mrp/mod_mo_advanced.php' => ['PhanPluginSuspiciousParamOrder', 'PhanUndeclaredProperty'], 'htdocs/core/modules/oauth/github_oauthcallback.php' => ['PhanUndeclaredGlobalVariable'], + 'htdocs/core/modules/payment/mod_payment_ant.php' => ['PhanPluginSuspiciousParamOrder'], 'htdocs/core/modules/printing/printgcp.modules.php' => ['PhanTypeMismatchDimFetch'], 'htdocs/core/modules/product/doc/pdf_standard.modules.php' => ['PhanPluginEmptyStatementIf', 'PhanPossiblyUndeclaredVariable'], + 'htdocs/core/modules/product/mod_codeproduct_elephant.php' => ['PhanPluginSuspiciousParamOrder'], + 'htdocs/core/modules/product_batch/mod_lot_advanced.php' => ['PhanPluginSuspiciousParamOrder'], + 'htdocs/core/modules/product_batch/mod_sn_advanced.php' => ['PhanPluginSuspiciousParamOrder'], 'htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/project/doc/pdf_timespent.modules.php' => ['PhanUndeclaredProperty'], + 'htdocs/core/modules/project/mod_project_universal.php' => ['PhanPluginSuspiciousParamOrder'], 'htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanUndeclaredProperty'], + 'htdocs/core/modules/project/task/mod_task_universal.php' => ['PhanPluginSuspiciousParamOrder'], 'htdocs/core/modules/propale/doc/pdf_azur.modules.php' => ['PhanPluginEmptyStatementIf', 'PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/core/modules/propale/doc/pdf_cyan.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], + 'htdocs/core/modules/propale/mod_propale_saphir.php' => ['PhanPluginSuspiciousParamOrder'], 'htdocs/core/modules/propale/modules_propale.php' => ['PhanPluginUnknownPropertyType'], 'htdocs/core/modules/reception/doc/pdf_squille.modules.php' => ['PhanTypeMismatchArgumentNullableInternal', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/societe/mod_codecompta_aquarium.php' => ['PhanPluginUnknownPropertyType'], - 'htdocs/core/modules/societe/mod_codecompta_digitaria.php' => ['PhanPluginUnknownPropertyType', 'PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentNullableInternal'], + 'htdocs/core/modules/reception/mod_reception_moonstone.php' => ['PhanPluginSuspiciousParamOrder'], + 'htdocs/core/modules/societe/mod_codecompta_aquarium.php' => ['PhanPluginSuspiciousParamOrder', 'PhanPluginUnknownPropertyType'], + 'htdocs/core/modules/societe/mod_codecompta_digitaria.php' => ['PhanPluginSuspiciousParamOrder', 'PhanPluginUnknownPropertyType', 'PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentNullableInternal'], 'htdocs/core/modules/stock/doc/pdf_standard_stock.modules.php' => ['PhanPluginUnknownPropertyType', 'PhanPossiblyUndeclaredVariable'], 'htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanUndeclaredProperty'], 'htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php' => ['PhanUndeclaredProperty'], + 'htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php' => ['PhanPluginSuspiciousParamOrder', 'PhanUndeclaredProperty'], 'htdocs/core/modules/supplier_invoice/doc/doc_generic_supplier_invoice_odt.modules.php' => ['PhanPossiblyUndeclaredVariable'], 'htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchProperty'], 'htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php' => ['PhanPossiblyUndeclaredVariable'], @@ -221,24 +236,24 @@ return [ 'htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php' => ['PhanPossiblyUndeclaredVariable'], 'htdocs/core/modules/supplier_order/modules_commandefournisseur.php' => ['PhanPluginUnknownPropertyType'], 'htdocs/core/modules/supplier_payment/doc/pdf_standard_supplierpayment.modules.php' => ['PhanPluginUnknownPropertyType'], + 'htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php' => ['PhanPluginSuspiciousParamOrder'], 'htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php' => ['PhanTypeMismatchDimFetch', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], 'htdocs/core/modules/supplier_proposal/doc/pdf_zenith.modules.php' => ['PhanTypeMismatchDimFetch', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/syslog/mod_syslog_file.php' => ['PhanPluginDuplicateArrayKey'], + 'htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php' => ['PhanPluginSuspiciousParamOrder'], + 'htdocs/core/modules/takepos/mod_takepos_ref_universal.php' => ['PhanPluginSuspiciousParamOrder'], 'htdocs/core/modules/ticket/doc/doc_generic_ticket_odt.modules.php' => ['PhanPossiblyUndeclaredVariable'], + 'htdocs/core/modules/ticket/mod_ticket_universal.php' => ['PhanPluginSuspiciousParamOrder'], 'htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php' => ['PhanPossiblyUndeclaredVariable'], - 'htdocs/core/modules/workstation/mod_workstation_advanced.php' => ['PhanUndeclaredProperty'], + 'htdocs/core/modules/workstation/mod_workstation_advanced.php' => ['PhanPluginSuspiciousParamOrder', 'PhanUndeclaredProperty'], 'htdocs/core/search_page.php' => ['PhanEmptyForeach', 'PhanPluginBothLiteralsBinaryOp'], - 'htdocs/core/tpl/ajaxrow.tpl.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanUndeclaredGlobalVariable'], + 'htdocs/core/tpl/ajaxrow.tpl.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/core/tpl/commonfields_view.tpl.php' => ['PhanPossiblyUndeclaredGlobalVariable'], - 'htdocs/core/tpl/document_actions_post_headers.tpl.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanUndeclaredGlobalVariable'], - 'htdocs/core/tpl/extrafields_edit.tpl.php' => ['PhanPluginUndeclaredVariableIsset'], - 'htdocs/core/tpl/extrafields_list_search_title.tpl.php' => ['PhanPluginUndeclaredVariableIsset'], + 'htdocs/core/tpl/document_actions_post_headers.tpl.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/core/tpl/extrafields_view.tpl.php' => ['PhanUndeclaredProperty'], - 'htdocs/core/tpl/filemanager.tpl.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeExpectedObjectPropAccess', 'PhanUndeclaredGlobalVariable'], - 'htdocs/core/tpl/formlayoutai.tpl.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanUndeclaredGlobalVariable'], - 'htdocs/core/tpl/list_print_total.tpl.php' => ['PhanPluginUndeclaredVariableIsset'], - 'htdocs/core/tpl/massactions_pre.tpl.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], - 'htdocs/core/tpl/notes.tpl.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanTypeMismatchArgumentProbablyReal'], + 'htdocs/core/tpl/filemanager.tpl.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeExpectedObjectPropAccess', 'PhanUndeclaredGlobalVariable'], + 'htdocs/core/tpl/formlayoutai.tpl.php' => ['PhanUndeclaredGlobalVariable'], + 'htdocs/core/tpl/massactions_pre.tpl.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], + 'htdocs/core/tpl/notes.tpl.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/core/tpl/object_discounts.tpl.php' => ['PhanTypeMismatchArgumentNullableInternal', 'PhanUndeclaredGlobalVariable'], 'htdocs/core/tpl/objectline_create.tpl.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'], 'htdocs/core/tpl/objectline_view.tpl.php' => ['PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], @@ -262,11 +277,10 @@ return [ 'htdocs/delivery/tpl/linkedobjectblock.tpl.php' => ['PhanUndeclaredProperty'], 'htdocs/document.php' => ['PhanRedefineFunction'], 'htdocs/don/admin/donation.php' => ['PhanUndeclaredMethod'], - 'htdocs/don/card.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], + 'htdocs/don/card.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/don/class/api_donations.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType'], 'htdocs/don/class/don.class.php' => ['PhanParamTooMany'], 'htdocs/don/document.php' => ['PhanPluginEmptyStatementIf', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'], - 'htdocs/don/index.php' => ['PhanPluginUndeclaredVariableIsset'], 'htdocs/don/info.php' => ['PhanPluginEmptyStatementIf', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'], 'htdocs/don/list.php' => ['PhanTypeMismatchProperty'], 'htdocs/don/note.php' => ['PhanPluginEmptyStatementIf', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'], @@ -277,9 +291,9 @@ return [ 'htdocs/ecm/dir_card.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/ecm/index.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/emailcollector/class/emailcollector.class.php' => ['PhanUndeclaredProperty'], + 'htdocs/emailcollector/lib/emailcollector.lib.php' => ['PhanUndeclaredTypeParameter'], 'htdocs/eventorganization/class/conferenceorboothattendee.class.php' => ['PhanUndeclaredMethod', 'PhanUndeclaredProperty'], 'htdocs/eventorganization/conferenceorbooth_card.php' => ['PhanUndeclaredGlobalVariable'], - 'htdocs/eventorganization/conferenceorbooth_contact.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'], 'htdocs/eventorganization/conferenceorbooth_list.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/eventorganization/conferenceorboothattendee_card.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'], 'htdocs/eventorganization/conferenceorboothattendee_list.php' => ['PhanTypeMismatchArgumentProbablyReal'], @@ -303,12 +317,12 @@ return [ '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/card-rec.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/fichinter/class/api_interventions.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', '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/filefunc.inc.php' => ['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'], @@ -325,7 +339,7 @@ return [ 'htdocs/fourn/facture/card.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchProperty'], 'htdocs/fourn/facture/list-rec.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/fourn/facture/list.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/fourn/facture/paiement.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'], + 'htdocs/fourn/facture/paiement.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php' => ['PhanUndeclaredProperty'], 'htdocs/fourn/paiement/card.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/fourn/paiement/document.php' => ['PhanTypeMismatchArgumentProbablyReal'], @@ -353,12 +367,10 @@ return [ 'htdocs/imports/emptyexample.php' => ['PhanRedefineFunction', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/imports/import.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/install/check.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentNullableInternal'], - 'htdocs/install/fileconf.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable'], - 'htdocs/install/inc.php' => ['PhanPluginUndeclaredVariableIsset'], + 'htdocs/install/fileconf.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/install/index.php' => ['PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/install/repair.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable'], + 'htdocs/install/repair.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/install/step2.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanUndeclaredProperty'], - 'htdocs/install/step5.php' => ['PhanPluginUndeclaredVariableIsset'], 'htdocs/install/upgrade.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentNullableInternal'], 'htdocs/intracommreport/card.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType'], @@ -376,7 +388,7 @@ return [ 'htdocs/mrp/class/mo.class.php' => ['PhanTypeMismatchProperty'], 'htdocs/mrp/mo_card.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/mrp/mo_movements.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanUndeclaredGlobalVariable'], - 'htdocs/mrp/mo_production.php' => ['PhanTypeMismatchArgumentProbablyReal'], + 'htdocs/mrp/mo_production.php' => ['PhanPluginEmptyStatementIf', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/mrp/tpl/linkedobjectblock.tpl.php' => ['PhanUndeclaredProperty'], 'htdocs/mrp/tpl/originproductline.tpl.php' => ['PhanUndeclaredProperty'], 'htdocs/multicurrency/class/api_multicurrencies.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType'], @@ -384,7 +396,6 @@ return [ 'htdocs/opcachepreload.php' => ['PhanEmptyForeach'], 'htdocs/opensurvey/card.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/opensurvey/class/opensurveysondage.class.php' => ['PhanTypeMismatchProperty'], - 'htdocs/opensurvey/list.php' => ['PhanPluginUndeclaredVariableIsset'], 'htdocs/opensurvey/results.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanUndeclaredGlobalVariable'], 'htdocs/opensurvey/wizard/choix_date.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/opensurvey/wizard/create_survey.php' => ['PhanPossiblyUndeclaredGlobalVariable'], @@ -401,12 +412,11 @@ return [ 'htdocs/product/class/html.formproduct.class.php' => ['PhanUndeclaredProperty'], 'htdocs/product/class/productfournisseurprice.class.php' => ['PhanUndeclaredMethod', 'PhanUndeclaredProperty'], 'htdocs/product/document.php' => ['PhanPossiblyNullTypeMismatchProperty', 'PhanPossiblyUndeclaredGlobalVariable'], - 'htdocs/product/index.php' => ['PhanPluginUndeclaredVariableIsset'], 'htdocs/product/inventory/card.php' => ['PhanPluginEmptyStatementIf', 'PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/product/inventory/class/inventory.class.php' => ['PhanUndeclaredProperty'], 'htdocs/product/inventory/inventory.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/product/inventory/list.php' => ['PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/product/list.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable'], + 'htdocs/product/list.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/product/price.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/product/reassort.php' => ['PhanTypeExpectedObjectPropAccessButGotNull'], 'htdocs/product/stats/card.php' => ['PhanTypeComparisonFromArray'], @@ -417,8 +427,8 @@ return [ 'htdocs/product/stock/class/mouvementstock.class.php' => ['PhanPossiblyUndeclaredVariable'], 'htdocs/product/stock/info.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/product/stock/list.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], - 'htdocs/product/stock/movement_card.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], - 'htdocs/product/stock/movement_list.php' => ['PhanPluginBothLiteralsBinaryOp', 'PhanPluginUndeclaredVariableIsset', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], + 'htdocs/product/stock/movement_card.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], + 'htdocs/product/stock/movement_list.php' => ['PhanPluginBothLiteralsBinaryOp', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/product/stock/product.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/product/stock/productlot_card.php' => ['PhanUndeclaredProperty'], 'htdocs/product/stock/productlot_list.php' => ['PhanTypeMismatchArgumentProbablyReal'], @@ -442,7 +452,7 @@ return [ 'htdocs/projet/element.php' => ['PhanUndeclaredProperty'], 'htdocs/projet/ganttchart.inc.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable'], 'htdocs/projet/ganttview.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/projet/graph_opportunities.inc.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanUndeclaredGlobalVariable'], + 'htdocs/projet/graph_opportunities.inc.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/projet/index.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/projet/list.php' => ['PhanPluginEmptyStatementIf', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/projet/stats/index.php' => ['PhanPossiblyUndeclaredGlobalVariable'], @@ -453,11 +463,11 @@ return [ 'htdocs/projet/tasks/list.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/projet/tasks/note.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/projet/tasks/task.php' => ['PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/projet/tasks/time.php' => ['PhanEmptyForeach', 'PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeInvalidDimOffset', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], + 'htdocs/projet/tasks/time.php' => ['PhanEmptyForeach', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeInvalidDimOffset', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/projet/tasks/tpl/linkedobjectblock.tpl.php' => ['PhanUndeclaredProperty'], 'htdocs/public/agenda/agendaexport.php' => ['PhanRedefineFunction'], 'htdocs/public/bookcal/index.php' => ['PhanRedefineFunction'], - 'htdocs/public/company/new.php' => ['PhanRedefineFunction', 'PhanUndeclaredGlobalVariable'], + 'htdocs/public/company/new.php' => ['PhanRedefineFunction'], 'htdocs/public/cron/cron_run_jobs_by_url.php' => ['PhanUndeclaredProperty'], 'htdocs/public/demo/index.php' => ['PhanRedefineFunction'], 'htdocs/public/donations/donateurs_code.php' => ['PhanRedefineFunction'], @@ -480,7 +490,6 @@ return [ 'htdocs/public/project/viewandvote.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'], 'htdocs/public/recruitment/view.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable'], 'htdocs/public/stripe/ipn.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable'], - 'htdocs/public/test/test_arrays.php' => ['PhanPluginUndeclaredVariableIsset'], 'htdocs/public/ticket/create_ticket.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchDimFetchNullable', 'PhanTypeMismatchProperty'], 'htdocs/public/ticket/view.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/public/webportal/tpl/menu.tpl.php' => ['PhanUndeclaredProperty'], @@ -492,15 +501,15 @@ return [ 'htdocs/reception/class/reception.class.php' => ['PhanUndeclaredProperty'], 'htdocs/reception/contact.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/reception/dispatch.php' => ['PhanPossiblyUndeclaredGlobalVariable'], - 'htdocs/reception/list.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], + 'htdocs/reception/list.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/reception/note.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/recruitment/admin/setup.php' => ['PhanEmptyForeach'], 'htdocs/recruitment/admin/setup_candidatures.php' => ['PhanEmptyForeach'], 'htdocs/recruitment/class/recruitmentcandidature.class.php' => ['PhanUndeclaredProperty'], 'htdocs/recruitment/class/recruitmentjobposition.class.php' => ['PhanUndeclaredProperty'], - 'htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], - 'htdocs/recruitment/core/modules/recruitment/mod_recruitmentcandidature_advanced.php' => ['PhanUndeclaredProperty'], - 'htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php' => ['PhanUndeclaredProperty'], + 'htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], + 'htdocs/recruitment/core/modules/recruitment/mod_recruitmentcandidature_advanced.php' => ['PhanPluginSuspiciousParamOrder', 'PhanUndeclaredProperty'], + 'htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php' => ['PhanPluginSuspiciousParamOrder', 'PhanUndeclaredProperty'], 'htdocs/recruitment/index.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/recruitment/recruitmentcandidature_card.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/recruitment/recruitmentcandidature_list.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], @@ -514,7 +523,7 @@ return [ 'htdocs/salaries/card.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/salaries/class/api_salaries.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType'], 'htdocs/salaries/list.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'], - 'htdocs/salaries/paiement_salary.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], + 'htdocs/salaries/paiement_salary.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/salaries/virement_request.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/societe/admin/societe.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredMethod'], 'htdocs/societe/ajax/company.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], @@ -522,7 +531,7 @@ return [ 'htdocs/societe/class/api_thirdparties.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], 'htdocs/societe/class/societe.class.php' => ['PhanTypeMismatchProperty'], 'htdocs/societe/consumption.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/societe/list.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], + 'htdocs/societe/list.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/societe/paymentmodes.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeExpectedObjectPropAccess', 'PhanUndeclaredGlobalVariable'], 'htdocs/societe/price.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/societe/tpl/linesalesrepresentative.tpl.php' => ['PhanTypeMismatchArgumentProbablyReal'], @@ -536,10 +545,9 @@ return [ 'htdocs/takepos/ajax/ajax.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/takepos/floors.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/takepos/freezone.php' => ['PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/takepos/index.php' => ['PhanPluginUndeclaredVariableIsset'], 'htdocs/takepos/invoice.php' => ['PhanPluginEmptyStatementIf', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable'], 'htdocs/takepos/pay.php' => ['PhanPossiblyUndeclaredGlobalVariable'], - 'htdocs/takepos/split.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], + 'htdocs/takepos/split.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/theme/eldy/badges.inc.php' => ['PhanRedefineFunction'], 'htdocs/theme/eldy/btn.inc.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/theme/eldy/dropdown.inc.php' => ['PhanUndeclaredGlobalVariable'], @@ -597,7 +605,6 @@ return [ 'htdocs/workstation/workstation_list.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/zapier/class/api_zapier.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType'], 'htdocs/zapier/class/hook.class.php' => ['PhanUndeclaredProperty'], - 'internal' => ['PhanUndeclaredConstant'], ], // 'directory_suppressions' => ['src/directory_name' => ['PhanIssueName1', 'PhanIssueName2']] can be manually added if needed. // (directory_suppressions will currently be ignored by subsequent calls to --save-baseline, but may be preserved in future Phan releases) diff --git a/htdocs/accountancy/class/accountancyimport.class.php b/htdocs/accountancy/class/accountancyimport.class.php index bcf7905f223..a35235e0218 100644 --- a/htdocs/accountancy/class/accountancyimport.class.php +++ b/htdocs/accountancy/class/accountancyimport.class.php @@ -136,7 +136,7 @@ class AccountancyImport $sens = 'C'; } - return "'" . $this->db->escape($sens) . "'"; + return $sens; } return "''"; diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 53e6efa4934..f8573c3f75e 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -3,7 +3,8 @@ * Copyright (C) 2015-2022 Alexandre Spangaro * Copyright (C) 2015-2020 Florian Henry * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024 MDW + * Copyright (C) 2024 Jose MARTINEZ * * 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 @@ -68,7 +69,7 @@ class BookKeeping extends CommonObject public $doc_date; /** - * @var int Deadline for payment + * @var int|null|'' Deadline for payment */ public $date_lim_reglement; @@ -324,7 +325,7 @@ class BookKeeping extends CommonObject $this->piece_num = 0; // First check if line not yet already in bookkeeping. - // Note that we must include 'doc_type - fk_doc - numero_compte - label' to be sure to have unicity of line (because we may have several lines + // Note that we must include 'doc_type - fk_doc - numero_compte - label - subledger_account (if not empty)' to be sure to have unicity of line (because we may have several lines // with same doc_type, fk_doc, numero_compte for 1 invoice line when using localtaxes with same account) // WARNING: This is not reliable, label may have been modified. This is just a small protection. // The page that make transfer make the test on couple (doc_type - fk_doc) only. @@ -338,6 +339,9 @@ class BookKeeping extends CommonObject } $sql .= " AND numero_compte = '".$this->db->escape($this->numero_compte)."'"; $sql .= " AND label_operation = '".$this->db->escape($this->label_operation)."'"; + if (!empty($this->subledger_account)) { + $sql .= " AND subledger_account = '".$this->db->escape($this->subledger_account)."'"; + } $sql .= " AND entity = ".$conf->entity; // Do not use getEntity for accounting features $resql = $this->db->query($sql); @@ -2863,10 +2867,8 @@ class BookKeeping extends CommonObject $sql = 'SELECT'; $sql .= " t.numero_compte,"; - $sql .= " t.label_compte,"; if ($separate_auxiliary_account) { - $sql .= " t.subledger_account,"; - $sql .= " t.subledger_label,"; + $sql .= " NULLIF(t.subledger_account, '') as subledger_account,"; // fix db issues with Null or "" values } $sql .= " aa.pcg_type,"; $sql .= " (SUM(t.credit) - SUM(t.debit)) as opening_balance"; @@ -2878,10 +2880,11 @@ class BookKeeping extends CommonObject $sql .= ' AND aa.pcg_type IN (' . $this->db->sanitize(implode(',', $pcg_type_filter), 1) . ')'; $sql .= " AND DATE(t.doc_date) >= '" . $this->db->idate($fiscal_period->date_start) . "'"; $sql .= " AND DATE(t.doc_date) <= '" . $this->db->idate($fiscal_period->date_end) . "'"; - $sql .= ' GROUP BY t.numero_compte, t.label_compte, aa.pcg_type'; + $sql .= ' GROUP BY t.numero_compte, aa.pcg_type'; if ($separate_auxiliary_account) { - $sql .= ' ,t.subledger_account, t.subledger_label'; + $sql .= " , NULLIF(t.subledger_account, '')"; } + $sql .= ' HAVING (SUM(t.credit) - SUM(t.debit)) != 0 '; // Exclude rows with opening_balance = 0 $sql .= $this->db->order("t.numero_compte", "ASC"); $resql = $this->db->query($sql); @@ -2902,24 +2905,41 @@ class BookKeeping extends CommonObject $bookkeeping = new BookKeeping($this->db); $bookkeeping->doc_date = $new_fiscal_period->date_start; - $bookkeeping->date_lim_reglement = 0; - $bookkeeping->doc_ref = $new_fiscal_period->label; + + $bookkeeping->date_lim_reglement = ''; + $bookkeeping->doc_ref = $fiscal_period->label; + $bookkeeping->date_creation = $now; $bookkeeping->doc_type = 'closure'; - $bookkeeping->fk_doc = $new_fiscal_period->id; + $bookkeeping->fk_doc = $fiscal_period->id; $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add $bookkeeping->thirdparty_code = ''; if ($separate_auxiliary_account) { $bookkeeping->subledger_account = $obj->subledger_account; - $bookkeeping->subledger_label = $obj->subledger_label; + $sql = 'SELECT'; + $sql .= " subledger_label"; + $sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element; + $sql .= " WHERE subledger_account = '" . $this->db->escape($obj->subledger_account) . "'"; + $sql .= " ORDER BY doc_date DESC"; + $sql .= " LIMIT 1"; + $result = $this->db->query($sql); + if (!$result) { + $this->errors[] = 'Error: ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + $error++; + } + $objtmp = $this->db->fetch_object($result); + $bookkeeping->subledger_label = $objtmp->subledger_label; // latest subledger label used } else { - $bookkeeping->subledger_account = ''; - $bookkeeping->subledger_label = ''; + $bookkeeping->subledger_account = null; + $bookkeeping->subledger_label = null; } $bookkeeping->numero_compte = $obj->numero_compte; - $bookkeeping->label_compte = $obj->label_compte; + $accountingaccount = new AccountingAccount($this->db); + $accountingaccount->fetch(0, $obj->numero_compte); + $bookkeeping->label_compte = $accountingaccount->label; // latest account label used $bookkeeping->label_operation = $new_fiscal_period->label; $bookkeeping->montant = $mt; @@ -2933,8 +2953,7 @@ class BookKeeping extends CommonObject $result = $bookkeeping->create($user); if ($result < 0) { - $this->error = $bookkeeping->error; - $this->errors = $bookkeeping->errors; + $this->setErrorsFromObject($bookkeeping); $error++; break; } @@ -2949,21 +2968,35 @@ class BookKeeping extends CommonObject $bookkeeping = new BookKeeping($this->db); $bookkeeping->doc_date = $new_fiscal_period->date_start; - $bookkeeping->date_lim_reglement = 0; - $bookkeeping->doc_ref = $new_fiscal_period->label; + + $bookkeeping->date_lim_reglement = ''; + $bookkeeping->doc_ref = $fiscal_period->label; + $bookkeeping->date_creation = $now; $bookkeeping->doc_type = 'closure'; - $bookkeeping->fk_doc = $new_fiscal_period->id; + $bookkeeping->fk_doc = $fiscal_period->id; $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add $bookkeeping->thirdparty_code = ''; if ($separate_auxiliary_account) { - $bookkeeping->subledger_label = ''; $bookkeeping->subledger_account = $obj->subledger_account; - $bookkeeping->subledger_label = $obj->subledger_label; + $sql = 'SELECT'; + $sql .= " subledger_label"; + $sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element; + $sql .= " WHERE subledger_account = '" . $this->db->escape($obj->subledger_account) . "'"; + $sql .= " ORDER BY doc_date DESC"; + $sql .= " LIMIT 1"; + $result = $this->db->query($sql); + if (!$result) { + $this->errors[] = 'Error: ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + $error++; + } + $objtmp = $this->db->fetch_object($result); + $bookkeeping->subledger_label = $objtmp->subledger_label; // latest subledger label used } else { - $bookkeeping->subledger_account = ''; - $bookkeeping->subledger_label = ''; + $bookkeeping->subledger_account = null; + $bookkeeping->subledger_label = null; } $bookkeeping->numero_compte = $accountingaccount->account_number; @@ -2981,8 +3014,7 @@ class BookKeeping extends CommonObject $result = $bookkeeping->create($user); if ($result < 0) { - $this->error = $bookkeeping->error; - $this->errors = $bookkeeping->errors; + $this->setErrorsFromObject($bookkeeping); $error++; } } diff --git a/htdocs/accountancy/class/lettering.class.php b/htdocs/accountancy/class/lettering.class.php index 923f977c544..964369fb545 100644 --- a/htdocs/accountancy/class/lettering.class.php +++ b/htdocs/accountancy/class/lettering.class.php @@ -864,14 +864,14 @@ class Lettering extends BookKeeping $sql = "SELECT DISTINCT tl2.fk_link, tl2.fk_doc"; $sql .= " FROM ("; // @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset - $sql .= " SELECT DISTINCT " . $this->db->ifsql("tll.".$this->db->sanitize($linked_info['fk_table_link_line_parent']), "tll.".$this->db->sanitize($linked_info['fk_table_link_line_parent']), "tl.".$this->db->sanitize($linked_info['fk_link']))." AS fk_link, tl.".$this->db->sanitize($linked_info['fk_doc'])." AS fk_doc"; + $sql .= " SELECT DISTINCT " . $this->db->ifsql("tll.".$this->db->sanitize($linked_info['fk_table_link_line_parent'])." IS NOT NULL", "tll.".$this->db->sanitize($linked_info['fk_table_link_line_parent']), "tl.".$this->db->sanitize($linked_info['fk_link']))." AS fk_link, tl.".$this->db->sanitize($linked_info['fk_doc'])." AS fk_doc"; $sql .= " FROM " . MAIN_DB_PREFIX .$this->db->sanitize($linked_info['table'])." AS tl"; // @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . $this->db->sanitize($linked_info['table_link_line']) . " AS tll ON tll.".$this->db->sanitize($linked_info['fk_table_link_line']) . " = tl.".$this->db->sanitize($linked_info['fk_line_link']); $sql .= ") AS tl"; $sql .= " LEFT JOIN ("; // @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset - $sql .= " SELECT DISTINCT " . $this->db->ifsql("tll.".$this->db->sanitize($linked_info['fk_table_link_line_parent']), "tll.".$this->db->sanitize($linked_info['fk_table_link_line_parent']), "tl.".$this->db->sanitize($linked_info['fk_link']))." AS fk_link, tl.".$this->db->sanitize($linked_info['fk_doc'])." AS fk_doc"; + $sql .= " SELECT DISTINCT " . $this->db->ifsql("tll.".$this->db->sanitize($linked_info['fk_table_link_line_parent'])." IS NOT NULL", "tll.".$this->db->sanitize($linked_info['fk_table_link_line_parent']), "tl.".$this->db->sanitize($linked_info['fk_link']))." AS fk_link, tl.".$this->db->sanitize($linked_info['fk_doc'])." AS fk_doc"; $sql .= " FROM " . MAIN_DB_PREFIX .$this->db->sanitize($linked_info['table'])." AS tl"; // @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . $this->db->sanitize($linked_info['table_link_line']) . " AS tll ON tll.".$this->db->sanitize($linked_info['fk_table_link_line']) . " = tl.".$this->db->sanitize($linked_info['fk_line_link']); diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php index ecf9ce56121..2b166dff8d9 100644 --- a/htdocs/accountancy/journal/sellsjournal.php +++ b/htdocs/accountancy/journal/sellsjournal.php @@ -461,12 +461,12 @@ SELECT fk_facture, COUNT(fd.rowid) as nb FROM - ".MAIN_DB_PREFIX."facturedet as fd + ".MAIN_DB_PREFIX."facturedet as fd WHERE fd.product_type <= 2 AND fd.fk_code_ventilation <= 0 AND fd.total_ttc <> 0 - AND fk_facture IN (".$db->sanitize(implode(",", array_keys($tabfac))).") + AND fk_facture IN (".$db->sanitize(implode(",", array_keys($tabfac))).") GROUP BY fk_facture "; $resql = $db->query($sql); diff --git a/htdocs/adherents/canvas/default/tpl/adherentcard_create.tpl.php b/htdocs/adherents/canvas/default/tpl/adherentcard_create.tpl.php index e80c263c78e..630205413d3 100644 --- a/htdocs/adherents/canvas/default/tpl/adherentcard_create.tpl.php +++ b/htdocs/adherents/canvas/default/tpl/adherentcard_create.tpl.php @@ -19,8 +19,11 @@ /** * @var Adherent $object + * @var Canvas $this * @var Conf $conf * @var Translate $langs + * + * @var string $canvas */ // Protection to avoid direct call of template diff --git a/htdocs/adherents/canvas/default/tpl/adherentcard_edit.tpl.php b/htdocs/adherents/canvas/default/tpl/adherentcard_edit.tpl.php index 0b19fcb851a..626833d8385 100644 --- a/htdocs/adherents/canvas/default/tpl/adherentcard_edit.tpl.php +++ b/htdocs/adherents/canvas/default/tpl/adherentcard_edit.tpl.php @@ -1,6 +1,6 @@ - * Copyright (C) 2012 Philippe Grand +/* Copyright (C) 2010 Regis Houssin + * Copyright (C) 2012 Philippe Grand * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -19,8 +19,11 @@ /** * @var Adherent $object + * @var Canvas $this * @var Conf $conf * @var Translate $langs + * + * @var string $canvas */ // Protection to avoid direct call of template diff --git a/htdocs/adherents/canvas/default/tpl/adherentcard_view.tpl.php b/htdocs/adherents/canvas/default/tpl/adherentcard_view.tpl.php index 30bd5eded83..54c3acafa6a 100644 --- a/htdocs/adherents/canvas/default/tpl/adherentcard_view.tpl.php +++ b/htdocs/adherents/canvas/default/tpl/adherentcard_view.tpl.php @@ -1,6 +1,6 @@ - * Copyright (C) 2012-2022 Philippe Grand +/* Copyright (C) 2010-2012 Regis Houssin + * Copyright (C) 2012-2022 Philippe Grand * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -19,9 +19,12 @@ /** * @var Adherent $object + * @var Canvas $this * @var Conf $conf * @var Translate $langs * @var User $user + * + * @var string $canvas */ // Protection to avoid direct call of template diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index ffe840e9483..26833536fee 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -374,7 +374,7 @@ class Adherent extends CommonObject */ const STATUS_VALIDATED = 1; /** - * Resiliated + * Resiliated (membership end and was not renew) */ const STATUS_RESILIATED = 0; /** diff --git a/htdocs/admin/agenda_other.php b/htdocs/admin/agenda_other.php index 972ede049d2..5f50050e53c 100644 --- a/htdocs/admin/agenda_other.php +++ b/htdocs/admin/agenda_other.php @@ -53,6 +53,7 @@ $langs->loadLangs(array('admin', 'other', 'agenda', 'users')); $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$label = GETPOST('label', 'alpha'); $modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php $param = GETPOST('param', 'alpha'); diff --git a/htdocs/admin/agenda_reminder.php b/htdocs/admin/agenda_reminder.php index 68e63d3eb32..14821a3da45 100644 --- a/htdocs/admin/agenda_reminder.php +++ b/htdocs/admin/agenda_reminder.php @@ -48,6 +48,7 @@ $langs->loadLangs(array("admin", "other", "agenda")); $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$label = GETPOST('label', 'alpha'); $modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php $param = GETPOST('param', 'alpha'); diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 72373a88c5f..ffabe10d68d 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -1381,7 +1381,26 @@ if ($id > 0) { $tablecode = 't.code'; $tableprefix = ''; - $tableprefixarray = array(DICT_FORME_JURIDIQUE => 'f.code', DICT_DEPARTEMENTS => 'd.code_departement', DICT_REGIONS => 'r.code_region', DICT_COUNTRY => 'c.code', DICT_CIVILITY => 'c.code', DICT_ACTIONCOMM => 'a.code', DICT_CURRENCIES => 'code_iso', DICT_ECOTAXE => 'e.code', DICT_HOLIDAY_TYPES => 'h.code', DICT_CHARGESOCIALES => 'a.code', DICT_HRM_PUBLIC_HOLIDAY => 'a.code', DICT_UNITS => 'r.code', DICT_SOCIALNETWORKS => 's.code', 45 => 'f.code', 46 => 'f.code', 47 => 'f.code', 48 => 'f.code'); + $tableprefixarray = array( + DICT_FORME_JURIDIQUE => 'f.code', + DICT_DEPARTEMENTS => 'd.code_departement', + DICT_REGIONS => 'r.code_region', + DICT_COUNTRY => 'c.code', + DICT_CIVILITY => 'c.code', + DICT_ACTIONCOMM => 'a.code', + DICT_CHARGESOCIALES => 'a.code', + DICT_TYPENT => 't.code', + DICT_CURRENCIES => 'c.code_iso', + DICT_ECOTAXE => 'e.code', + DICT_HOLIDAY_TYPES => 'h.code', + DICT_HRM_PUBLIC_HOLIDAY => 'a.code', + DICT_UNITS => 'r.code', + DICT_SOCIALNETWORKS => 's.code', + 45 => 'f.code', + 46 => 'f.code', + 47 => 'f.code', + 48 => 'f.code', + ); if (!empty($tableprefixarray[$id])) { $tablecode = $tableprefixarray[$id]; $tableprefix = preg_replace('/\..*$/', '.', $tablecode); diff --git a/htdocs/admin/index.php b/htdocs/admin/index.php index 2fe24da05e9..0aa392a0c52 100644 --- a/htdocs/admin/index.php +++ b/htdocs/admin/index.php @@ -61,16 +61,16 @@ print load_fiche_titre($langs->trans("SetupArea"), '', 'tools'); if (getDolGlobalString('MAIN_MOTD_SETUPPAGE')) { - $conf->global->MAIN_MOTD_SETUPPAGE = preg_replace('//i', '
', $conf->global->MAIN_MOTD_SETUPPAGE); + $conf->global->MAIN_MOTD_SETUPPAGE = preg_replace('//i', '
', getDolGlobalString('MAIN_MOTD_SETUPPAGE')); if (getDolGlobalString('MAIN_MOTD_SETUPPAGE')) { $i = 0; $reg = array(); - while (preg_match('/__\(([a-zA-Z|@]+)\)__/i', $conf->global->MAIN_MOTD_SETUPPAGE, $reg) && $i < 100) { + while (preg_match('/__\(([a-zA-Z|@]+)\)__/i', getDolGlobalString('MAIN_MOTD_SETUPPAGE'), $reg) && $i < 100) { $tmp = explode('|', $reg[1]); if (!empty($tmp[1])) { $langs->load($tmp[1]); } - $conf->global->MAIN_MOTD_SETUPPAGE = preg_replace('/__\('.preg_quote($reg[1]).'\)__/i', $langs->trans($tmp[0]), $conf->global->MAIN_MOTD_SETUPPAGE); + $conf->global->MAIN_MOTD_SETUPPAGE = preg_replace('/__\('.preg_quote($reg[1]).'\)__/i', $langs->trans($tmp[0]), getDolGlobalString('MAIN_MOTD_SETUPPAGE')); $i++; } diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index b4e9267eec0..afda0e31733 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -1059,9 +1059,24 @@ if ($action == 'edit') { $text .= /* ($text ? '

' : ''). */$langs->trans("WarningPHPMailSPF", getDolGlobalString('MAIN_EXTERNAL_SMTP_SPF_STRING_TO_ADD')); } if (getDolGlobalString('MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS')) { // Not defined by default. Depend on platform. + $ipstoshow = ''; // List of IP shown as record to add as allowed IP if we use the smtp method. Value is '1.2.3.4, [aaaa:bbbb:cccc:dddd]' - // TODO Add a key to allow to show the IP/name of server detected dynamically - $text .= ($text ? '

' : '').$langs->trans("WarningPHPMail2", getDolGlobalString('MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS')); + $arrayipstoshow = explode(',', getDolGlobalString('MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS')); + foreach ($arrayipstoshow as $iptoshow) { + // If MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS is an URL to get/show the public IP/name of server detected dynamically + if (preg_match('/^http/i', $iptoshow)) { + $tmpresult = getURLContent($iptoshow, 'GET', '', 1, array(), array('http', 'https'), 0); + if (!empty($tmpresult['content'])) { + $iptoshow = $tmpresult['content']; + } else { + $iptoshow = ''; // Failed to get IP + } + } + $ipstoshow .= ($ipstoshow ? ', ' : '').trim($iptoshow); + } + if ($ipstoshow) { + $text .= ($text ? '

' : '').$langs->trans("WarningPHPMail2", $ipstoshow); + } } } diff --git a/htdocs/admin/mails_senderprofile_list.php b/htdocs/admin/mails_senderprofile_list.php index 29887bba770..a586d8407bb 100644 --- a/htdocs/admin/mails_senderprofile_list.php +++ b/htdocs/admin/mails_senderprofile_list.php @@ -1,8 +1,8 @@ - * Copyright (C) 2018 Ferran Marcet +/* Copyright (C) 2007-2017 Laurent Destailleur + * Copyright (C) 2018 Ferran Marcet * Copyright (C) 2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024 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 @@ -55,7 +55,6 @@ $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' $mode = GETPOST('mode', 'aZ'); // The output mode ('list', 'kanban', 'hierarchy', 'calendar', ...) $id = GETPOSTINT('id'); -$rowid = GETPOST('rowid', 'alpha'); // Load variable for pagination $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit; @@ -83,8 +82,8 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen // Default sort order (if not yet defined by previous GETPOST) if (!$sortfield) { - reset($object->fields); // Reset is required to avoid key() to return null. - $sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition. + reset($object->fields); // Reset is required to avoid key() to return null. + $sortfield = "t.position"; // Set here default search field. By default 1st field in definition. } if (!$sortorder) { $sortorder = "ASC"; @@ -804,14 +803,11 @@ while ($i < $imaxinloop) { $url .= '&limit='.((int) $limit); } if ($page) { - $url .= '&page='.urlencode((string) ($page)); - } - if ($sortfield) { - $url .= '&sortfield='.urlencode($sortfield); - } - if ($sortorder) { - $url .= '&page='.urlencode($sortorder); + $url .= '&page='.urlencode((string) $page); } + $url .= '&sortfield='.urlencode((string) $sortfield); + $url .= '&page='.urlencode((string) $sortorder); + print ''.img_edit().''; //print '   '; print ''.img_delete().'   '; @@ -828,7 +824,6 @@ while ($i < $imaxinloop) { } } - print ''."\n"; } diff --git a/htdocs/admin/openid_connect.php b/htdocs/admin/openid_connect.php index 7a42c90369d..c5f80897c5e 100644 --- a/htdocs/admin/openid_connect.php +++ b/htdocs/admin/openid_connect.php @@ -37,10 +37,11 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/openid_connect.lib.php'; * @var User $user */ -$langs->load("admin"); -$langs->load("openidconnect"); +$langs->loadLangs(["admin", "openidconnect"]); -if (!$user->admin) accessforbidden(); +if (!$user->admin) { + accessforbidden(); +} $action = GETPOST('action', 'alpha'); @@ -143,8 +144,6 @@ print '
'; print ''; print ''; -$var=true; - print '
Commit IDDateReported on
Yogosha
Reported on
GIT
Reported on
CVE
TitleBranch of fix
Commit IDDateReported on
Yogosha
Reported on
GIT
Reported on
CVE
TitleBranch of fix
'; print ''; print ''."\n"; @@ -153,8 +152,7 @@ print ''."\n"; print "\n"; // MAIN_AUTHENTICATION_OIDC_LOGIN_CLAIM -$var = !$var; -print '' . "\n"; +print '' . "\n"; print ''."\n"; print ''."\n"; print '' . "\n"; print ''."\n"; print ''."\n"; print '' . "\n"; print ''."\n"; print ''."\n"; print '' . "\n"; print ''."\n"; print ''."\n"; print '' . "\n"; print ''."\n"; print ''."\n"; print '' . "\n"; print ''."\n"; print ''."\n"; print '' . "\n"; print ''."\n"; print ''."\n"; print '' . "\n"; print ''."\n"; print ''."\n"; print '' . "\n"; print ''."\n"; print ''."\n"; print '' . "\n"; print ''."\n"; print ''."\n"; print '\n\n"; $found++; if (isModEnabled("reception")) { - print ''; + print ''; print ''; print ''; print '\n\n"; $found++; - + print ''; print ''; print ''; print ''; // Actions code print ''; // Ref print ''; -// Link to ref -print ''; - // Amount print ''; @@ -521,6 +519,9 @@ print $form->selectarray('search_showonlyerrors', $array, $search_showonlyerrors print ''; // Status note +//print ''; + +// Link to original ref into business software print ''; // Action column @@ -543,12 +544,12 @@ print getTitleFieldOfList($langs->trans('Date'), 0, $_SERVER["PHP_SELF"], 'date_ print getTitleFieldOfList($langs->trans('Author'), 0, $_SERVER["PHP_SELF"], 'user_fullname', '', $param, '', $sortfield, $sortorder, '')."\n"; print getTitleFieldOfList($langs->trans('Action'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '')."\n"; print getTitleFieldOfList($langs->trans('Ref'), 0, $_SERVER["PHP_SELF"], 'ref_object', '', $param, '', $sortfield, $sortorder, '')."\n"; -print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '')."\n"; print getTitleFieldOfList($langs->trans('Amount'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'right ')."\n"; -print getTitleFieldOfList($langs->trans('DataOfArchivedEvent'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ', 0, $langs->trans('DataOfArchivedEventHelp').'
'.$langs->trans('DataOfArchivedEventHelp2'), 1)."\n"; +print getTitleFieldOfList($langs->trans('DataOfArchivedEvent'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ', 0, $langs->trans('DataOfArchivedEventHelp'), 1)."\n"; print getTitleFieldOfList($langs->trans('Fingerprint'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '')."\n"; -print getTitleFieldOfList($langs->trans('Status'), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ')."\n"; -print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ')."\n"; +print getTitleFieldOfList($form->textwithpicto($langs->trans('Status'), $langs->trans('DataOfArchivedEventHelp2')), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ')."\n"; +//print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ')."\n"; +print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '')."\n"; // Action column if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $param, 'class="center"', $sortfield, $sortorder, '')."\n"; @@ -633,12 +634,6 @@ if (is_array($blocks)) { print dol_escape_htmltag($block->ref_object); print ''; - // Link to source object - print ''; @@ -666,14 +661,18 @@ if (is_array($blocks)) { } else { print 'OK'; } - print ''; + //print ''; // Note - print ''; + // Link to source object + print ''; @@ -1811,7 +1811,7 @@ if ($action == 'create') { print "\n".''; - */ if ($conf->use_javascript_ajax) { $out .= ajax_combobox('model'); } @@ -1420,7 +1387,7 @@ class FormFile // Show title of list of existing files $morehtmlright = ''; if (!empty($moreoptions['showhideaddbutton']) && $conf->use_javascript_ajax) { - $tmpurlforbutton = 'javascript:console.log("open add file form");jQuery(".divattachnewfile").toggle(); if (!jQuery(".divattachnewfile").is(":hidden")) { jQuery("input[type=\'file\']").click(); }'; + $tmpurlforbutton = 'javascript:console.log("open add file form");jQuery(".divattachnewfile").toggle(); if (!jQuery(".divattachnewfile").is(":hidden")) { jQuery("input[type=\'file\']").click();}void(0);'; $morehtmlright .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', $tmpurlforbutton, '', $permtoeditline); } @@ -2254,7 +2221,7 @@ class FormFile $morehtmlright = ''; if (!empty($moreoptions['showhideaddbutton']) && $conf->use_javascript_ajax) { - $morehtmlright .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', 'javascript:console.log("open addlink form"); jQuery(".divlinkfile").toggle();', '', $permissiontoedit); + $morehtmlright .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', 'javascript:console.log("open addlink form"); jQuery(".divlinkfile").toggle(); void(0);', '', $permissiontoedit); } // Show list of associated links diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php index e920f35f098..6b1ab1cb007 100644 --- a/htdocs/core/class/html.formsetup.class.php +++ b/htdocs/core/class/html.formsetup.class.php @@ -1331,12 +1331,25 @@ class FormSetupItem public function generateOutputFieldColor() { global $langs; + $out = ''; $this->fieldAttr['disabled'] = null; $color = colorArrayToHex(colorStringToArray($this->fieldValue, array()), ''); - if ($color) { - return ''; + $useDefaultColor = false; + if (!$color && !empty($this->defaultFieldValue)) { + $color = $this->defaultFieldValue; + $useDefaultColor = true; } - return $langs->trans("Default"); + if ($color) { + $out.= ''; + } + + if ($useDefaultColor) { + $out.= ' '.$langs->trans("Default"); + } else { + $out.= ' #'.$color; + } + + return $out; } /** * generateInputFieldColor diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php index 30664b90218..348fe8a81e0 100644 --- a/htdocs/core/class/html.formticket.class.php +++ b/htdocs/core/class/html.formticket.class.php @@ -895,7 +895,7 @@ class FormTicket $ticketstat->loadCacheTypesTickets(); print ''; $text .= ''; $text .= ''; - $text .= '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'.$langs->trans("MainAuthenticationOidcLoginClaimName").''.$langs->trans("MainAuthenticationOidcLoginClaimDesc").'' . "\n"; @@ -162,8 +160,7 @@ print '' . "\n"; +print '
'.$langs->trans("MainAuthenticationOidcClientIdName").''.$langs->trans("MainAuthenticationOidcClientIdDesc").'' . "\n"; @@ -171,8 +168,7 @@ print '' . "\n"; +print '
'.$langs->trans("MainAuthenticationOidcClientSecretName").''.$langs->trans("MainAuthenticationOidcClientSecretDesc").'' . "\n"; @@ -180,8 +176,7 @@ print '' . "\n"; +print '
'.$langs->trans("MainAuthenticationOidcScopesName").''.$langs->trans("MainAuthenticationOidcScopesDesc").'' . "\n"; @@ -189,8 +184,7 @@ print '' . "\n"; +print '
'.$langs->trans("MainAuthenticationOidcAuthorizeUrlName").''.$langs->trans("MainAuthenticationOidcAuthorizeUrlDesc").'' . "\n"; @@ -198,8 +192,7 @@ print '' . "\n"; +print '
'.$langs->trans("MainAuthenticationOidcTokenUrlName").''.$langs->trans("MainAuthenticationOidcTokenUrlDesc").'' . "\n"; @@ -207,8 +200,7 @@ print '' . "\n"; +print '
'.$langs->trans("MainAuthenticationOidcUserinfoUrlName").''.$langs->trans("MainAuthenticationOidcUserinfoUrlDesc").'' . "\n"; @@ -216,8 +208,7 @@ print '' . "\n"; +print '
'.$langs->trans("MainAuthenticationOidcLogoutUrlName").''.$langs->trans("MainAuthenticationOidcLogoutUrlDesc").'' . "\n"; @@ -225,8 +216,7 @@ print '' . "\n"; +print '
'.$langs->trans("MainAuthenticationOidcRedirectUrlName").''.$langs->trans("MainAuthenticationOidcRedirectUrlDesc").'' . "\n"; @@ -234,8 +224,7 @@ print '' . "\n"; +print '
'.$langs->trans("MainAuthenticationOidcLogoutRedirectUrlName").''.$langs->trans("MainAuthenticationOidcLogoutRedirectUrlDesc").'' . "\n"; @@ -256,3 +245,4 @@ print '
'; print dol_get_fiche_end(); llxFooter(); +$db->close(); diff --git a/htdocs/admin/security_other.php b/htdocs/admin/security_other.php index 017194f70c4..433d7a325fd 100644 --- a/htdocs/admin/security_other.php +++ b/htdocs/admin/security_other.php @@ -76,6 +76,7 @@ if (preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) { $res3 = 1; $res4 = 1; $res5 = 1; + $res6 = 1; if (GETPOSTISSET('MAIN_APPLICATION_TITLE')) { $res1 = dolibarr_set_const($db, "MAIN_APPLICATION_TITLE", GETPOST("MAIN_APPLICATION_TITLE", 'alphanohtml'), 'chaine', 0, '', $conf->entity); } @@ -91,7 +92,10 @@ if (preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) { if (GETPOSTISSET('MAIN_SECURITY_MAX_ATTACHMENT_ON_FORMS')) { $res5 = dolibarr_set_const($db, "MAIN_SECURITY_MAX_ATTACHMENT_ON_FORMS", GETPOST("MAIN_SECURITY_MAX_ATTACHMENT_ON_FORMS", 'alphanohtml'), 'int', 0, '', $conf->entity); } - if ($res1 && $res2 && $res3 && $res4 && $res5) { + if (GETPOSTISSET('MAIN_SECURITY_MAX_NUMBER_FAILED_AUTH')) { + $res6 = dolibarr_set_const($db, "MAIN_SECURITY_MAX_NUMBER_FAILED_AUTH", GETPOST("MAIN_SECURITY_MAX_NUMBER_FAILED_AUTH", 'alphanohtml'), 'int', 0, '', $conf->entity); + } + if ($res1 && $res2 && $res3 && $res4 && $res5 && $res6) { setEventMessages($langs->trans("RecordModifiedSuccessfully"), null, 'mesgs'); } } diff --git a/htdocs/admin/sms.php b/htdocs/admin/sms.php index dbfb0e7a8e9..ad815dc5bc8 100644 --- a/htdocs/admin/sms.php +++ b/htdocs/admin/sms.php @@ -1,7 +1,7 @@ - * Copyright (C) 2009 Regis Houssin - * Copyright (C) 2013 Juanjo Menent +/* Copyright (C) 2007-2011 Laurent Destailleur + * Copyright (C) 2009 Regis Houssin + * Copyright (C) 2013 Juanjo Menent * Copyright (C) 2020-2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -83,10 +83,10 @@ if ($action == 'send' && !$cancel) { } $sendto = GETPOST("sendto", 'alphanohtml'); $body = GETPOST('message', 'alphanohtml'); - $deliveryreceipt = GETPOST("deliveryreceipt", 'alphanohtml'); - $deferred = GETPOST('deferred', 'alphanohtml'); - $priority = GETPOST('priority', 'alphanohtml'); - $class = GETPOST('class', 'alphanohtml'); + $deliveryreceipt = GETPOSTINT("deliveryreceipt"); + $deferred = GETPOSTINT('deferred'); + $priority = GETPOSTINT('priority'); + $class = GETPOSTINT('class'); $errors_to = GETPOST("errorstosms", 'alphanohtml'); // Create form object diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index 258fd52e511..7e87218c977 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -371,7 +371,7 @@ print "
'.$langs->trans("StockOnReception").''; @@ -386,7 +386,7 @@ if (isModEnabled("reception")) { print "
'.$langs->trans("StockOnReceptionOnClosing").''; diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index b0f657e9411..2861b0fce9b 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -38,6 +38,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/events.class.php'; * @var HookManager $hookmanager * @var Translate $langs * @var User $user + * + * @var string[] $arrayofstreamtodisable // $arrayofstreamtodisable is defined into filefunc.inc.php + * @var string $conffile // $conffile is defined into filefunc.inc.php */ // Load translation files required by the page diff --git a/htdocs/asset/card.php b/htdocs/asset/card.php index 9531347d580..9b6e857f8fa 100644 --- a/htdocs/asset/card.php +++ b/htdocs/asset/card.php @@ -132,7 +132,7 @@ if (empty($reshook)) { // Action dispose object if ($action == 'confirm_disposal' && $confirm == 'yes' && $permissiontoadd) { - $object->disposal_date = dol_mktime(12, 0, 0, GETPOSTINT('disposal_datemonth'), GETPOSTINT('disposal_dateday'), GETPOSTINT('disposal_dateyear')); // for date without hour, we use gmt + $object->disposal_date = dol_mktime(0, 0, 0, GETPOSTINT('disposal_datemonth'), GETPOSTINT('disposal_dateday'), GETPOSTINT('disposal_dateyear'), 'gmt'); // for date without hour, we use gmt $object->disposal_amount_ht = GETPOSTINT('disposal_amount'); $object->fk_disposal_type = GETPOSTINT('fk_disposal_type'); $disposal_invoice_id = GETPOSTINT('disposal_invoice_id'); @@ -273,7 +273,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Disposal $langs->load('bills'); - $disposal_date = dol_mktime(12, 0, 0, GETPOSTINT('disposal_datemonth'), GETPOSTINT('disposal_dateday'), GETPOSTINT('disposal_dateyear')); // for date without hour, we use gmt + $disposal_date = dol_mktime(0, 0, 0, GETPOSTINT('disposal_datemonth'), GETPOSTINT('disposal_dateday'), GETPOSTINT('disposal_dateyear'), 'gmt'); // for date without hour, we use gmt $disposal_amount = GETPOSTINT('disposal_amount'); $fk_disposal_type = GETPOSTINT('fk_disposal_type'); $disposal_invoice_id = GETPOSTINT('disposal_invoice_id'); diff --git a/htdocs/asset/class/assetdepreciationoptions.class.php b/htdocs/asset/class/assetdepreciationoptions.class.php index 33bbb0f28cb..ecd6d276726 100644 --- a/htdocs/asset/class/assetdepreciationoptions.class.php +++ b/htdocs/asset/class/assetdepreciationoptions.class.php @@ -262,7 +262,7 @@ class AssetDepreciationOptions extends CommonObject if (in_array($field_info['type'], array('text', 'html'))) { $value = GETPOST($html_name, 'restricthtml'); } elseif ($field_info['type'] == 'date') { - $value = dol_mktime(12, 0, 0, GETPOSTINT($html_name . 'month'), GETPOSTINT($html_name . 'day'), GETPOSTINT($html_name . 'year')); // for date without hour, we use gmt + $value = dol_mktime(0, 0, 0, GETPOSTINT($html_name . 'month'), GETPOSTINT($html_name . 'day'), GETPOSTINT($html_name . 'year'), 'gmt'); // for date without hour, we use gmt } elseif ($field_info['type'] == 'datetime') { $value = dol_mktime(GETPOSTINT($html_name . 'hour'), GETPOSTINT($html_name . 'min'), GETPOSTINT($html_name . 'sec'), GETPOSTINT($html_name . 'month'), GETPOSTINT($html_name . 'day'), GETPOSTINT($html_name . 'year'), 'tzuserrel'); } elseif ($field_info['type'] == 'duration') { diff --git a/htdocs/asset/tpl/depreciation_options_view.tpl.php b/htdocs/asset/tpl/depreciation_options_view.tpl.php index 7b35097b4c6..0f0a28adf63 100644 --- a/htdocs/asset/tpl/depreciation_options_view.tpl.php +++ b/htdocs/asset/tpl/depreciation_options_view.tpl.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 MDW +/* Copyright (C) 2021 Open-Dsi + * Copyright (C) 2024 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -30,6 +30,7 @@ * @var Form $form * @var HookManager $hookmanager * @var AssetDepreciationOptions $assetdepreciationoptions + * @var Translate $langs */ ' @phan-var-force ?Form $form diff --git a/htdocs/asset/tpl/depreciation_view.tpl.php b/htdocs/asset/tpl/depreciation_view.tpl.php index 9fcf366ae3f..c0a6d3e1e91 100644 --- a/htdocs/asset/tpl/depreciation_view.tpl.php +++ b/htdocs/asset/tpl/depreciation_view.tpl.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 MDW +/* Copyright (C) 2021 Open-Dsi + * Copyright (C) 2024 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -27,8 +27,13 @@ */ /** + * @var AssetDepreciationOptions $assetdepreciationoptions + * @var DoliDB $db * @var Form $form * @var HookManager $hookmanager + * @var Translate $langs + * + * @var string $action */ // Protection to avoid direct call of template diff --git a/htdocs/blockedlog/admin/blockedlog_list.php b/htdocs/blockedlog/admin/blockedlog_list.php index 95da9f8f9ee..01cb2c58f1c 100644 --- a/htdocs/blockedlog/admin/blockedlog_list.php +++ b/htdocs/blockedlog/admin/blockedlog_list.php @@ -80,7 +80,7 @@ $search_end = -1; if (GETPOST('search_endyear') != '') { $search_end = dol_mktime(23, 59, 59, $search_endmonth, $search_endday, $search_endyear); } -$search_code = GETPOST('search_code', 'alpha'); +$search_code = GETPOST('search_code', 'array:alpha'); $search_ref = GETPOST('search_ref', 'alpha'); $search_amount = GETPOST('search_amount', 'alpha'); @@ -138,7 +138,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_fk_user = ''; $search_start = -1; $search_end = -1; - $search_code = ''; + $search_code = array(); $search_ref = ''; $search_amount = ''; $search_showonlyerrors = 0; @@ -496,15 +496,13 @@ print ''; -print $form->selectarray('search_code', $block_static->trackedevents, $search_code, 1, 0, 0, '', 1, 0, 0, 'ASC', 'maxwidth150', 1); +//print $form->selectarray('search_code', $block_static->trackedevents, $search_code, 1, 0, 0, '', 1, 0, 0, 'ASC', 'maxwidth150', 1); +print $form->multiselectarray('search_code', $block_static->trackedevents, $search_code, 0, 0, 'maxwidth150', 1); print ''; - print ''; // $object_link can be a ''; - // Amount print ''.price($block->amounts).''; + //print ''; if (!$checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror)) { // If error if ($checkresult[$block->id]) { print $form->textwithpicto('', $langs->trans('OkCheckFingerprintValidityButChainIsKo')); + } else { + //print $form->textwithpicto('', $langs->trans('KoCheckFingerprintValidity')); } + } else { + //print $form->textwithpicto('', $langs->trans('DataOfArchivedEventHelp2')); } if (getDolGlobalString('BLOCKEDLOG_USE_REMOTE_AUTHORITY') && getDolGlobalString('BLOCKEDLOG_AUTHORITY_URL')) { @@ -681,6 +680,12 @@ if (is_array($blocks)) { } print ''; + print ''; // $object_link can be a ''; + // Action column if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print ''; diff --git a/htdocs/blockedlog/class/blockedlog.class.php b/htdocs/blockedlog/class/blockedlog.class.php index ef209ae6b85..c959800cef7 100644 --- a/htdocs/blockedlog/class/blockedlog.class.php +++ b/htdocs/blockedlog/class/blockedlog.class.php @@ -169,7 +169,7 @@ class BlockedLog // Customer Invoice/Facture / Payment if (isModEnabled('invoice')) { $this->trackedevents['BILL_VALIDATE'] = 'logBILL_VALIDATE'; - $this->trackedevents['BILL_DELETE'] = 'logBILL_DELETE'; + //$this->trackedevents['BILL_UPDATE'] = 'logBILL_UPDATE'; $this->trackedevents['BILL_SENTBYMAIL'] = 'logBILL_SENTBYMAIL'; $this->trackedevents['DOC_DOWNLOAD'] = 'BlockedLogBillDownload'; $this->trackedevents['DOC_PREVIEW'] = 'BlockedLogBillPreview'; @@ -532,7 +532,8 @@ class BlockedLog continue; // Discard some properties } if (!in_array($key, array( - 'ref', 'ref_client', 'ref_supplier', 'date', 'datef', 'datev', 'type', 'total_ht', 'total_tva', 'total_ttc', 'localtax1', 'localtax2', 'revenuestamp', 'datepointoftax', 'note_public', 'lines' + 'ref', 'ref_client', 'ref_supplier', 'date', 'datef', 'datev', 'type', 'total_ht', 'total_tva', 'total_ttc', 'localtax1', 'localtax2', 'revenuestamp', 'datepointoftax', 'note_public', 'lines', + 'module_source', 'pos_source' ))) { continue; // Discard if not into a dedicated list } @@ -542,7 +543,13 @@ class BlockedLog $lineid++; foreach ($tmpline as $keyline => $valueline) { if (!in_array($keyline, array( - 'ref', 'multicurrency_code', 'multicurrency_total_ht', 'multicurrency_total_tva', 'multicurrency_total_ttc', 'qty', 'product_type', 'product_label', 'vat_src_code', 'tva_tx', 'info_bits', 'localtax1_tx', 'localtax2_tx', 'total_ht', 'total_tva', 'total_ttc', 'total_localtax1', 'total_localtax2' + 'ref', 'product_type', 'product_label', + 'qty', + 'subprice', + 'vat_src_code', 'tva_tx', 'localtax1_tx', 'localtax2_tx', + 'total_ht', 'total_tva', 'total_ttc', 'total_localtax1', 'total_localtax2', + 'multicurrency_code', 'multicurrency_total_ht', 'multicurrency_total_tva', 'multicurrency_total_ttc', + 'info_bits', 'special_code', ))) { continue; // Discard if not into a dedicated list } @@ -846,12 +853,12 @@ class BlockedLog */ public function dolEncodeBlockedData($data, $mode = 0) { + $aaa = ''; try { $aaa = json_encode($data); } catch (Exception $e) { - //print $e->getErrs); + // print $e->getErrs); } - //var_dump($aaa); return $aaa; } @@ -866,12 +873,12 @@ class BlockedLog */ public function dolDecodeBlockedData($data, $mode = 0) { + $aaa = null; try { $aaa = (object) jsonOrUnserialize($data); } catch (Exception $e) { - //print $e->getErrs); + // print $e->getErrs); } - //var_dump($aaa); return $aaa; } @@ -901,12 +908,10 @@ class BlockedLog */ public function create($user, $forcesignature = '') { - global $conf, $langs, $hookmanager; + global $conf, $langs; $langs->load('blockedlog'); - $error = 0; - // Clean data $this->amounts = (float) $this->amounts; @@ -941,9 +946,9 @@ class BlockedLog $this->db->begin(); - $previoushash = $this->getPreviousHash(1, 0); // This get last record and lock database until insert is done + $previoushash = $this->getPreviousHash(1, 0); // This get last record and lock database until insert is done and transaction closed - $keyforsignature = $this->buildKeyForSignature(); + $keyforsignature = $this->buildKeyForSignature(); // All the information for the has (meta data + data saved) include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php'; @@ -1142,18 +1147,18 @@ class BlockedLog /** * Return array of log objects (with criteria) * - * @param string $element element to search - * @param int $fk_object id of object to search - * @param int<0,max> $limit max number of element, 0 for all - * @param string $sortfield sort field - * @param string $sortorder sort order - * @param int $search_fk_user id of user(s) - * @param int $search_start start time limit - * @param int $search_end end time limit - * @param string $search_ref search ref - * @param string $search_amount search amount - * @param string $search_code search code - * @return BlockedLog[]|int<-2,-1> Array of object log or <0 if error + * @param string $element element to search + * @param int $fk_object id of object to search + * @param int<0,max> $limit max number of element, 0 for all + * @param string $sortfield sort field + * @param string $sortorder sort order + * @param int $search_fk_user id of user(s) + * @param int $search_start start time limit + * @param int $search_end end time limit + * @param string $search_ref search ref + * @param string $search_amount search amount + * @param string|string[] $search_code search code + * @return BlockedLog[]|int<-2,-1> Array of object log or <0 if error */ public function getLog($element, $fk_object, $limit = 0, $sortfield = '', $sortorder = '', $search_fk_user = -1, $search_start = -1, $search_end = -1, $search_ref = '', $search_amount = '', $search_code = '') { @@ -1195,8 +1200,14 @@ class BlockedLog if ($search_amount != '') { $sql .= natural_search("amounts", $search_amount, 1); } - if ($search_code != '' && $search_code != '-1') { - $sql .= natural_search("action", $search_code, 3); + if (is_array($search_code)) { + if (!empty($search_code)) { + $sql .= natural_search("action", implode(',', $search_code), 3); + } + } else { + if ($search_code != '' && $search_code != '-1') { + $sql .= natural_search("action", $search_code, 3); + } } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/bom/tpl/objectline_edit.tpl.php b/htdocs/bom/tpl/objectline_edit.tpl.php index 4ae80f95915..48fa81082b1 100644 --- a/htdocs/bom/tpl/objectline_edit.tpl.php +++ b/htdocs/bom/tpl/objectline_edit.tpl.php @@ -1,13 +1,13 @@ - * Copyright (C) 2010-2012 Laurent Destailleur - * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2012 Cédric Salvador - * Copyright (C) 2012-2014 Raphaël Doursenaud - * Copyright (C) 2013 Florian Henry - * Copyright (C) 2018 Frédéric France - * Copyright (C) 2024 Vincent Maury - * Copyright (C) 2024 MDW +/* Copyright (C) 2010-2012 Regis Houssin + * Copyright (C) 2010-2012 Laurent Destailleur + * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2012 Cédric Salvador + * Copyright (C) 2012-2014 Raphaël Doursenaud + * Copyright (C) 2013 Florian Henry + * Copyright (C) 2018-2024 Frédéric France + * Copyright (C) 2024 Vincent Maury + * Copyright (C) 2024 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 @@ -34,7 +34,19 @@ */ require_once DOL_DOCUMENT_ROOT."/product/class/html.formproduct.class.php"; - +/** + * @var BOMLine $line + * @var CommonObject $this + * @var CommonObject $object + * @var HookManager $hookmanager + * @var Societe $buyer + * @var Societe $seller + * @var Translate $langs + * + * @var string $action + * @var int $i + * @var bool $var + */ // Protection to avoid direct call of template if (empty($object) || !is_object($object)) { diff --git a/htdocs/bom/tpl/objectline_view.tpl.php b/htdocs/bom/tpl/objectline_view.tpl.php index 1c2c615a138..def20558866 100644 --- a/htdocs/bom/tpl/objectline_view.tpl.php +++ b/htdocs/bom/tpl/objectline_view.tpl.php @@ -45,6 +45,7 @@ * * @var int $i * @var int $num + * @var string $action */ ' @phan-var-force CommonObjectLine $line diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index e7f8a9b1139..010f405e549 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -1546,8 +1546,8 @@ if ($action == 'create') { $listofuserid[$firstelem['id']]['transparency'] = (GETPOSTISSET('transparency') ? GETPOST('transparency', 'alpha') : 0); // 0 by default when refreshing } } - print '
'; - print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, array(), 0, '', array(), 0, 0, 0, 'AND u.statut != 0', 1, $listofuserid, $listofcontactid, $listofotherid); + print '
'; + print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, array(), 0, '', array(), 0, 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid); print '
'; print '
'; + $text .= '
'; $tooltip = $langs->trans("GenericMaskCodes", $langs->transnoentities("Asset"), $langs->transnoentities("Asset")); $tooltip .= $langs->trans("GenericMaskCodes2"); @@ -81,7 +81,7 @@ class mod_asset_advanced extends ModeleNumRefAsset // Parametrage du prefix $text .= ''; - $text .= ''; + $text .= ''; $text .= ''; diff --git a/htdocs/core/modules/barcode/mod_barcode_product_standard.php b/htdocs/core/modules/barcode/mod_barcode_product_standard.php index 944e244fd17..ca5c3b7a3e0 100644 --- a/htdocs/core/modules/barcode/mod_barcode_product_standard.php +++ b/htdocs/core/modules/barcode/mod_barcode_product_standard.php @@ -95,7 +95,7 @@ class mod_barcode_product_standard extends ModeleNumRefBarCode // Mask parameter //$texte.= ''; $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; $texte .= ''; diff --git a/htdocs/core/modules/barcode/mod_barcode_thirdparty_standard.php b/htdocs/core/modules/barcode/mod_barcode_thirdparty_standard.php index 9cb371267b6..cf3cb3135a4 100644 --- a/htdocs/core/modules/barcode/mod_barcode_thirdparty_standard.php +++ b/htdocs/core/modules/barcode/mod_barcode_thirdparty_standard.php @@ -131,7 +131,7 @@ class mod_barcode_thirdparty_standard extends ModeleNumRefBarCode // Mask parameter //$texte.= ''; $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; $texte .= ''; diff --git a/htdocs/core/modules/bom/mod_bom_advanced.php b/htdocs/core/modules/bom/mod_bom_advanced.php index 18cbfa0cdb6..bc3ef9a72ff 100644 --- a/htdocs/core/modules/bom/mod_bom_advanced.php +++ b/htdocs/core/modules/bom/mod_bom_advanced.php @@ -82,7 +82,7 @@ class mod_bom_advanced extends ModeleNumRefBoms // Parametrage du prefix $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; diff --git a/htdocs/core/modules/cheque/mod_chequereceipt_thyme.php b/htdocs/core/modules/cheque/mod_chequereceipt_thyme.php index c03e67d6687..848b3ccbace 100644 --- a/htdocs/core/modules/cheque/mod_chequereceipt_thyme.php +++ b/htdocs/core/modules/cheque/mod_chequereceipt_thyme.php @@ -76,7 +76,7 @@ class mod_chequereceipt_thyme extends ModeleNumRefChequeReceipts // Parametrage du prefix $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php index 9a371ccb0a2..6f70914d9f7 100644 --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php @@ -200,10 +200,7 @@ class pdf_eratosthene extends ModelePDFCommandes $nblines = (is_array($object->lines) ? count($object->lines) : 0); - $hidetop = 0; - if (getDolGlobalString('MAIN_PDF_DISABLE_COL_HEAD_TITLE')) { - $hidetop = getDolGlobalString('MAIN_PDF_DISABLE_COL_HEAD_TITLE'); - } + $hidetop = getDolGlobalInt('MAIN_PDF_DISABLE_COL_HEAD_TITLE'); // Loop on each lines to detect if there is at least one image to show $realpatharray = array(); @@ -366,6 +363,10 @@ class pdf_eratosthene extends ModelePDFCommandes $tab_top = 90 + $top_shift + $shipp_shift; $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift : 10); + if (!$hidetop && getDolGlobalInt('MAIN_PDF_ENABLE_COL_HEAD_TITLE_REPEAT')) { + // TODO : make this hidden conf the default behavior for each PDF when each PDF managed this new Display + $tab_top_newpage+= $this->tabTitleHeight; + } $tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext; @@ -549,7 +550,24 @@ class pdf_eratosthene extends ModelePDFCommandes $pageposbeforeprintlines = $pdf->getPage(); $pagenb = $pageposbeforeprintlines; for ($i = 0; $i < $nblines; $i++) { + $linePosition = $i + 1; $curY = $nexY; + + // in First Check line page break and add page if needed + if (isset($object->lines[$i]->pagebreak) && $object->lines[$i]->pagebreak) { + // New page + $pdf->AddPage(); + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); + } + + $pdf->setPage($pdf->getNumPages()); + $nexY = $tab_top_newpage; + } + + $this->resetAfterColsLinePositionsData($nexY, $pdf->getPage()); + + $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage $pdf->SetTextColor(0, 0, 0); @@ -560,114 +578,76 @@ class pdf_eratosthene extends ModelePDFCommandes } $pdf->setTopMargin($tab_top_newpage); - $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. $pageposbefore = $pdf->getPage(); + $curYBefore = $curY; - - $showpricebeforepagebreak = 1; + // Allows data in the first page if description is long enough to break in multiples pages + $showpricebeforepagebreak = getDolGlobalInt('MAIN_PDF_DATA_ON_FIRST_PAGE'); $posYAfterImage = 0; - $posYAfterDescription = 0; if ($this->getColumnStatus('photo')) { // We start with Photo of product line - if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // If photo too high, we moved completely on new page + $imageTopMargin = 1; + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imageTopMargin + $imglinesize['height']) > ($this->page_hauteur - $heightforfooter)) { // If photo too high, we moved completely on new page $pdf->AddPage('', '', true); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); } $pdf->setPage($pageposbefore + 1); - + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. $curY = $tab_top_newpage; - - // Allows data in the first page if description is long enough to break in multiples pages - if (getDolGlobalInt('MAIN_PDF_DATA_ON_FIRST_PAGE')) { - $showpricebeforepagebreak = 1; - } else { - $showpricebeforepagebreak = 0; - } + $showpricebeforepagebreak = 0; } + // I remove the line commented below because it probably uselesss (or bug source) no need to change bottom margin because we have checked image fit + //$pdf->setPageOrientation('', 0, $heightforfooter + $heightforfreetext); // The only function to edit the bottom margin of current page to set it. + if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { - $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + $imageTopMargin, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually $posYAfterImage = $curY + $imglinesize['height']; + $this->setAfterColsLinePositionsData('photo', $posYAfterImage, $pdf->getPage()); } } + // restore Page orientation for text + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. + // Description of product line if ($this->getColumnStatus('desc')) { - $pdf->startTransaction(); - $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); - $pageposafter = $pdf->getPage(); - - if ($pageposafter > $pageposbefore) { // There is a pagebreak - $pdf->rollbackTransaction(true); - $pageposafter = $pageposbefore; - //print $pageposafter.'-'.$pageposbefore;exit; - $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. - - $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); - $pageposafter = $pdf->getPage(); - $posyafter = $pdf->GetY(); - if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text - if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page - $pdf->AddPage('', '', true); - if (!empty($tplidx)) { - $pdf->useTemplate($tplidx); - } - $pdf->setPage($pageposafter + 1); - } - } else { - // We found a page break - // Allows data in the first page if description is long enough to break in multiples pages - if (getDolGlobalInt('MAIN_PDF_DATA_ON_FIRST_PAGE')) { - $showpricebeforepagebreak = 1; - } else { - $showpricebeforepagebreak = 0; - } - } - } else { // No pagebreak - $pdf->commitTransaction(); - } - $posYAfterDescription = $pdf->GetY(); + $this->setAfterColsLinePositionsData('desc', $pdf->GetY(), $pdf->getPage()); } - - $nexY = max($pdf->GetY(), $posYAfterImage); - - - $pageposafter = $pdf->getPage(); - + $afterPosData = $this->getMaxAfterColsLinePositionsData(); $pdf->setPage($pageposbefore); $pdf->setTopMargin($this->marge_haute); - $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', 0, $heightforfooter); // The only function to edit the bottom margin of current page to set it. // We suppose that a too long description or photo were moved completely on next page - if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { - $pdf->setPage($pageposafter); + if ($afterPosData['page'] > $pageposbefore && (empty($showpricebeforepagebreak) || ($curY + 4) > ($this->page_hauteur - $heightforfooter))) { + $pdf->setPage($afterPosData['page']); $curY = $tab_top_newpage; } $pdf->SetFont('', '', $default_font_size - 1); // We reposition the default font - // # of line + // Line position if ($this->getColumnStatus('position')) { - $this->printStdColumnContent($pdf, $curY, 'position', (string) ($i + 1)); + $this->printStdColumnContent($pdf, $curY, 'position', strval($linePosition)); } // VAT Rate if ($this->getColumnStatus('vat')) { $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate); - $nexY = max($pdf->GetY(), $nexY); } // Unit price before discount if ($this->getColumnStatus('subprice')) { $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax); - $nexY = max($pdf->GetY(), $nexY); } // Quantity @@ -675,7 +655,6 @@ class pdf_eratosthene extends ModelePDFCommandes if ($this->getColumnStatus('qty')) { $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'qty', $qty); - $nexY = max($pdf->GetY(), $nexY); } @@ -683,28 +662,24 @@ class pdf_eratosthene extends ModelePDFCommandes if ($this->getColumnStatus('unit')) { $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'unit', $unit); - $nexY = max($pdf->GetY(), $nexY); } // Discount on line if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) { $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent); - $nexY = max($pdf->GetY(), $nexY); } // Total excl tax line (HT) if ($this->getColumnStatus('totalexcltax')) { $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax); - $nexY = max($pdf->GetY(), $nexY); } // Total with tax line (TTC) if ($this->getColumnStatus('totalincltax')) { $total_incl_tax = pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'totalincltax', $total_incl_tax); - $nexY = max($pdf->GetY(), $nexY); } // Extrafields @@ -713,17 +688,18 @@ class pdf_eratosthene extends ModelePDFCommandes if ($this->getColumnStatus($extrafieldColKey)) { $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey, $outputlangs); $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); - $nexY = max($pdf->GetY(), $nexY); + $this->setAfterColsLinePositionsData('options_'.$extrafieldColKey, $pdf->GetY(), $pdf->getPage()); } } } + $afterPosData = $this->getMaxAfterColsLinePositionsData(); $parameters = array( 'object' => $object, 'i' => $i, 'pdf' => & $pdf, 'curY' => & $curY, - 'nexY' => & $nexY, + 'nexY' => & $afterPosData['y'], // for backward module hook compatibility Y will be accessible by $object->getMaxAfterColsLinePositionsData() 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails ); @@ -785,60 +761,86 @@ class pdf_eratosthene extends ModelePDFCommandes } $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate' => $vatrate, 'vatcode' => $vatcode, 'amount' => $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne); + $afterPosData = $this->getMaxAfterColsLinePositionsData(); + $pdf->setPage($afterPosData['page']); + $nexY = $afterPosData['y']; + // Add line - if (getDolGlobalInt('MAIN_PDF_DASH_BETWEEN_LINES') && $i < ($nblines - 1)) { - $pdf->setPage($pageposafter); + if (getDolGlobalString('MAIN_PDF_DASH_BETWEEN_LINES') && $i < ($nblines - 1) && $afterPosData['y'] < $this->page_hauteur - $heightforfooter - 5) { $pdf->SetLineStyle(array('dash' => '1,1', 'color' => array(80, 80, 80))); //$pdf->SetDrawColor(190,190,200); - $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY); + $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1); $pdf->SetLineStyle(array('dash' => 0)); } + $nexY += 2; // Add space between lines + } - // Detect if some page were added automatically and output _tableau for past pages - while ($pagenb < $pageposafter) { - $pdf->setPage($pagenb); - if ($pagenb == $pageposbeforeprintlines) { - $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis); + // Add last page for document footer if there are not enough size left + $afterPosData = $this->getMaxAfterColsLinePositionsData(); + if ($afterPosData['y'] > $this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot) ) { + $pdf->AddPage(); + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); + } + $pagenb++; + $pdf->setPage($pagenb); + } + + // Draw table frames and columns borders + $drawTabNumbPage = $pdf->getNumPages(); + for ($i=$pageposbeforeprintlines; $i<=$drawTabNumbPage; $i++) { + $pdf->setPage($i); + // reset page orientation each loop to override it if it was changed + $pdf->setPageOrientation('', 0, 0); // The only function to edit the bottom margin of current page to set it. + + $drawTabHideTop = $hidetop; + $drawTabTop = $tab_top_newpage; + $drawTabBottom = $this->page_hauteur - $heightforfooter;; + $hideBottom = 0; // TODO understand why it change to 1 or 0 during process + + if ($i == $pageposbeforeprintlines) { + // first page need to start after notes + $drawTabTop = $tab_top; + } elseif (!$drawTabHideTop) { + if (getDolGlobalInt('MAIN_PDF_ENABLE_COL_HEAD_TITLE_REPEAT')) { + $drawTabTop-= $this->tabTitleHeight; } else { - $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis); - } - $this->_pagefoot($pdf, $object, $outputlangs, 1); - $pagenb++; - $pdf->setPage($pagenb); - $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. - if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) { - $this->_pagehead($pdf, $object, 0, $outputlangs); - } - if (!empty($tplidx)) { - $pdf->useTemplate($tplidx); + $drawTabHideTop = 1; } } - if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { // @phan-suppress-current-line PhanUndeclaredProperty - if ($pagenb == $pageposafter) { - $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis); - } else { - $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis); - } - $this->_pagefoot($pdf, $object, $outputlangs, 1); - // New page - $pdf->AddPage(); - if (!empty($tplidx)) { - $pdf->useTemplate($tplidx); - } - $pagenb++; - if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) { - $this->_pagehead($pdf, $object, 0, $outputlangs); - } + + // last page need to include document footer + if ($i == $pdf->getNumPages()) { + // remove document footer height to tab bottom position + $drawTabBottom-= $heightforfreetext + $heightforinfotot; + } + + $drawTabHeight = $drawTabBottom - $drawTabTop; + $this->_tableau($pdf, $drawTabTop, $drawTabHeight, 0, $outputlangs, $drawTabHideTop, $hideBottom, $object->multicurrency_code, $outputlangsbis); + + $hideFreeText = $i != $pdf->getNumPages() ? 1 : 0; // Display free text only in last page + $this->_pagefoot($pdf, $object, $outputlangs, $hideFreeText); + + $pdf->setPage($i); // in case of _pagefoot or _tableau change it + + // reset page orientation each loop to override it if it was changed by _pagefoot or _tableau change it + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + + // Don't print head on first page ($pageposbeforeprintlines) because already added previously + if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') && $i != $pageposbeforeprintlines) { + $this->_pagehead($pdf, $object, 0, $outputlangs); + } + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); } } - // Show square - if ($pagenb == $pageposbeforeprintlines) { - $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code, $outputlangsbis); - } else { - $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code, $outputlangsbis); - } + // reset text color before print footers + $pdf->SetTextColor(0, 0, 0); + + $pdf->setPage($pdf->getNumPages()); + $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; // Display infos area @@ -847,16 +849,8 @@ class pdf_eratosthene extends ModelePDFCommandes // Display total zone $posy = $this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs); - // Display payment area - /* - if ($deja_regle) - { - $posy=$this->drawPaymentsTable($pdf, $object, $posy, $outputlangs); - } - */ - // Pagefoot - $this->_pagefoot($pdf, $object, $outputlangs); + // Add number of pages in footer if (method_exists($pdf, 'AliasNbPages')) { $pdf->AliasNbPages(); // @phan-suppress-current-line PhanUndeclaredMethod } diff --git a/htdocs/core/modules/commande/mod_commande_saphir.php b/htdocs/core/modules/commande/mod_commande_saphir.php index a3280fa1455..bb0603ef0f0 100644 --- a/htdocs/core/modules/commande/mod_commande_saphir.php +++ b/htdocs/core/modules/commande/mod_commande_saphir.php @@ -82,7 +82,7 @@ class mod_commande_saphir extends ModeleNumRefCommandes // Parametrage du prefix $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; diff --git a/htdocs/core/modules/contract/mod_contract_magre.php b/htdocs/core/modules/contract/mod_contract_magre.php index 7af0d9e16bb..e872357c63c 100644 --- a/htdocs/core/modules/contract/mod_contract_magre.php +++ b/htdocs/core/modules/contract/mod_contract_magre.php @@ -73,7 +73,7 @@ class mod_contract_magre extends ModelNumRefContracts $tooltip .= '
'.$langs->trans("GenericMaskCodes5b"); $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; $texte .= ''; $texte .= '
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).' 
'.$langs->trans("Mask").' ('.$langs->trans("BarCodeModel").'):
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).' 
'.$langs->trans("Mask").' ('.$langs->trans("BarCodeModel").'):
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).' 
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).' 
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).' 
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).' 
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).' 
'; diff --git a/htdocs/core/modules/delivery/mod_delivery_saphir.php b/htdocs/core/modules/delivery/mod_delivery_saphir.php index 60cbc9420ab..f09c8764d7a 100644 --- a/htdocs/core/modules/delivery/mod_delivery_saphir.php +++ b/htdocs/core/modules/delivery/mod_delivery_saphir.php @@ -87,7 +87,7 @@ class mod_delivery_saphir extends ModeleNumRefDeliveryOrder // Parametrage du prefix $texte .= ''.$langs->trans("Mask").':'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).''; $texte .= '  '; diff --git a/htdocs/core/modules/expedition/mod_expedition_ribera.php b/htdocs/core/modules/expedition/mod_expedition_ribera.php index 30bd7abd94b..a6394c0df16 100644 --- a/htdocs/core/modules/expedition/mod_expedition_ribera.php +++ b/htdocs/core/modules/expedition/mod_expedition_ribera.php @@ -83,7 +83,7 @@ class mod_expedition_ribera extends ModelNumRefExpedition $tooltip .= '
'.$langs->trans("GenericMaskCodes5b"); $texte .= ''.$langs->trans("Mask").':'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).''; $texte .= '  '; $texte .= ''; $texte .= ''; diff --git a/htdocs/core/modules/expensereport/mod_expensereport_sand.php b/htdocs/core/modules/expensereport/mod_expensereport_sand.php index 0c5962c871e..6f4f091f90e 100644 --- a/htdocs/core/modules/expensereport/mod_expensereport_sand.php +++ b/htdocs/core/modules/expensereport/mod_expensereport_sand.php @@ -87,7 +87,7 @@ class mod_expensereport_sand extends ModeleNumRefExpenseReport // Parametrage du prefix $texte .= ''.$langs->trans("Mask").':'; $mask = getDolGlobalString('EXPENSEREPORT_SAND_MASK'); - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).''; $texte .= '  '; diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index 0fdcf740020..a5c514576e1 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -102,7 +102,7 @@ class pdf_crabe extends ModelePDFFactures */ public function __construct($db) { - global $conf, $langs, $mysoc; + global $langs, $mysoc; // Translations $langs->loadLangs(array("main", "bills")); @@ -359,10 +359,10 @@ class pdf_crabe extends ModelePDFFactures $certprivate = empty($user->conf->CERTIFICATE_CRT_PRIVATE) ? '' : $user->conf->CERTIFICATE_CRT_PRIVATE; // If user has no certificate, we try to take the company one if (!$cert) { - $cert = !getDolGlobalString('CERTIFICATE_CRT') ? '' : $conf->global->CERTIFICATE_CRT; + $cert = getDolGlobalString('CERTIFICATE_CRT'); } if (!$certprivate) { - $certprivate = !getDolGlobalString('CERTIFICATE_CRT_PRIVATE') ? '' : $conf->global->CERTIFICATE_CRT_PRIVATE; + $certprivate = getDolGlobalString('CERTIFICATE_CRT_PRIVATE'); } // If a certificate is found if ($cert) { @@ -1162,7 +1162,7 @@ class pdf_crabe extends ModelePDFFactures protected function _tableau_info(&$pdf, $object, $posy, $outputlangs, $outputlangsbis) { // phpcs:enable - global $conf, $mysoc, $hookmanager; + global $mysoc, $hookmanager; $default_font_size = pdf_getPDFFontSize($outputlangs); @@ -1170,6 +1170,9 @@ class pdf_crabe extends ModelePDFFactures krsort($this->tva_array); + // Clean data type + $object->total_tva = (float) $object->total_tva; + // Show VAT details if ($object->total_tva != 0 && getDolGlobalInt('PDF_INVOICE_SHOW_VAT_ANALYSIS')) { $pdf->SetFillColor(224, 224, 224); @@ -1227,16 +1230,19 @@ class pdf_crabe extends ModelePDFFactures } } - // If France, show VAT mention if not applicable - if ($this->emetteur->country_code == 'FR' && empty($object->total_tva) && (empty($mysoc->tva_assuj) || ($this->emetteur->isInEEC() && $object->thirdparty->isInEEC()))) { - $pdf->SetFont('', 'B', $default_font_size - 2); + // If France, show VAT mention if applicable + if (in_array($this->emetteur->country_code, array('FR')) && empty($object->total_tva)) { + $pdf->SetFont('', '', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); - if ($mysoc->forme_juridique_code == 92) { - $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoiceAsso"), 0, 'L', 0); - } else { - $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0); + if (empty($mysoc->tva_assuj)) { + if ($mysoc->forme_juridique_code == 92) { + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoiceAsso"), 0, 'L', 0); + } else { + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0); + } + } elseif (getDolGlobalString("INVOICE_VAT_SHOW_REVERSE_CHARGE_MENTION") && $this->emetteur->country_code != $object->thirdparty->country_code && $this->emetteur->isInEEC() && $object->thirdparty->isInEEC()) { + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedReverseChargeProcedure"), 0, 'L', 0); } - $posy = $pdf->GetY() + 4; } @@ -1367,7 +1373,7 @@ class pdf_crabe extends ModelePDFFactures if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') { // If payment mode unregulated or payment mode forced to CHQ if (getDolGlobalInt('FACTURE_CHQ_NUMBER')) { - $diffsizetitle = (!getDolGlobalString('PDF_DIFFSIZE_TITLE') ? 3 : $conf->global->PDF_DIFFSIZE_TITLE); + $diffsizetitle = getDolGlobalInt('PDF_DIFFSIZE_TITLE', 3); if (getDolGlobalInt('FACTURE_CHQ_NUMBER') > 0) { $account = new Account($this->db); @@ -1385,7 +1391,7 @@ class pdf_crabe extends ModelePDFFactures $posy = $pdf->GetY() + 2; } } - if ($conf->global->FACTURE_CHQ_NUMBER == -1) { + if (getDolGlobalInt('FACTURE_CHQ_NUMBER') == -1) { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle); $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0); @@ -1404,7 +1410,7 @@ class pdf_crabe extends ModelePDFFactures // If payment mode not forced or forced to VIR, show payment with BAN if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') { if ($object->fk_account > 0 || $object->fk_bank > 0 || getDolGlobalInt('FACTURE_RIB_NUMBER')) { - $bankid = ($object->fk_account <= 0 ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account); + $bankid = ($object->fk_account <= 0 ? getDolGlobalString('FACTURE_RIB_NUMBER') : $object->fk_account); if ($object->fk_bank > 0) { $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank } @@ -1828,7 +1834,7 @@ class pdf_crabe extends ModelePDFFactures $index++; $index++; $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); - $pdf->MultiCell($col2x - $col1x, $tab2_hl, $conf->global->BILL_TEXT_TOTAL_FOOTER, 0, 'L', 0); + $pdf->MultiCell($col2x - $col1x, $tab2_hl, getDolGlobalString('BILL_TEXT_TOTAL_FOOTER'), 0, 'L', 0); } return ($tab2_top + ($tab2_hl * $index)); @@ -1877,7 +1883,6 @@ class pdf_crabe extends ModelePDFFactures $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4); $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre); - //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) { $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, $this->corner_radius, '1001', 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); } diff --git a/htdocs/core/modules/facture/doc/pdf_octopus.modules.php b/htdocs/core/modules/facture/doc/pdf_octopus.modules.php index 06fa8d0c9d5..6c75e61ae9c 100644 --- a/htdocs/core/modules/facture/doc/pdf_octopus.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_octopus.modules.php @@ -1329,7 +1329,7 @@ class pdf_octopus extends ModelePDFFactures */ protected function drawInfoTable(&$pdf, $object, $posy, $outputlangs, $outputlangsbis) { - global $conf, $mysoc, $hookmanager; + global $mysoc, $hookmanager; $default_font_size = pdf_getPDFFontSize($outputlangs); @@ -1337,6 +1337,9 @@ class pdf_octopus extends ModelePDFFactures krsort($this->tva_array); + // Clean data type + $object->total_tva = (float) $object->total_tva; + // Show VAT details if ($object->total_tva != 0 && getDolGlobalInt('PDF_INVOICE_SHOW_VAT_ANALYSIS')) { $pdf->SetFillColor(224, 224, 224); @@ -1394,16 +1397,19 @@ class pdf_octopus extends ModelePDFFactures } } - // If France, show VAT mention if not applicable - if ($this->emetteur->country_code == 'FR' && empty($object->total_tva) && (empty($mysoc->tva_assuj) || ($this->emetteur->isInEEC() && $object->thirdparty->isInEEC()))) { - $pdf->SetFont('', 'B', $default_font_size - 2); + // If France, show VAT mention if applicable + if (in_array($this->emetteur->country_code, array('FR')) && empty($object->total_tva)) { + $pdf->SetFont('', '', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); - if ($mysoc->forme_juridique_code == 92) { - $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoiceAsso"), 0, 'L', 0); - } else { - $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0); + if (empty($mysoc->tva_assuj)) { + if ($mysoc->forme_juridique_code == 92) { + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoiceAsso"), 0, 'L', 0); + } else { + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0); + } + } elseif (getDolGlobalString("INVOICE_VAT_SHOW_REVERSE_CHARGE_MENTION") && $this->emetteur->country_code != $object->thirdparty->country_code && $this->emetteur->isInEEC() && $object->thirdparty->isInEEC()) { + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedReverseChargeProcedure"), 0, 'L', 0); } - $posy = $pdf->GetY() + 4; } @@ -1664,7 +1670,7 @@ class pdf_octopus extends ModelePDFFactures $pdf->SetXY($col1x, $tab2_top + 0); $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHT") : ''), 0, 'L', 1); - $total_ht = ((!empty($conf->multicurrency->enabled) && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht); + $total_ht = ((isModEnabled('multicurrency') && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht); $pdf->SetXY($col2x, $tab2_top + 0); $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht, 0, $outputlangs), 0, 'R', 1); @@ -2549,7 +2555,7 @@ class pdf_octopus extends ModelePDFFactures */ public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0) { - global $conf, $hookmanager; + global $hookmanager; // Default field style for content $this->defaultContentsFieldsStyle = array( @@ -2871,7 +2877,6 @@ class pdf_octopus extends ModelePDFFactures $width = $this->page_largeur - $this->marge_gauche - $this->marge_droite - 83; - //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) { //$pdf->Rect($this->posx_cumul_anterieur - 1, $tab_top, $width, 5, 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); $pdf->RoundedRect($this->posx_cumul_anterieur - 1, $tab_top, $width, 5, $this->corner_radius, '1001', 'F', explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); @@ -3069,8 +3074,6 @@ class pdf_octopus extends ModelePDFFactures */ public function getDataSituation(&$object) { - global $conf, $db; - // Fetch previous and next situations invoices. // Return all previous and next invoices (both standard and credit notes) $object->fetchPreviousNextSituationInvoice(); @@ -3233,7 +3236,6 @@ class pdf_octopus extends ModelePDFFactures return $object->displayRetainedWarranty(); } else { // FOR RETROCOMPATIBILITY - global $conf; // TODO : add a flag on invoices to store this conf USE_RETAINED_WARRANTY_ONLY_FOR_SITUATION_FINAL @@ -3365,7 +3367,7 @@ class pdf_octopus extends ModelePDFFactures */ public function btpGetInvoiceAmounts($id, $forceReadFromDB = false) { - global $user,$langs,$conf,$mysoc,$db,$hookmanager,$nblignes; + global $user, $langs, $mysoc, $db, $hookmanager, $nblignes; $object = new Facture($db); $object->fetch($id); @@ -3517,7 +3519,7 @@ class pdf_octopus extends ModelePDFFactures if (count($propals)) { $propal = array_pop($propals); - $total_ht = ($conf->multicurrency->enabled && $propal->multicurrency_tx != 1) ? $propal->multicurrency_total_ht : $propal->total_ht; + $total_ht = (isModEnabled('multicurrency') && $propal->multicurrency_tx != 1) ? $propal->multicurrency_total_ht : $propal->total_ht; $remain_to_pay = $total_ht; $pdf->SetTextColor(0, 0, 60); @@ -3540,7 +3542,7 @@ class pdf_octopus extends ModelePDFFactures } elseif (count($orders)) { $order = array_pop($orders); - $total_ht = ($conf->multicurrency->enabled && $order->multicurrency_tx != 1 ? $order->multicurrency_total_ht : $order->total_ht); + $total_ht = (isModEnabled('multicurrency') && $order->multicurrency_tx != 1 ? $order->multicurrency_total_ht : $order->total_ht); $remain_to_pay = $total_ht; } @@ -3608,7 +3610,7 @@ class pdf_octopus extends ModelePDFFactures $pdf->SetXY($posx, $posy); $pdf->MultiCell($width, $height, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1); - $total_ht = ($conf->multicurrency->enabled && $invoice->multicurrency_tx != 1 ? $invoice->multicurrency_total_ht : $invoice->total_ht); + $total_ht = (isModEnabled('multicurrency') && $invoice->multicurrency_tx != 1 ? $invoice->multicurrency_total_ht : $invoice->total_ht); $pdf->SetXY($posx + $width, $posy); $pdf->MultiCell($width2, $height, price($sign * ($total_ht + (!empty($invoice->remise) ? $invoice->remise : 0)), 0, $outputlangs), 0, 'R', 1); @@ -3651,8 +3653,8 @@ class pdf_octopus extends ModelePDFFactures $index++; - $total_ht = ($conf->multicurrency->enabled && $invoice->multicurrency_tx != 1) ? $invoice->multicurrency_total_ht : $invoice->total_ht; - $total_ttc = ($conf->multicurrency->enabled && $invoice->multicurrency_tx != 1) ? $invoice->multicurrency_total_ttc : $invoice->total_ttc; + $total_ht = (isModEnabled('multicurrency') && $invoice->multicurrency_tx != 1) ? $invoice->multicurrency_total_ht : $invoice->total_ht; + $total_ttc = (isModEnabled('multicurrency') && $invoice->multicurrency_tx != 1) ? $invoice->multicurrency_total_ttc : $invoice->total_ttc; // Total TTC $pdf->SetXY($posx, $posy + $height * $index); diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index f4f29b0edbd..7fa776dff12 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -702,7 +702,23 @@ class pdf_sponge extends ModelePDFFactures $pageposbeforeprintlines = $pdf->getPage(); $pagenb = $pageposbeforeprintlines; for ($i = 0; $i < $nblines; $i++) { + $linePosition = $i + 1; $curY = $nexY; + + // in First Check line page break and add page if needed + if (isset($object->lines[$i]->pagebreak) && $object->lines[$i]->pagebreak) { + // New page + $pdf->AddPage(); + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); + } + + $pdf->setPage($pdf->getNumPages()); + $nexY = $this->tab_top_newpage; + } + + $this->resetAfterColsLinePositionsData($nexY, $pdf->getPage()); + $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage $pdf->SetTextColor(0, 0, 0); @@ -713,112 +729,76 @@ class pdf_sponge extends ModelePDFFactures } $pdf->setTopMargin($this->tab_top_newpage); - $page_bottom_margin = $this->heightforfooter + $this->heightforfreetext + $this->heightforinfotot + $this->getHeightForQRInvoice($pdf->getPage(), $object, $langs); - $pdf->setPageOrientation('', 1, $page_bottom_margin); + $pdf->setPageOrientation('', 1, $this->heightforfooter); $pageposbefore = $pdf->getPage(); + $curYBefore = $curY; - $showpricebeforepagebreak = 1; - $posYAfterImage = 0; - $posYAfterDescription = 0; + // Allows data in the first page if description is long enough to break in multiples pages + $showpricebeforepagebreak = getDolGlobalInt('MAIN_PDF_DATA_ON_FIRST_PAGE'); if ($this->getColumnStatus('photo')) { // We start with Photo of product line - if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - $page_bottom_margin)) { // If photo too high, we moved completely on new page + $imageTopMargin = 1; + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imageTopMargin + $imglinesize['height']) > ($this->page_hauteur - $this->heightforfooter)) { // If photo too high, we moved completely on new page $pdf->AddPage('', '', true); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); } $pdf->setPage($pageposbefore + 1); - + $pdf->setPageOrientation('', 1, $this->heightforfooter); // The only function to edit the bottom margin of current page to set it. $curY = $this->tab_top_newpage; - - // Allows data in the first page if description is long enough to break in multiples pages - if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) { - $showpricebeforepagebreak = 1; - } else { - $showpricebeforepagebreak = 0; - } + $showpricebeforepagebreak = 0; } + $pdf->setPageOrientation('', 0, $this->heightforfooter + $this->heightforfreetext); // The only function to edit the bottom margin of current page to set it. if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { - $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + $imageTopMargin, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually $posYAfterImage = $curY + $imglinesize['height']; + + $this->setAfterColsLinePositionsData('photo', $posYAfterImage, $pdf->getPage()); } } + // restore Page orientation for text + $pdf->setPageOrientation('', 1, $this->heightforfooter); // The only function to edit the bottom margin of current page to set it. + // Description of product line if ($this->getColumnStatus('desc')) { - $pdf->startTransaction(); - $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); - $pageposafter = $pdf->getPage(); - - if ($pageposafter > $pageposbefore) { // There is a pagebreak - $pdf->rollbackTransaction(true); - $pageposafter = $pageposbefore; - $pdf->setPageOrientation('', 1, $this->heightforfooter); // The only function to edit the bottom margin of current page to set it. - - $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); - - $pageposafter = $pdf->getPage(); - $posyafter = $pdf->GetY(); - //var_dump($posyafter); var_dump(($this->page_hauteur - ($this->heightforfooter+$this->heightforfreetext+$this->heightforinfotot))); exit; - if ($posyafter > ($this->page_hauteur - $page_bottom_margin)) { // There is no space left for total+free text - if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page - $pdf->AddPage('', '', true); - if (!empty($tplidx)) { - $pdf->useTemplate($tplidx); - } - $pdf->setPage($pageposafter + 1); - } - } else { - // We found a page break - // Allows data in the first page if description is long enough to break in multiples pages - if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) { - $showpricebeforepagebreak = 1; - } else { - $showpricebeforepagebreak = 0; - } - } - } else { // No pagebreak - $pdf->commitTransaction(); - } - $posYAfterDescription = $pdf->GetY(); + $this->setAfterColsLinePositionsData('desc', $pdf->GetY(), $pdf->getPage()); } - $nexY = max($pdf->GetY(), $posYAfterImage, $posYAfterDescription); - $pageposafter = $pdf->getPage(); + $afterPosData = $this->getMaxAfterColsLinePositionsData(); $pdf->setPage($pageposbefore); $pdf->setTopMargin($this->marge_haute); - $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + $curY = $curYBefore; + $pdf->setPageOrientation('', 0, $this->heightforfooter); // The only function to edit the bottom margin of current page to set it. // We suppose that a too long description or photo were moved completely on next page - if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { - $pdf->setPage($pageposafter); + if ($afterPosData['page'] > $pageposbefore && (empty($showpricebeforepagebreak) || ($curY + 4) > ($this->page_hauteur - $this->heightforfooter))) { + $pdf->setPage($afterPosData['page']); $curY = $this->tab_top_newpage; } $pdf->SetFont('', '', $default_font_size - 1); // We reposition the default font - // # of line + // Line position if ($this->getColumnStatus('position')) { - $this->printStdColumnContent($pdf, $curY, 'position', (string) ($i + 1)); + $this->printStdColumnContent($pdf, $curY, 'position', strval($linePosition)); } // VAT Rate if ($this->getColumnStatus('vat')) { $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate); - $nexY = max($pdf->GetY(), $nexY); } // Unit price before discount if ($this->getColumnStatus('subprice')) { $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax); - $nexY = max($pdf->GetY(), $nexY); } // Quantity @@ -826,42 +806,36 @@ class pdf_sponge extends ModelePDFFactures if ($this->getColumnStatus('qty')) { $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'qty', $qty); - $nexY = max($pdf->GetY(), $nexY); } // Situation progress if ($this->getColumnStatus('progress')) { $progress = pdf_getlineprogress($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'progress', $progress); - $nexY = max($pdf->GetY(), $nexY); } // Unit if ($this->getColumnStatus('unit')) { $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'unit', $unit); - $nexY = max($pdf->GetY(), $nexY); } // Discount on line if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) { $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent); - $nexY = max($pdf->GetY(), $nexY); } // Total excl tax line (HT) if ($this->getColumnStatus('totalexcltax')) { $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax); - $nexY = max($pdf->GetY(), $nexY); } // Total with tax line (TTC) if ($this->getColumnStatus('totalincltax')) { $total_incl_tax = pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'totalincltax', $total_incl_tax); - $nexY = max($pdf->GetY(), $nexY); } // Extrafields @@ -870,18 +844,19 @@ class pdf_sponge extends ModelePDFFactures if ($this->getColumnStatus($extrafieldColKey)) { $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey, $outputlangs); $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); - $nexY = max($pdf->GetY(), $nexY); + + $this->setAfterColsLinePositionsData('options_' . $extrafieldColKey, $pdf->GetY(), $pdf->getPage()); } } } - + $afterPosData = $this->getMaxAfterColsLinePositionsData(); $parameters = array( 'object' => $object, 'i' => $i, 'pdf' => & $pdf, 'curY' => & $curY, - 'nexY' => & $nexY, + 'nexY' => & $afterPosData['y'], // for backward module hook compatibility Y will be accessible by $object->getMaxAfterColsLinePositionsData() 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails ); @@ -960,7 +935,7 @@ class pdf_sponge extends ModelePDFFactures if (!isset($this->tva[$vatrate])) { $this->tva[$vatrate] = 0; } - $this->tva[$vatrate] += $tvaligne; // ->tva is abandoned, we use now ->tva_array that is more complete + $this->tva[$vatrate] += $tvaligne; // ->tva is abandoned, we use now ->tva_array that is more complete $vatcode = $object->lines[$i]->vat_src_code; if (getDolGlobalInt('PDF_INVOICE_SHOW_VAT_ANALYSIS')) { if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['tot_ht'])) { @@ -974,67 +949,91 @@ class pdf_sponge extends ModelePDFFactures $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate' => $vatrate, 'vatcode' => $vatcode, 'amount' => $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne); } - $nexY = max($nexY, $posYAfterImage); + $afterPosData = $this->getMaxAfterColsLinePositionsData(); + $pdf->setPage($afterPosData['page']); + $nexY = $afterPosData['y']; // Add line - if (getDolGlobalString('MAIN_PDF_DASH_BETWEEN_LINES') && $i < ($nblines - 1)) { - $pdf->setPage($pageposafter); + if (getDolGlobalString('MAIN_PDF_DASH_BETWEEN_LINES') && $i < ($nblines - 1) && $afterPosData['y'] < $this->page_hauteur - $this->heightforfooter - 5) { $pdf->SetLineStyle(array('dash' => '1,1', 'color' => array(80, 80, 80))); //$pdf->SetDrawColor(190,190,200); - $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY); + $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1); $pdf->SetLineStyle(array('dash' => 0)); } - // Detect if some page were added automatically and output _tableau for past pages - while ($pagenb < $pageposafter) { - $pdf->setPage($pagenb); - $heightforqrinvoice = $this->getHeightForQRInvoice($pagenb, $object, $langs); - if ($pagenb == $pageposbeforeprintlines) { - $this->_tableau($pdf, $this->tab_top, $this->page_hauteur - $this->tab_top - $this->heightforfooter - $heightforqrinvoice, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis); + $nexY += 2; // Add space between lines + } + + // Add last page for document footer if there are not enough size left + $afterPosData = $this->getMaxAfterColsLinePositionsData(); + $page_bottom_margin = $this->heightforfooter + $this->heightforfreetext + $this->heightforinfotot + $this->getHeightForQRInvoice($pdf->getPage(), $object, $langs); + + if ($afterPosData['y'] > $this->page_hauteur - $page_bottom_margin) { + $pdf->AddPage(); + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); + } + $pagenb++; + $pdf->setPage($pagenb); + } + + // Draw table frames and columns borders + $drawTabNumbPage = $pdf->getNumPages(); + for ($i=$pageposbeforeprintlines; $i<=$drawTabNumbPage; $i++) { + $pdf->setPage($i); + // reset page orientation each loop to override it if it was changed + $pdf->setPageOrientation('', 0, 0); // The only function to edit the bottom margin of current page to set it. + + $drawTabHideTop = $hidetop; + $drawTabTop = $this->tab_top_newpage; + $drawTabBottom = $this->page_hauteur - $this->heightforfooter;; + $hideBottom = 0; // TODO understand why it change to 1 or 0 during process + + if ($i == $pageposbeforeprintlines) { + // first page need to start after notes + $drawTabTop = $this->tab_top; + } elseif (!$drawTabHideTop) { + if (getDolGlobalInt('MAIN_PDF_ENABLE_COL_HEAD_TITLE_REPEAT')) { + $drawTabTop-= $this->tabTitleHeight; } else { - $this->_tableau($pdf, $this->tab_top_newpage, $this->page_hauteur - $this->tab_top_newpage - $this->heightforfooter - $heightforqrinvoice, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis); - } - $this->_pagefoot($pdf, $object, $outputlangs, 1, $this->getHeightForQRInvoice($pdf->getPage(), $object, $outputlangs)); - $pagenb++; - $pdf->setPage($pagenb); - $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. - if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) { - $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis); - } - if (!empty($tplidx)) { - $pdf->useTemplate($tplidx); + $drawTabHideTop = 1; } } - if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { // @phan-suppress-current-line PhanUndeclaredProperty - $heightforqrinvoice = $this->getHeightForQRInvoice($pagenb, $object, $langs); - if ($pagenb == $pageposafter) { - $this->_tableau($pdf, $this->tab_top, $this->page_hauteur - $this->tab_top - $this->heightforfooter - $heightforqrinvoice, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis); - } else { - $this->_tableau($pdf, $this->tab_top_newpage, $this->page_hauteur - $this->tab_top_newpage - $this->heightforfooter - $heightforqrinvoice, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis); - } - $this->_pagefoot($pdf, $object, $outputlangs, 1, $this->getHeightForQRInvoice($pdf->getPage(), $object, $outputlangs)); - // New page - $pdf->AddPage(); - if (!empty($tplidx)) { - $pdf->useTemplate($tplidx); - } - $pagenb++; - if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) { - $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis); - } + // last page need to include document footer + if ($i == $pdf->getNumPages()) { + // remove document footer height to tab bottom position + $drawTabBottom-= $this->heightforfreetext + $this->heightforinfotot + $this->getHeightForQRInvoice($pdf->getPage(), $object, $outputlangs); + } + + $drawTabHeight = $drawTabBottom - $drawTabTop; + $this->_tableau($pdf, $drawTabTop, $drawTabHeight, 0, $outputlangs, $drawTabHideTop, $hideBottom, $object->multicurrency_code, $outputlangsbis); + + $hideFreeText = $i != $pdf->getNumPages() ? 1 : 0; // Display free text only in last page + + $this->_pagefoot($pdf, $object, $outputlangs, $hideFreeText, $this->getHeightForQRInvoice($pdf->getPage(), $object, $outputlangs)); + + $pdf->setPage($i); // in case of _pagefoot or _tableau change it + + // reset page orientation each loop to override it if it was changed by _pagefoot or _tableau change it + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + + // Don't print head on first page ($pageposbeforeprintlines) because already added previously + if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') && $i != $pageposbeforeprintlines) { + $this->_pagehead($pdf, $object, 0, $outputlangs); + } + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); } } - // Show square - $heightforqrinvoice = $this->getHeightForQRInvoice($pagenb, $object, $langs); - if ($pagenb == $pageposbeforeprintlines) { - $this->_tableau($pdf, $this->tab_top, $this->page_hauteur - $this->tab_top - $this->heightforinfotot - $this->heightforfreetext - $this->heightforfooter - $heightforqrinvoice, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code, $outputlangsbis); - $bottomlasttab = $this->page_hauteur - $this->heightforinfotot - $this->heightforfreetext - $this->heightforfooter - $heightforqrinvoice + 1; - } else { - $this->_tableau($pdf, $this->tab_top_newpage, $this->page_hauteur - $this->tab_top_newpage - $this->heightforinfotot - $this->heightforfreetext - $this->heightforfooter - $heightforqrinvoice, 0, $outputlangs, 1, 0, $object->multicurrency_code, $outputlangsbis); - $bottomlasttab = $this->page_hauteur - $this->heightforinfotot - $this->heightforfreetext - $this->heightforfooter - $heightforqrinvoice + 1; - } + + // reset text color before print footers + $pdf->SetTextColor(0, 0, 0); + + $pdf->setPage($pdf->getNumPages()); + + $bottomlasttab = $this->page_hauteur - $this->heightforinfotot - $this->heightforfreetext - $this->heightforfooter - $heightforqrinvoice + 1; // Display infos area $posy = $this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs, $outputlangsbis); @@ -1048,8 +1047,7 @@ class pdf_sponge extends ModelePDFFactures $posy = $this->drawPaymentsTable($pdf, $object, $posy, $outputlangs); } - // Pagefoot - $this->_pagefoot($pdf, $object, $outputlangs, 0, $this->getHeightForQRInvoice($pdf->getPage(), $object, $langs)); + // Add number of pages in footer if (method_exists($pdf, 'AliasNbPages')) { $pdf->AliasNbPages(); // @phan-suppress-current-line PhanUndeclaredMethod } @@ -1270,6 +1268,9 @@ class pdf_sponge extends ModelePDFFactures krsort($this->tva_array); + // Clean data type + $object->total_tva = (float) $object->total_tva; + // Show VAT details if ($object->total_tva != 0 && getDolGlobalInt('PDF_INVOICE_SHOW_VAT_ANALYSIS')) { $pdf->SetFillColor(224, 224, 224); @@ -1327,16 +1328,19 @@ class pdf_sponge extends ModelePDFFactures } } - // If France, show VAT mention if not applicable - if ($this->emetteur->country_code == 'FR' && empty($object->total_tva) && (empty($mysoc->tva_assuj) || ($this->emetteur->isInEEC() && $object->thirdparty->isInEEC()))) { + // If France, show VAT mention if applicable + if (in_array($this->emetteur->country_code, array('FR')) && empty($object->total_tva)) { $pdf->SetFont('', '', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); - if ($mysoc->forme_juridique_code == 92) { - $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoiceAsso"), 0, 'L', 0); - } else { - $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0); + if (empty($mysoc->tva_assuj)) { + if ($mysoc->forme_juridique_code == 92) { + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoiceAsso"), 0, 'L', 0); + } else { + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0); + } + } elseif (getDolGlobalString("INVOICE_VAT_SHOW_REVERSE_CHARGE_MENTION") && $this->emetteur->country_code != $object->thirdparty->country_code && $this->emetteur->isInEEC() && $object->thirdparty->isInEEC()) { + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedReverseChargeProcedure"), 0, 'L', 0); } - $posy = $pdf->GetY() + 4; } @@ -1470,7 +1474,7 @@ class pdf_sponge extends ModelePDFFactures if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') { // If payment mode unregulated or payment mode forced to CHQ if (getDolGlobalInt('FACTURE_CHQ_NUMBER')) { - $diffsizetitle = (!getDolGlobalString('PDF_DIFFSIZE_TITLE') ? 3 : $conf->global->PDF_DIFFSIZE_TITLE); + $diffsizetitle = getDolGlobalInt('PDF_DIFFSIZE_TITLE', 3); if (getDolGlobalInt('FACTURE_CHQ_NUMBER') > 0) { $account = new Account($this->db); @@ -1488,7 +1492,7 @@ class pdf_sponge extends ModelePDFFactures $posy = $pdf->GetY() + 2; } } - if ($conf->global->FACTURE_CHQ_NUMBER == -1) { + if (getDolGlobalInt('FACTURE_CHQ_NUMBER') == -1) { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle); $pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0); @@ -1572,7 +1576,7 @@ class pdf_sponge extends ModelePDFFactures */ protected function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs, $outputlangsbis) { - global $conf, $mysoc, $hookmanager; + global $mysoc, $hookmanager; $sign = 1; if ($object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) { @@ -2820,7 +2824,7 @@ class pdf_sponge extends ModelePDFFactures $this->cols['totalexcltax'] = array( 'rank' => $rank, 'width' => 26, // in mm - 'status' => !getDolGlobalString('PDF_PROPAL_HIDE_PRICE_EXCL_TAX'), + 'status' => !getDolGlobalBool('PDF_INVOICE_HIDE_PRICE_EXCL_TAX'), 'title' => array( 'textkey' => 'TotalHTShort' ), @@ -2831,7 +2835,7 @@ class pdf_sponge extends ModelePDFFactures $this->cols['totalincltax'] = array( 'rank' => $rank, 'width' => 26, // in mm - 'status' => getDolGlobalBool('PDF_PROPAL_SHOW_PRICE_INCL_TAX'), + 'status' => getDolGlobalBool('PDF_INVOICE_SHOW_PRICE_INCL_TAX'), 'title' => array( 'textkey' => 'TotalTTCShort' ), diff --git a/htdocs/core/modules/facture/mod_facture_mercure.php b/htdocs/core/modules/facture/mod_facture_mercure.php index 40dc1034642..3d3a93e8154 100644 --- a/htdocs/core/modules/facture/mod_facture_mercure.php +++ b/htdocs/core/modules/facture/mod_facture_mercure.php @@ -84,7 +84,7 @@ class mod_facture_mercure extends ModeleNumRefFactures // Setting the prefix $texte .= ''.$langs->trans("Mask").' ('.$langs->trans("InvoiceStandard").'):'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1, '', 0, 3, 'tooltipstandardmercure').''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', '', 0, 3, 'tooltipstandardmercure').''; $texte .= '  '; @@ -92,20 +92,20 @@ class mod_facture_mercure extends ModeleNumRefFactures // Prefix setting of credit note $texte .= ''.$langs->trans("Mask").' ('.$langs->trans("InvoiceAvoir").'):'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1, '', 0, 3, 'tooltipcreditnotemercure').''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', '', 0, 3, 'tooltipcreditnotemercure').''; $texte .= ''; // Prefix setting of replacement invoices if (!getDolGlobalString('INVOICE_DISABLE_REPLACEMENT')) { $texte .= ''.$langs->trans("Mask").' ('.$langs->trans("InvoiceReplacement").'):'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1, '', 0, 3, 'tooltipreplacementmercure').''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', '', 0, 3, 'tooltipreplacementmercure').''; $texte .= ''; } // Prefix setting of deposit if (!getDolGlobalString('INVOICE_DISABLE_DEPOSIT')) { $texte .= ''.$langs->trans("Mask").' ('.$langs->trans("InvoiceDeposit").'):'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1, '', 0, 3, 'tooltipdownpaymentmercure').''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', '', 0, 3, 'tooltipdownpaymentmercure').''; $texte .= ''; } diff --git a/htdocs/core/modules/fichinter/mod_arctic.php b/htdocs/core/modules/fichinter/mod_arctic.php index 0ac08eb7e06..a23fe52bbf6 100644 --- a/htdocs/core/modules/fichinter/mod_arctic.php +++ b/htdocs/core/modules/fichinter/mod_arctic.php @@ -88,7 +88,7 @@ class mod_arctic extends ModeleNumRefFicheinter // Setting the prefix $texte .= ''.$langs->trans("Mask").':'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).''; $texte .= '  '; diff --git a/htdocs/core/modules/holiday/mod_holiday_immaculate.php b/htdocs/core/modules/holiday/mod_holiday_immaculate.php index 03029517427..c8ed8ec5996 100644 --- a/htdocs/core/modules/holiday/mod_holiday_immaculate.php +++ b/htdocs/core/modules/holiday/mod_holiday_immaculate.php @@ -73,7 +73,7 @@ class mod_holiday_immaculate extends ModelNumRefHolidays //$tooltip .= '
'.$langs->trans("GenericMaskCodes5b"); $texte .= ''.$langs->trans("Mask").':'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).''; $texte .= '  '; $texte .= ''; $texte .= ''; diff --git a/htdocs/core/modules/hrm/mod_evaluation_advanced.php b/htdocs/core/modules/hrm/mod_evaluation_advanced.php index de221e52fee..434512e1cb1 100644 --- a/htdocs/core/modules/hrm/mod_evaluation_advanced.php +++ b/htdocs/core/modules/hrm/mod_evaluation_advanced.php @@ -82,7 +82,7 @@ class mod_evaluation_advanced extends ModeleNumRefEvaluation // Parametrage du prefix $texte .= ''.$langs->trans("Mask").':'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).''; $texte .= '  '; diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php index 10b889aa345..6d9e7c32e22 100644 --- a/htdocs/core/modules/import/import_csv.modules.php +++ b/htdocs/core/modules/import/import_csv.modules.php @@ -830,7 +830,7 @@ class ImportCsv extends ModeleImports $tmp = explode('-', $tmpval, 2); $listfields[] = $keyfield; $listvalues[] = "'".$this->db->escape($tmp[1])."'"; - } elseif (preg_match('/^rule-/', $tmpval)) { + } elseif (preg_match('/^rule-/', $tmpval)) { // Example: rule-computeAmount, rule-computeDirection, ... $fieldname = $tmpkey; if (!empty($objimport->array_import_convertvalue[0][$fieldname])) { if ($objimport->array_import_convertvalue[0][$fieldname]['rule'] == 'compute') { diff --git a/htdocs/core/modules/member/doc/pdf_standard_member.class.php b/htdocs/core/modules/member/doc/pdf_standard_member.class.php index 3adbb53d53f..42113bb78cd 100644 --- a/htdocs/core/modules/member/doc/pdf_standard_member.class.php +++ b/htdocs/core/modules/member/doc/pdf_standard_member.class.php @@ -291,7 +291,7 @@ class pdf_standard_member extends CommonStickerGenerator // List of values to scan for a replacement $substitutionarray = array( - '__ID__' => $object->id, + '__ID__' => (string) $object->id, '__REF__' => $object->ref, '__LOGIN__' => empty($object->login) ? '' : $object->login, '__FIRSTNAME__' => empty($object->firstname) ? '' : $object->firstname, @@ -309,7 +309,7 @@ class pdf_standard_member extends CommonStickerGenerator '__YEAR__' => $year, '__MONTH__' => $month, '__DAY__' => $day, - '__DOL_MAIN_URL_ROOT__' => DOL_MAIN_URL_ROOT, + '__DOL_MAIN_URL_ROOT__' => (string) DOL_MAIN_URL_ROOT, '__SERVER__' => "https://".$_SERVER["SERVER_NAME"]."/" ); complete_substitutions_array($substitutionarray, $langs); diff --git a/htdocs/core/modules/modAccounting.class.php b/htdocs/core/modules/modAccounting.class.php index 1dc084ee7cd..a630b1f9fd3 100644 --- a/htdocs/core/modules/modAccounting.class.php +++ b/htdocs/core/modules/modAccounting.class.php @@ -400,4 +400,37 @@ class modAccounting extends DolibarrModules 'b.multicurrency_code'=>"US (Necessary if devise is different than EUR)", ); } + + /** + * Function called when module is enabled. + * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. + * It also creates data directories + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + public function init($options = '') + { + $result = $this->_load_tables('/install/mysql/', 'accounting'); + if ($result < 0) { + return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') + } + + $sql = array(); + return $this->_init($sql, $options); + } + + /** + * Function called when module is disabled. + * Remove from database constants, boxes and permissions from Dolibarr database. + * Data directories are not deleted + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + public function remove($options = '') + { + $sql = array(); + return $this->_remove($sql, $options); + } } diff --git a/htdocs/core/modules/modStock.class.php b/htdocs/core/modules/modStock.class.php index c9bc793fb36..62b15d2116e 100644 --- a/htdocs/core/modules/modStock.class.php +++ b/htdocs/core/modules/modStock.class.php @@ -44,7 +44,7 @@ class modStock extends DolibarrModules */ public function __construct($db) { - global $conf, $langs; + global $conf, $langs; // $conf is used by inc.php $this->db = $db; $this->numero = 52; @@ -156,6 +156,17 @@ class modStock extends DolibarrModules $this->rights[$r][4] = 'mouvement'; $this->rights[$r][5] = 'creer'; + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { + // Not yet implemented. TODO + $r++; + $this->rights[$r][0] = 1008; + $this->rights[$r][1] = 'Read stock value'; + $this->rights[$r][2] = 'w'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'value_advance'; + $this->rights[$r][5] = 'read'; + } + $r++; $this->rights[$r][0] = 1011; $this->rights[$r][1] = 'inventoryReadPermission'; // Permission label diff --git a/htdocs/core/modules/mrp/mod_mo_advanced.php b/htdocs/core/modules/mrp/mod_mo_advanced.php index 255a3e6da43..82286280b8e 100644 --- a/htdocs/core/modules/mrp/mod_mo_advanced.php +++ b/htdocs/core/modules/mrp/mod_mo_advanced.php @@ -83,7 +83,7 @@ class mod_mo_advanced extends ModeleNumRefMos // Parametrage du prefix $text .= ''.$langs->trans("Mask").':'; - $text .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $text .= ''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).''; $text .= '  '; diff --git a/htdocs/core/modules/payment/mod_payment_ant.php b/htdocs/core/modules/payment/mod_payment_ant.php index 3a1fe0a9fad..5e3f0a4b37d 100644 --- a/htdocs/core/modules/payment/mod_payment_ant.php +++ b/htdocs/core/modules/payment/mod_payment_ant.php @@ -85,7 +85,7 @@ class mod_payment_ant extends ModeleNumRefPayments // Parametrage du prefix $texte .= ''.$langs->trans("Mask").':'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).''; $texte .= '  '; diff --git a/htdocs/core/modules/product/mod_codeproduct_elephant.php b/htdocs/core/modules/product/mod_codeproduct_elephant.php index 51d3943314c..b0932e24308 100644 --- a/htdocs/core/modules/product/mod_codeproduct_elephant.php +++ b/htdocs/core/modules/product/mod_codeproduct_elephant.php @@ -98,7 +98,7 @@ class mod_codeproduct_elephant extends ModeleProductCode // Parametrage du prefix customers $texte .= ''.$langs->trans("Mask").' ('.$langs->trans("ProductCodeModel").'):'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).''; $texte .= '  '; @@ -106,7 +106,7 @@ class mod_codeproduct_elephant extends ModeleProductCode // Parametrage du prefix suppliers $texte .= ''.$langs->trans("Mask").' ('.$langs->trans("ServiceCodeModel").'):'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).''; $texte .= ''; $texte .= ''; diff --git a/htdocs/core/modules/product_batch/mod_lot_advanced.php b/htdocs/core/modules/product_batch/mod_lot_advanced.php index 35fa10f867e..d07ce3fd9e3 100644 --- a/htdocs/core/modules/product_batch/mod_lot_advanced.php +++ b/htdocs/core/modules/product_batch/mod_lot_advanced.php @@ -86,7 +86,7 @@ class mod_lot_advanced extends ModeleNumRefBatch // Parametrage du prefix $texte .= ''.$langs->trans("Mask").':'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).''; $texte .= '  '; diff --git a/htdocs/core/modules/product_batch/mod_sn_advanced.php b/htdocs/core/modules/product_batch/mod_sn_advanced.php index dfcba97ccaf..18a33833ed3 100644 --- a/htdocs/core/modules/product_batch/mod_sn_advanced.php +++ b/htdocs/core/modules/product_batch/mod_sn_advanced.php @@ -86,7 +86,7 @@ class mod_sn_advanced extends ModeleNumRefBatch // Parametrage du prefix $texte .= ''.$langs->trans("Mask").':'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).''; $texte .= '  '; diff --git a/htdocs/core/modules/project/mod_project_universal.php b/htdocs/core/modules/project/mod_project_universal.php index 2be62efa5f3..4132956f86e 100644 --- a/htdocs/core/modules/project/mod_project_universal.php +++ b/htdocs/core/modules/project/mod_project_universal.php @@ -92,7 +92,7 @@ class mod_project_universal extends ModeleNumRefProjects // Prefix settings $texte .= ''.$langs->trans("Mask").':'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).''; $texte .= '  '; diff --git a/htdocs/core/modules/project/task/mod_task_universal.php b/htdocs/core/modules/project/task/mod_task_universal.php index 08cee523fec..4fcb310c941 100644 --- a/htdocs/core/modules/project/task/mod_task_universal.php +++ b/htdocs/core/modules/project/task/mod_task_universal.php @@ -87,7 +87,7 @@ class mod_task_universal extends ModeleNumRefTask // Parametrage du prefix $texte .= ''.$langs->trans("Mask").':'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).''; $texte .= '  '; diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php index 3e363c3be54..c52dc1b2c16 100644 --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php @@ -81,7 +81,6 @@ class pdf_cyan extends ModelePDFPropales */ public $cols; - /** * Constructor * @@ -194,10 +193,7 @@ class pdf_cyan extends ModelePDFPropales $nblines = count($object->lines); - $hidetop = 0; - if (getDolGlobalString('MAIN_PDF_DISABLE_COL_HEAD_TITLE')) { - $hidetop = getDolGlobalString('MAIN_PDF_DISABLE_COL_HEAD_TITLE'); - } + $hidetop = getDolGlobalInt('MAIN_PDF_DISABLE_COL_HEAD_TITLE'); // Loop on each lines to detect if there is at least one image to show $realpatharray = array(); @@ -361,6 +357,10 @@ class pdf_cyan extends ModelePDFPropales $tab_top = 90 + $top_shift; $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift : 10); + if (!$hidetop && getDolGlobalInt('MAIN_PDF_ENABLE_COL_HEAD_TITLE_REPEAT')) { + // TODO : make this hidden conf the default behavior for each PDF when each PDF managed this new Display + $tab_top_newpage+= $this->tabTitleHeight; + } $nexY = $tab_top; @@ -558,8 +558,25 @@ class pdf_cyan extends ModelePDFPropales // Loop on each lines $pageposbeforeprintlines = $pdf->getPage(); $pagenb = $pageposbeforeprintlines; + for ($i = 0; $i < $nblines; $i++) { + $linePosition = $i + 1; $curY = $nexY; + + // in First Check line page break and add page if needed + if (isset($object->lines[$i]->pagebreak) && $object->lines[$i]->pagebreak) { + // New page + $pdf->AddPage(); + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); + } + + $pdf->setPage($pdf->getNumPages()); + $nexY = $tab_top_newpage; + } + + $this->resetAfterColsLinePositionsData($nexY, $pdf->getPage()); + $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage $pdf->SetTextColor(0, 0, 0); @@ -570,112 +587,78 @@ class pdf_cyan extends ModelePDFPropales } $pdf->setTopMargin($tab_top_newpage); - $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot); // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. $pageposbefore = $pdf->getPage(); + $curYBefore = $curY; + + // Allows data in the first page if description is long enough to break in multiples pages + $showpricebeforepagebreak = getDolGlobalInt('MAIN_PDF_DATA_ON_FIRST_PAGE'); - $showpricebeforepagebreak = 1; $posYAfterImage = 0; - $posYAfterDescription = 0; if ($this->getColumnStatus('photo')) { // We start with Photo of product line - if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot))) { // If photo too high, we moved completely on new page + $imageTopMargin = 1; + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imageTopMargin + $imglinesize['height']) > ($this->page_hauteur - $heightforfooter)) { // If photo too high, we moved completely on new page $pdf->AddPage('', '', true); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); } $pdf->setPage($pageposbefore + 1); - + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. $curY = $tab_top_newpage; - - // Allows data in the first page if description is long enough to break in multiples pages - if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) { - $showpricebeforepagebreak = 1; - } else { - $showpricebeforepagebreak = 0; - } + $showpricebeforepagebreak = 0; } - + $pdf->setPageOrientation('', 0, $heightforfooter + $heightforfreetext); // The only function to edit the bottom margin of current page to set it. if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { - $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + $imageTopMargin, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually $posYAfterImage = $curY + $imglinesize['height']; + + $this->setAfterColsLinePositionsData('photo', $posYAfterImage, $pdf->getPage()); } } - // Description of product line + // restore Page orientation for text + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. + if ($this->getColumnStatus('desc')) { - $pdf->startTransaction(); - $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); - $pageposafter = $pdf->getPage(); - - if ($pageposafter > $pageposbefore) { // There is a pagebreak (not enough space for total+free text+footer) - $pdf->rollbackTransaction(true); - - $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it to simple footer, so we can retry as if we have just the simple footer. - - $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); - - $pageposafter = $pdf->getPage(); - $posyafter = $pdf->GetY(); - //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit; - if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot))) { // There is no space left for total+free text but no page break. - if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page manually because no break page was done automatically for the last part. - $pdf->AddPage('', '', true); - if (!empty($tplidx)) { - $pdf->useTemplate($tplidx); - } - $pdf->setPage($pageposafter + 1); - } - } else { - // We found a page break that was done automatically and there is ow enough space for total+free text+footer. - // Allows data in the first page if description is long enough to break in multiples pages - if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) { - $showpricebeforepagebreak = 1; - } else { - $showpricebeforepagebreak = 0; - } - } - } else { // No pagebreak - $pdf->commitTransaction(); - } - $posYAfterDescription = $pdf->GetY(); + $this->setAfterColsLinePositionsData('desc', $pdf->GetY(), $pdf->getPage()); } - $nexY = $pdf->GetY(); - $pageposafter = $pdf->getPage(); - + $afterPosData = $this->getMaxAfterColsLinePositionsData(); $pdf->setPage($pageposbefore); $pdf->setTopMargin($this->marge_haute); - $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + $curY = $curYBefore; + $pdf->setPageOrientation('', 0, $heightforfooter); // The only function to edit the bottom margin of current page to set it. - // We suppose that a too long description or photo were moved completely on next page, so we set the value for $curY and current page that will be used by the following output. - if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { - $pdf->setPage($pageposafter); + + // We suppose that a too long description or photo were moved completely on next page + if ($afterPosData['page'] > $pageposbefore && (empty($showpricebeforepagebreak) || ($curY + 4) > ($this->page_hauteur - $heightforfooter))) { + $pdf->setPage($afterPosData['page']); $curY = $tab_top_newpage; } $pdf->SetFont('', '', $default_font_size - 1); // We reposition the default font + // # of line if ($this->getColumnStatus('position')) { - $this->printStdColumnContent($pdf, $curY, 'position', (string) ($i + 1)); + $this->printStdColumnContent($pdf, $curY, 'position', strval($linePosition)); } // VAT Rate if ($this->getColumnStatus('vat')) { $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate); - $nexY = max($pdf->GetY(), $nexY); } // Unit price before discount if ($this->getColumnStatus('subprice')) { $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax); - $nexY = max($pdf->GetY(), $nexY); } // Quantity @@ -683,7 +666,6 @@ class pdf_cyan extends ModelePDFPropales if ($this->getColumnStatus('qty')) { $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'qty', $qty); - $nexY = max($pdf->GetY(), $nexY); } @@ -691,28 +673,24 @@ class pdf_cyan extends ModelePDFPropales if ($this->getColumnStatus('unit')) { $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'unit', $unit); - $nexY = max($pdf->GetY(), $nexY); } // Discount on line if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) { $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent); - $nexY = max($pdf->GetY(), $nexY); } // Total excl tax line (HT) if ($this->getColumnStatus('totalexcltax')) { $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax); - $nexY = max($pdf->GetY(), $nexY); } // Total with tax line (TTC) if ($this->getColumnStatus('totalincltax')) { $total_incl_tax = pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails); $this->printStdColumnContent($pdf, $curY, 'totalincltax', $total_incl_tax); - $nexY = max($pdf->GetY(), $nexY); } // Extrafields @@ -721,19 +699,21 @@ class pdf_cyan extends ModelePDFPropales if ($this->getColumnStatus($extrafieldColKey)) { $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey, $outputlangs); $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); - $nexY = max($pdf->GetY(), $nexY); + + $this->setAfterColsLinePositionsData('options_'.$extrafieldColKey, $pdf->GetY(), $pdf->getPage()); } } } + $afterPosData = $this->getMaxAfterColsLinePositionsData(); $parameters = array( - 'object' => $object, - 'i' => $i, - 'pdf' => & $pdf, - 'curY' => & $curY, - 'nexY' => & $nexY, - 'outputlangs' => $outputlangs, - 'hidedetails' => $hidedetails + 'object' => $object, + 'i' => $i, + 'pdf' => & $pdf, + 'curY' => & $curY, + 'nexY' => & $afterPosData['y'], // for backward module hook compatibility Y will be accessible by $object->getMaxAfterColsLinePositionsData() + 'outputlangs' => $outputlangs, + 'hidedetails' => $hidedetails ); $reshook = $hookmanager->executeHooks('printPDFline', $parameters, $this); // Note that $object may have been modified by hook @@ -804,13 +784,14 @@ class pdf_cyan extends ModelePDFPropales } $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate' => $vatrate, 'vatcode' => $vatcode, 'amount' => $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne); - if ($posYAfterImage > $posYAfterDescription) { - $nexY = max($nexY, $posYAfterImage); - } + + + $afterPosData = $this->getMaxAfterColsLinePositionsData(); + $pdf->setPage($afterPosData['page']); + $nexY = $afterPosData['y']; // Add line - if (getDolGlobalString('MAIN_PDF_DASH_BETWEEN_LINES') && $i < ($nblines - 1)) { - $pdf->setPage($pageposafter); + if (getDolGlobalString('MAIN_PDF_DASH_BETWEEN_LINES') && $i < ($nblines - 1) && $afterPosData['y'] < $this->page_hauteur - $heightforfooter - 5) { $pdf->SetLineStyle(array('dash' => '1,1', 'color' => array(80, 80, 80))); //$pdf->SetDrawColor(190,190,200); $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1); @@ -818,54 +799,75 @@ class pdf_cyan extends ModelePDFPropales } $nexY += 2; // Add space between lines + } - // Detect if some page were added automatically and output _tableau for past pages - while ($pagenb < $pageposafter) { - $pdf->setPage($pagenb); - if ($pagenb == $pageposbeforeprintlines) { - $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis); + + // Add last page for document footer if there are not enough size left + $afterPosData = $this->getMaxAfterColsLinePositionsData(); + if ($afterPosData['y'] > $this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot) ) { + $pdf->AddPage(); + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); + } + $pagenb++; + $pdf->setPage($pagenb); + } + + // Draw table frames and columns borders + $drawTabNumbPage = $pdf->getNumPages(); + for ($i=$pageposbeforeprintlines; $i<=$drawTabNumbPage; $i++) { + $pdf->setPage($i); + // reset page orientation each loop to override it if it was changed + $pdf->setPageOrientation('', 0, 0); // The only function to edit the bottom margin of current page to set it. + + $drawTabHideTop = $hidetop; + $drawTabTop = $tab_top_newpage; + $drawTabBottom = $this->page_hauteur - $heightforfooter;; + $hideBottom = 0; // TODO understand why it change to 1 or 0 during process + + if ($i == $pageposbeforeprintlines) { + // first page need to start after notes + $drawTabTop = $tab_top; + } elseif (!$drawTabHideTop) { + if (getDolGlobalInt('MAIN_PDF_ENABLE_COL_HEAD_TITLE_REPEAT')) { + $drawTabTop-= $this->tabTitleHeight; } else { - $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis); - } - $this->_pagefoot($pdf, $object, $outputlangs, 1); - $pagenb++; - $pdf->setPage($pagenb); - $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. - if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) { - $this->_pagehead($pdf, $object, 0, $outputlangs); - } - if (!empty($tplidx)) { - $pdf->useTemplate($tplidx); + $drawTabHideTop = 1; } } - if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { // @phan-suppress-current-line PhanUndeclaredProperty - if ($pagenb == $pageposafter) { - $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis); - } else { - $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis); - } - $this->_pagefoot($pdf, $object, $outputlangs, 1); - // New page - $pdf->AddPage(); - if (!empty($tplidx)) { - $pdf->useTemplate($tplidx); - } - $pagenb++; - if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) { - $this->_pagehead($pdf, $object, 0, $outputlangs); - } + // last page need to include document footer + if ($i == $pdf->getNumPages()) { + // remove document footer height to tab bottom position + $drawTabBottom-= $heightforsignature + $heightforfreetext + $heightforinfotot; + } + + $drawTabHeight = $drawTabBottom - $drawTabTop; + $this->_tableau($pdf, $drawTabTop, $drawTabHeight, 0, $outputlangs, $drawTabHideTop, $hideBottom, $object->multicurrency_code, $outputlangsbis); + + $hideFreeText = $i != $pdf->getNumPages() ? 1 : 0; // Display free text only in last page + $this->_pagefoot($pdf, $object, $outputlangs, $hideFreeText); + + $pdf->setPage($i); // in case of _pagefoot or _tableau change it + + // reset page orientation each loop to override it if it was changed by _pagefoot or _tableau change it + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + + // Don't print head on first page ($pageposbeforeprintlines) because already added previously + if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') && $i != $pageposbeforeprintlines) { + $this->_pagehead($pdf, $object, 0, $outputlangs); + } + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); } } - // Show square - if ($pagenb == $pageposbeforeprintlines) { - $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code, $outputlangsbis); - $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1; - } else { - $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code, $outputlangsbis); - $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1; - } + // reset text color before print footers + $pdf->SetTextColor(0, 0, 0); + + $pdf->setPage($pdf->getNumPages()); + + $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1; // Display infos area $posy = $this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs); @@ -878,8 +880,7 @@ class pdf_cyan extends ModelePDFPropales $posy = $this->drawSignatureArea($pdf, $object, $posy, $outputlangs); } - // Pagefoot - $this->_pagefoot($pdf, $object, $outputlangs); + // Add number of pages in footer if (method_exists($pdf, 'AliasNbPages')) { $pdf->AliasNbPages(); // @phan-suppress-current-line PhanUndeclaredMethod } diff --git a/htdocs/core/modules/propale/mod_propale_saphir.php b/htdocs/core/modules/propale/mod_propale_saphir.php index 8f3e6402b63..93ebf4f8298 100644 --- a/htdocs/core/modules/propale/mod_propale_saphir.php +++ b/htdocs/core/modules/propale/mod_propale_saphir.php @@ -90,7 +90,7 @@ class mod_propale_saphir extends ModeleNumRefPropales // Parametrage du prefix $texte .= ''.$langs->trans("Mask").':'; $mask = !getDolGlobalString('PROPALE_SAPHIR_MASK') ? '' : $conf->global->PROPALE_SAPHIR_MASK; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).''; $texte .= '  '; diff --git a/htdocs/core/modules/reception/mod_reception_moonstone.php b/htdocs/core/modules/reception/mod_reception_moonstone.php index 3810da99bb1..a482366fc36 100644 --- a/htdocs/core/modules/reception/mod_reception_moonstone.php +++ b/htdocs/core/modules/reception/mod_reception_moonstone.php @@ -67,7 +67,7 @@ class mod_reception_moonstone extends ModelNumRefReception $tooltip .= '
'.$langs->trans("GenericMaskCodes5b"); $texte .= ''.$langs->trans("Mask").':'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).''; $texte .= '  '; $texte .= ''; $texte .= ''; diff --git a/htdocs/core/modules/societe/mod_codeclient_elephant.php b/htdocs/core/modules/societe/mod_codeclient_elephant.php index 566d7bb70f0..b01fcafb6db 100644 --- a/htdocs/core/modules/societe/mod_codeclient_elephant.php +++ b/htdocs/core/modules/societe/mod_codeclient_elephant.php @@ -110,7 +110,7 @@ class mod_codeclient_elephant extends ModeleThirdPartyCode // Parametrage du prefix customers $texte .= ''.$langs->trans("Mask").' ('.$langs->trans("CustomerCodeModel").'):'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1, '', 0, 3, 'tooltipelephantcutomer').''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', '', 0, 3, 'tooltipelephantcutomer').''; $texte .= '  '; @@ -118,7 +118,7 @@ class mod_codeclient_elephant extends ModeleThirdPartyCode // Parametrage du prefix suppliers $texte .= ''.$langs->trans("Mask").' ('.$langs->trans("SupplierCodeModel").'):'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1, '', 0, 3, 'tooltipelephantsupplier').''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 'help', '', 0, 3, 'tooltipelephantsupplier').''; $texte .= ''; // Date of switch to that numbering model diff --git a/htdocs/core/modules/societe/mod_codecompta_aquarium.php b/htdocs/core/modules/societe/mod_codecompta_aquarium.php index 0161aff09d6..868488bd4a2 100644 --- a/htdocs/core/modules/societe/mod_codecompta_aquarium.php +++ b/htdocs/core/modules/societe/mod_codecompta_aquarium.php @@ -87,7 +87,6 @@ class mod_codecompta_aquarium extends ModeleAccountancyCode */ public function info($langs) { - global $conf; global $form; $langs->load("companies"); @@ -100,8 +99,8 @@ class mod_codecompta_aquarium extends ModeleAccountancyCode $texte .= ''; $texte .= ''; $texte .= ''; - $s1 = $form->textwithpicto('', $tooltip, 1, 1); - $s2 = $form->textwithpicto('', $tooltip, 1, 1); + $s1 = $form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name); + $s2 = $form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name); $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; diff --git a/htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php b/htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php index 67592bde09a..628b7411ebf 100644 --- a/htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php +++ b/htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php @@ -86,7 +86,7 @@ class mod_supplier_payment_brodator extends ModeleNumRefSupplierPayments // Parametrage du prefix $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; @@ -139,7 +139,7 @@ class mod_supplier_payment_brodator extends ModeleNumRefSupplierPayments return 0; } - $numFinal = get_next_value($db, $mask, 'paiementfourn', 'ref', '', $objsoc, $object->datepaye); + $numFinal = get_next_value($db, $mask, 'paiementfourn', 'ref', '', $objsoc, is_object($object) ?$object->datepaye :''); return $numFinal; } diff --git a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php index 4eada1d1578..9c83c7d9176 100644 --- a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php +++ b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php @@ -90,7 +90,7 @@ class mod_supplier_proposal_saphir extends ModeleNumRefSupplierProposal // Parametrage du prefix $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; diff --git a/htdocs/core/modules/takepos/mod_takepos_ref_universal.php b/htdocs/core/modules/takepos/mod_takepos_ref_universal.php index 2affafe14ba..75768b9f87e 100644 --- a/htdocs/core/modules/takepos/mod_takepos_ref_universal.php +++ b/htdocs/core/modules/takepos/mod_takepos_ref_universal.php @@ -84,7 +84,7 @@ class mod_takepos_ref_universal extends ModeleNumRefTakepos // Setting up the prefix $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; diff --git a/htdocs/core/modules/ticket/mod_ticket_universal.php b/htdocs/core/modules/ticket/mod_ticket_universal.php index 81b263a931e..dcac49b041a 100644 --- a/htdocs/core/modules/ticket/mod_ticket_universal.php +++ b/htdocs/core/modules/ticket/mod_ticket_universal.php @@ -85,7 +85,7 @@ class mod_ticket_universal extends ModeleNumRefTicket // Prefix settings $text .= ''; - $text .= ''; + $text .= ''; $text .= ''; diff --git a/htdocs/core/modules/workstation/mod_workstation_advanced.php b/htdocs/core/modules/workstation/mod_workstation_advanced.php index f372547a395..c67765e88d8 100644 --- a/htdocs/core/modules/workstation/mod_workstation_advanced.php +++ b/htdocs/core/modules/workstation/mod_workstation_advanced.php @@ -83,7 +83,7 @@ class mod_workstation_advanced extends ModeleNumRefWorkstation // Parametrage du prefix $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; diff --git a/htdocs/core/tpl/advtarget.tpl.php b/htdocs/core/tpl/advtarget.tpl.php index 317aa2d1fe8..310ea9b814b 100644 --- a/htdocs/core/tpl/advtarget.tpl.php +++ b/htdocs/core/tpl/advtarget.tpl.php @@ -314,7 +314,10 @@ if (!getDolGlobalString('MAIN_EXTRAFIELDS_DISABLED')) { $extrafields->fetch_name_optionals_label($elementtype); foreach ($extrafields->attributes[$elementtype]['label'] as $key => $val) { if ($key != 'ts_nameextra' && $key != 'ts_payeur') { - print ''; + break; + case 'string': // This type is no more used. type is now varchar(x) + print ''; + break; + case 'stock': + print ''; + break; + default: + print ''; + break; + } + } +} + // Move fields of totalizable into the common array pos and val if (!empty($totalarray['totalizable']) && is_array($totalarray['totalizable'])) { foreach ($totalarray['totalizable'] as $keytotalizable => $valtotalizable) { @@ -107,40 +147,3 @@ if (isset($totalarray['pos'])) { } //print ''; } - -/** print a total cell value according to its type - * - * @param string $type of field (duration, string..) - * @param string $val the value to display - * - * @return void (direct print) - */ -function printTotalValCell($type, $val) -{ - // if $totalarray['type'] not present we consider it as number - if (empty($type)) { - $type = 'real'; - } - switch ($type) { - case 'duration': - print ''; - break; - case 'string': // This type is no more used. type is now varchar(x) - print ''; - break; - case 'stock': - print ''; - break; - default: - print ''; - break; - } -} diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index 077f7d4aeb1..7b9029cf6b8 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -3,6 +3,7 @@ * Copyright (C) 2011-2022 Laurent Destailleur * Copyright (C) 2024 MDW * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024 Charlene Benke * * 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 @@ -281,11 +282,12 @@ if ($disablenofollow) {
"> +file->main_authentication) || $conf->file->main_authentication != 'googleoauth') { ?>
- + " name="username" class="flat input-icon-user minwidth150" value="" tabindex="1" autofocus="autofocus" autocapitalize="off" autocomplete="on" spellcheck="false" autocorrect="off" /> @@ -293,7 +295,6 @@ if ($disablenofollow) {
-file->main_authentication) || $conf->file->main_authentication != 'googleoauth') { ?>
'/core/modules/security/captcha/'), is_array($conf->modules_parts['captcha']) ? $conf->modules_parts['captcha'] : array()); + $dirModCaptcha = array_merge(array('main' => '/core/modules/security/captcha/'), (isset($conf->modules_parts['captcha']) && is_array($conf->modules_parts['captcha'])) ? $conf->modules_parts['captcha'] : array()); $fullpathclassfile = ''; foreach ($dirModCaptcha as $dir) { $fullpathclassfile = dol_buildpath($dir."modCaptcha".ucfirst($captcha).'.class.php', 0, 2); @@ -334,7 +335,7 @@ if (!empty($captcha)) { $classname = "modCaptcha".ucfirst($captcha); if (class_exists($classname)) { /** @var ModeleCaptcha $captchaobj */ - $captchaobj = new $classname($db, $conf, $langs, $user); + $captchaobj = new $classname($db, $conf, $langs, null); '@phan-var-force ModeleCaptcha $captchaobj'; if (is_object($captchaobj) && method_exists($captchaobj, 'getCaptchaCodeForForm')) { diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 8b58ba7879b..4cf2258fded 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -204,9 +204,9 @@ if ($nolinesbefore) { } } - // Free line + // Select type of free line $labelforempty = 1; - print ''; + print ''; // Show radio for the non predefined product if ($forceall >= 0 && (isModEnabled("product") || isModEnabled("service"))) { print ''; - //print ' '; } else { echo ''; // Show type selector @@ -228,11 +226,10 @@ if ($nolinesbefore) { } else { $labelforempty = $langs->trans("FreeLineOfType"); } - //print ' '; } } - $form->select_type_of_lines(GETPOSTISSET("type") ? GETPOST("type", 'alpha', 2) : -1, 'type', $labelforempty, 1, $forceall, ''); + $form->select_type_of_lines(GETPOSTISSET("type") ? GETPOST("type", 'alpha', 2) : -1, 'type', $labelforempty, 1, $forceall, 'minwidth200', 0); print ''; } // Predefined product/service @@ -281,10 +278,10 @@ if ($nolinesbefore) { if (getDolGlobalString('MAIN_AUTO_OPEN_SELECT2_ON_FOCUS_FOR_CUSTOMER_PRODUCTS')) { ?> '; +//print 'Click'; + print "\n"; diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index e50370f4c45..9e34f4ba39f 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -312,8 +312,8 @@ $tooltiponpricemultiprice = ''; $tooltiponpriceend = ''; $tooltiponpriceendmultiprice = ''; if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) { - $tooltiponprice = $langs->transcountry("TotalHT", $mysoc->country_code).'='.price($line->total_ht, 0, '', 0, 0); - $tooltiponpricemultiprice = $langs->transcountry("TotalHT", $mysoc->country_code).'='.price($line->multicurrency_total_ht, 0, '', 0, 0); + $tooltiponprice .= $langs->transcountry("TotalHT", $mysoc->country_code).'='.price($line->total_ht, 0, '', 0, 0); + $tooltiponpricemultiprice .= $langs->transcountry("TotalHT", $mysoc->country_code).'='.price($line->multicurrency_total_ht, 0, '', 0, 0); $tooltiponprice .= '
'.$langs->transcountry("TotalVAT", ($senderissupplier ? $object->thirdparty->country_code : $mysoc->country_code)).'='.price($line->total_tva, 0, '', 0, 0); $tooltiponpricemultiprice .= '
'.$langs->transcountry("TotalVAT", ($senderissupplier ? $object->thirdparty->country_code : $mysoc->country_code)).'='.price($line->multicurrency_total_tva, 0, '', 0, 0); if (is_object($object->thirdparty)) { @@ -347,6 +347,19 @@ if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) { $tooltiponprice .= '
'.$langs->transcountry("TotalTTC", $mysoc->country_code).'='.price($line->total_ttc, 0, '', 0, 0); $tooltiponpricemultiprice .= '
'.$langs->transcountry("TotalTTC", $mysoc->country_code).'='.price($line->multicurrency_total_ttc, 0, '', 0, 0); + if (!empty($line->special_code) || $line->product_type == 9) { + $tooltiponprice .= '
'; + $tooltiponpricemultiprice .= '
'; + if (!empty($line->special_code)) { + $tooltiponprice .= '
'.$langs->trans("SpecialLine").' : '.getLabelSpecialCode($line->special_code); + $tooltiponpricemultiprice .= '
'.$langs->trans("SpecialLine").' : '.getLabelSpecialCode($line->special_code); + } + if ($line->product_type == 9) { + $tooltiponprice .= '
'.$langs->trans("SpecialLine").' : '.$langs->trans("GroupingLine"); + $tooltiponpricemultiprice .= '
'.$langs->trans("SpecialLine").' : '.$langs->trans("GroupingLine"); + } + } + $tooltiponprice = ''; $tooltiponpricemultiprice = ''; diff --git a/htdocs/core/tpl/passwordreset.tpl.php b/htdocs/core/tpl/passwordreset.tpl.php index 4754c76c4fb..05a7ccfb7ae 100644 --- a/htdocs/core/tpl/passwordreset.tpl.php +++ b/htdocs/core/tpl/passwordreset.tpl.php @@ -52,7 +52,7 @@ if (empty($conf) || !is_object($conf)) { } // DDOS protection -$size = (int) $_SERVER['CONTENT_LENGTH']; +$size = (int) ($_SERVER['CONTENT_LENGTH'] ?? 0); if ($size > 10000) { $langs->loadLangs(array("errors", "install")); httponly_accessforbidden('
'.$langs->trans("ErrorRequestTooLarge").'
'.$langs->trans("ClickHereToGoToApp").'
', 413, 1); diff --git a/htdocs/core/triggers/interface_95_modZapier_ZapierTriggers.class.php b/htdocs/core/triggers/interface_95_modZapier_ZapierTriggers.class.php index 87fd49d1f0e..d6ed6a6383f 100644 --- a/htdocs/core/triggers/interface_95_modZapier_ZapierTriggers.class.php +++ b/htdocs/core/triggers/interface_95_modZapier_ZapierTriggers.class.php @@ -224,7 +224,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers case 'ORDER_CLASSIFY_BILLED': case 'ORDER_SETDRAFT': case 'LINEORDER_INSERT': - case 'LINEORDER_UPDATE': + case 'LINEORDER_MODIFY': case 'LINEORDER_DELETE': break; // Supplier orders @@ -239,7 +239,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'ORDER_SUPPLIER_RECEIVE': // case 'LINEORDER_SUPPLIER_DISPATCH': // case 'LINEORDER_SUPPLIER_CREATE': - // case 'LINEORDER_SUPPLIER_UPDATE': + // case 'LINEORDER_SUPPLIER_MODIFY': // Proposals // case 'PROPAL_CREATE': @@ -251,7 +251,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'PROPAL_CLOSE_REFUSED': // case 'PROPAL_DELETE': // case 'LINEPROPAL_INSERT': - // case 'LINEPROPAL_UPDATE': + // case 'LINEPROPAL_MODIFY': // case 'LINEPROPAL_DELETE': // SupplierProposal @@ -264,7 +264,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'SUPPLIER_PROPOSAL_CLOSE_REFUSED': // case 'SUPPLIER_PROPOSAL_DELETE': // case 'LINESUPPLIER_PROPOSAL_INSERT': - // case 'LINESUPPLIER_PROPOSAL_UPDATE': + // case 'LINESUPPLIER_PROPOSAL_MODIFY': // case 'LINESUPPLIER_PROPOSAL_DELETE': // Contracts @@ -274,7 +274,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'CONTRACT_CLOSE': // case 'CONTRACT_DELETE': // case 'LINECONTRACT_INSERT': - // case 'LINECONTRACT_UPDATE': + // case 'LINECONTRACT_MODIFY': // case 'LINECONTRACT_DELETE': // Bills @@ -288,19 +288,19 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'BILL_DELETE': // case 'BILL_PAYED': // case 'LINEBILL_INSERT': - // case 'LINEBILL_UPDATE': + // case 'LINEBILL_MODIFY': // case 'LINEBILL_DELETE': //Supplier Bill // case 'BILL_SUPPLIER_CREATE': - // case 'BILL_SUPPLIER_UPDATE': + // case 'BILL_SUPPLIER_MODIFY': // case 'BILL_SUPPLIER_DELETE': // case 'BILL_SUPPLIER_PAYED': // case 'BILL_SUPPLIER_UNPAYED': // case 'BILL_SUPPLIER_VALIDATE': // case 'BILL_SUPPLIER_UNVALIDATE': // case 'LINEBILL_SUPPLIER_CREATE': - // case 'LINEBILL_SUPPLIER_UPDATE': + // case 'LINEBILL_SUPPLIER_MODIFY': // case 'LINEBILL_SUPPLIER_DELETE': // Payments @@ -316,7 +316,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // Donation // case 'DON_CREATE': - // case 'DON_UPDATE': + // case 'DON_MODIFY': // case 'DON_DELETE': // Interventions @@ -325,7 +325,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'FICHINTER_VALIDATE': // case 'FICHINTER_DELETE': // case 'LINEFICHINTER_CREATE': - // case 'LINEFICHINTER_UPDATE': + // case 'LINEFICHINTER_MODIFY': // case 'LINEFICHINTER_DELETE': // Members diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index f7bb85395c8..b814567f710 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -1223,7 +1223,7 @@ class Cronjob extends CommonObject dol_syslog(get_class($this)."::run_jobs jobtype=".$this->jobtype." userlogin=".$userlogin, LOG_DEBUG); // Increase limit of time. Works only if we are not in safe mode - $ExecTimeLimit = 600; + $ExecTimeLimit = getDolGlobalInt('MAIN_CRON_EXEC_TIME_LIMIT', 600); if (!empty($ExecTimeLimit)) { $err = error_reporting(); error_reporting(0); // Disable all errors @@ -1231,7 +1231,7 @@ class Cronjob extends CommonObject @set_time_limit($ExecTimeLimit); // Need more than 240 on Windows 7/64 error_reporting($err); } - $MemoryLimit = 0; + $MemoryLimit = getDolGlobalString('MAIN_CRON_MEMORY_LIMIT'); if (!empty($MemoryLimit)) { @ini_set('memory_limit', $MemoryLimit); } diff --git a/htdocs/document.php b/htdocs/document.php index 9b440a30e06..6ed09912043 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -5,8 +5,8 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2010 Pierre Morin * Copyright (C) 2010 Juanjo Menent - * Copyright (C) 2022 Ferran Marcet - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2022 Ferran Marcet + * Copyright (C) 2024 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 @@ -102,9 +102,12 @@ function llxHeader($head = '', $title = '', $help_url = '', $target = '', $disab * Footer empty * * @ignore + * @param string $comment A text to add as HTML comment into HTML generated page + * @param string $zone 'private' (for private pages) or 'public' (for public pages) + * @param int $disabledoutputofmessages Clear all messages stored into session without displaying them * @return void */ -function llxFooter() +function llxFooter($comment = '', $zone = 'private', $disabledoutputofmessages = 0) { } @@ -126,7 +129,7 @@ $original_file = GETPOST('file', 'alphanohtml'); $hashp = GETPOST('hashp', 'aZ09'); $modulepart = GETPOST('modulepart', 'alpha'); $urlsource = GETPOST('urlsource', 'alpha'); -$entity = GETPOSTINT('entity', $conf->entity); +$entity = GETPOSTINT('entity') ? GETPOSTINT('entity') : $conf->entity; // Security check if (empty($modulepart) && empty($hashp)) { diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php index df8f9ff436d..b282e6ebe5d 100644 --- a/htdocs/ecm/class/ecmfiles.class.php +++ b/htdocs/ecm/class/ecmfiles.class.php @@ -1008,7 +1008,14 @@ class EcmFiles extends CommonObject } if ($option) { - $url = DOL_URL_ROOT.'/document.php?modulepart='.$option.'&file='.urlencode(preg_replace('/^[^\/]+\//', '', $this->filepath).'/'.$this->filename).'&entity='.$this->entity; + if ($option == 'facture_fournisseur') { + $tmppath = preg_replace('/^fournisseur\/facture\//', '', $this->filepath); + } elseif ($option == 'commande_fournisseur') { + $tmppath = preg_replace('/^fournisseur\/commande\//', '', $this->filepath); + } else { + $tmppath = preg_replace('/^[^\/]+\//', '', $this->filepath); + } + $url = DOL_URL_ROOT.'/document.php?modulepart='.urlencode($option).'&file='.urlencode($tmppath.'/'.$this->filename).'&entity='.$this->entity; } else { $url = DOL_URL_ROOT.'/ecm/file_card.php?id='.$this->id; } diff --git a/htdocs/eventorganization/conferenceorbooth_card.php b/htdocs/eventorganization/conferenceorbooth_card.php index 6df36447088..69162c5fca8 100644 --- a/htdocs/eventorganization/conferenceorbooth_card.php +++ b/htdocs/eventorganization/conferenceorbooth_card.php @@ -228,7 +228,7 @@ if (!empty($withproject)) { // Define a complementary filter for search of next/prev ref. if (!$user->hasRight('project', 'all', 'lire')) { $objectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 0); - $projectstatic->next_prev_filter = "rowid:IN:(".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0').")"; + $projectstatic->next_prev_filter = "rowid:IN:".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0'); } dol_banner_tab($projectstatic, 'project_ref', $linkback, 1, 'ref', 'ref', $morehtmlref); diff --git a/htdocs/eventorganization/conferenceorbooth_contact.php b/htdocs/eventorganization/conferenceorbooth_contact.php index 8748ea0d15d..dd8d9b6aa3f 100644 --- a/htdocs/eventorganization/conferenceorbooth_contact.php +++ b/htdocs/eventorganization/conferenceorbooth_contact.php @@ -206,7 +206,7 @@ if (!empty($withproject)) { // Define a complementary filter for search of next/prev ref. if (!$user->hasRight('project', 'all', 'lire')) { $objectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 0); - $projectstatic->next_prev_filter = "rowid:IN:(".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0').")"; + $projectstatic->next_prev_filter = "rowid:IN:".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0'); } dol_banner_tab($projectstatic, 'project_ref', $linkback, 1, 'ref', 'ref', $morehtmlref); diff --git a/htdocs/eventorganization/conferenceorbooth_document.php b/htdocs/eventorganization/conferenceorbooth_document.php index efd21894b7d..e561ae99265 100644 --- a/htdocs/eventorganization/conferenceorbooth_document.php +++ b/htdocs/eventorganization/conferenceorbooth_document.php @@ -180,7 +180,7 @@ if (!empty($withproject)) { // Define a complementary filter for search of next/prev ref. if (!$user->hasRight('project', 'all', 'lire')) { $objectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 0); - $projectstatic->next_prev_filter = "rowid:IN:(".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0').")"; + $projectstatic->next_prev_filter = "rowid:IN:".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0'); } dol_banner_tab($projectstatic, 'project_ref', $linkback, 1, 'ref', 'ref', $morehtmlref); diff --git a/htdocs/eventorganization/conferenceorbooth_list.php b/htdocs/eventorganization/conferenceorbooth_list.php index d03ffe9ed1b..46bb260a6be 100644 --- a/htdocs/eventorganization/conferenceorbooth_list.php +++ b/htdocs/eventorganization/conferenceorbooth_list.php @@ -342,7 +342,7 @@ if ($projectid > 0) { // Define a complementary filter for search of next/prev ref. if (!$user->hasRight('project', 'all', 'lire')) { $objectsListId = $project->getProjectsAuthorizedForUser($user, 0, 0); - $project->next_prev_filter = "rowid:IN:(".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0').")"; + $project->next_prev_filter = "rowid:IN:".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0'); } dol_banner_tab($project, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); diff --git a/htdocs/eventorganization/conferenceorboothattendee_card.php b/htdocs/eventorganization/conferenceorboothattendee_card.php index 3014cab7a8d..b7010dadaf5 100644 --- a/htdocs/eventorganization/conferenceorboothattendee_card.php +++ b/htdocs/eventorganization/conferenceorboothattendee_card.php @@ -256,7 +256,7 @@ if (!empty($withproject)) { // Define a complementary filter for search of next/prev ref. if (!$user->hasRight('projet', 'all', 'lire')) { $objectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 0); - $projectstatic->next_prev_filter = "rowid:IN:(".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0').")"; + $projectstatic->next_prev_filter = "rowid:IN:".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0'); } dol_banner_tab($projectstatic, 'project_ref', $linkback, 1, 'ref', 'ref', $morehtmlref); diff --git a/htdocs/eventorganization/conferenceorboothattendee_list.php b/htdocs/eventorganization/conferenceorboothattendee_list.php index 1474a71eef6..c5934e13ecd 100644 --- a/htdocs/eventorganization/conferenceorboothattendee_list.php +++ b/htdocs/eventorganization/conferenceorboothattendee_list.php @@ -441,7 +441,7 @@ if ($projectstatic->id > 0 || $confOrBooth > 0) { // Define a complementary filter for search of next/prev ref. if (!$user->hasRight('projet', 'all', 'lire')) { $objectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 0); - $projectstatic->next_prev_filter = "rowid:IN:(".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0').")"; + $projectstatic->next_prev_filter = "rowid:IN:".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0'); } dol_banner_tab($projectstatic, 'project_ref', $linkback, 1, 'ref', 'ref', $morehtmlref); diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 2fe1ac92ddd..56d300c9b8f 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1875,7 +1875,7 @@ if ($action == 'create') { print '
'; } - if ($object->status == $object::STATUS_CLOSED) { + if ($object->status == ExpenseReport::STATUS_CLOSED) { /* TODO this fields are not yet filled print ''; print ''; @@ -2615,12 +2615,12 @@ if ($action == 'create') { // Unit price net print ''; // Unit price with tax print ''; // Quantity diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index f9757c4f779..b502bfe6ad7 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -1943,7 +1943,7 @@ class ExpenseReport extends CommonObject dol_syslog(get_class($this)."::addline qty=$qty, up=$up, fk_c_type_fees=$fk_c_type_fees, vatrate=$vatrate, date=$date, fk_project=$fk_project, type=$type, comments=$comments", LOG_DEBUG); - if ($this->status == self::STATUS_DRAFT) { + if ($this->status == self::STATUS_DRAFT || $this->status == self::STATUS_REFUSED) { if (empty($qty)) { $qty = 0; } @@ -2037,7 +2037,7 @@ class ExpenseReport extends CommonObject } } else { dol_syslog(get_class($this)."::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR); - $this->error = 'ErrorExpenseNotDraft'; + $this->error = 'ErrorExpenseNotDraftAndNotRefused'; return -3; } } diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php index 61042abf3de..72d260e1525 100644 --- a/htdocs/exports/export.php +++ b/htdocs/exports/export.php @@ -474,7 +474,7 @@ if ($step == 1 || !$datatoexport) { // Affiche les modules d'exports print '
'; // You can use div-table-responsive-no-min if you don't need reserved height for your table - print '
'; // trans remove html entities $texte .= $langs->trans("ModuleCompanyCodeCustomer".$this->name, '{s2}')."
\n"; diff --git a/htdocs/core/modules/societe/mod_codecompta_digitaria.php b/htdocs/core/modules/societe/mod_codecompta_digitaria.php index 28686db0ed6..857cb2d9521 100644 --- a/htdocs/core/modules/societe/mod_codecompta_digitaria.php +++ b/htdocs/core/modules/societe/mod_codecompta_digitaria.php @@ -112,10 +112,10 @@ class mod_codecompta_digitaria extends ModeleAccountancyCode $texte .= ''; $texte .= ''; $texte .= ''; - $s1 = $form->textwithpicto('', $tooltip, 1, 1); - $s2 = $form->textwithpicto('', $tooltip, 1, 1); - $s3 = $form->textwithpicto('', $tooltip, 1, 1); - $s4 = $form->textwithpicto('', $tooltip, 1, 1); + $s1 = $form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name); + $s2 = $form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name); + $s3 = $form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name); + $s4 = $form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name); $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; diff --git a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php index ed15e0e7351..bafa84d20c8 100644 --- a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php +++ b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php @@ -99,7 +99,7 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices // Setting the prefix $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; @@ -107,19 +107,19 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices // Prefix setting of credit note $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; if (!getDolGlobalString('INVOICE_DISABLE_REPLACEMENT') && getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { // Prefix setting of replacement $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; } // Prefix setting of deposit $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; $texte .= '
'; // trans remove html entities $texte .= $langs->trans("ModuleCompanyCodeCustomer".$this->name, '{s2}', '{s4}')."
\n"; diff --git a/htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php b/htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php index 62387787668..0bc819da50b 100644 --- a/htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php +++ b/htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php @@ -83,7 +83,7 @@ class mod_stocktransfer_advanced extends ModeleNumRefStockTransfer // Parametrage du prefix $texte .= '
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).' 
'.$langs->trans("Mask").' ('.$langs->trans("InvoiceStandard").')'; $texte .= ':'.$form->textwithpicto('', $tooltip, 1, 1, '', 0, 3, 'tooltipstandardtulip').''.$form->textwithpicto('', $tooltip, 1, 'help', '', 0, 3, 'tooltipstandardtulip').' 
'.$langs->trans("Mask").' ('.$langs->trans("InvoiceAvoir").'):'.$form->textwithpicto('', $tooltip, 1, 1, '', 0, 3, 'tooltipcredittuplie').''.$form->textwithpicto('', $tooltip, 1, 'help', '', 0, 3, 'tooltipcredittuplie').'
'.$langs->trans("Mask").' ('.$langs->trans("InvoiceReplacement").'):'.$form->textwithpicto('', $tooltip, 1, 1, '', 0, 3, 'tooltipreplacementtulip').''.$form->textwithpicto('', $tooltip, 1, 'help', '', 0, 3, 'tooltipreplacementtulip').'
'.$langs->trans("Mask").' ('.$langs->trans("InvoiceDeposit").'):'.$form->textwithpicto('', $tooltip, 1, 1, '', 0, 3, 'tooltipdownpaymenttulip').''.$form->textwithpicto('', $tooltip, 1, 'help', '', 0, 3, 'tooltipdownpaymenttulip').'
'; diff --git a/htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php b/htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php index 350e22302ea..707b64505d6 100644 --- a/htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php +++ b/htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php @@ -91,7 +91,7 @@ class mod_commande_fournisseur_orchidee extends ModeleNumRefSuppliersOrders // Parametrage du prefix $texte .= '
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1, '', 0, 3, 'tooltiporchidee').''.$form->textwithpicto('', $tooltip, 1, 'help', '', 0, 3, 'tooltiporchidee').' 
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).' 
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).' 
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).'
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).' 
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).' 
'.$extrafields->attributes[$elementtype]['label'][$key]; + if (isset($extrafields->attributes[$elementtype]['langfile'][$key])) { + $langs->load($extrafields->attributes[$elementtype]['langfile'][$key]); + } + print '
'.$langs->trans($extrafields->attributes[$elementtype]['label'][$key]); if (!empty($array_query['options_'.$key]) || (is_array($array_query['options_'.$key]) && count($array_query['options_'.$key]) > 0)) { print img_picto($langs->trans('AdvTgtUse'), 'ok.png@advtargetemailing'); } @@ -330,9 +333,9 @@ if (!getDolGlobalString('MAIN_EXTRAFIELDS_DISABLED')) { } elseif (($extrafields->attributes[$elementtype]['type'][$key] == 'date') || ($extrafields->attributes[$elementtype]['type'][$key] == 'datetime')) { print ''; print '
'.$langs->trans("AdvTgtStartDt").''; - print $form->selectDate('', 'options_'.$key.'_st_dt'); + print $form->selectDate('', 'options_'.$key.'_st_dt', 0, 0, 1); print ''.$langs->trans("AdvTgtEndDt").''; - print $form->selectDate('', 'options_'.$key.'_end_dt'); + print $form->selectDate('', 'options_'.$key.'_end_dt', 0, 0, 1); print '
'; print '
'."\n"; @@ -348,19 +351,19 @@ if (!getDolGlobalString('MAIN_EXTRAFIELDS_DISABLED')) { $array_query['options_'.$key] ); print ''."\n"; - } elseif (($extrafields->attributes[$elementtype]['type'][$key] == 'select')) { - print $formadvtargetemaling->advMultiselectarray('options_'.$key, $extrafields->attributes[$key]['param']['options'], $array_query['options_'.$key]); + } elseif ($extrafields->attributes[$elementtype]['type'][$key] == 'select') { + print $formadvtargetemaling->advMultiselectarray('options_'.$key, $extrafields->attributes[$elementtype]['param'][$key]['options'], $array_query['options_'.$key]); print ''."\n"; - } elseif (($extrafields->attributes[$elementtype]['type'][$key] == 'sellist')) { - print $formadvtargetemaling->advMultiselectarraySelllist('options_'.$key, $extrafields->attributes[$key]['param']['options'], $array_query['options_'.$key]); + } elseif ($extrafields->attributes[$elementtype]['type'][$key] == 'sellist') { + print $formadvtargetemaling->advMultiselectarraySelllist('options_'.$key, $extrafields->attributes[$elementtype]['param'][$key]['options'], $array_query['options_'.$key]); print ''."\n"; } else { print ''; print '
'; if (is_array($array_query['options_'.$key])) { - print $extrafields->showInputField($key, implode(',', $array_query['options_'.$key])); + print $extrafields->showInputField($key, implode(',', $array_query['options_'.$key]), '', '', '', '', 0, 'societe', 1); } else { - print $extrafields->showInputField($key, $array_query['options_'.$key]); + print $extrafields->showInputField($key, $array_query['options_'.$key], '', '', '', '', 0, 'societe', 1); } print '
'; @@ -529,9 +532,9 @@ if (!getDolGlobalString('MAIN_EXTRAFIELDS_DISABLED')) { } elseif (($extrafields->attributes[$elementtype]['type'][$key] == 'date') || ($extrafields->attributes[$elementtype]['type'][$key] == 'datetime')) { print ''; print '
'.$langs->trans("AdvTgtStartDt").''; - print $form->selectDate('', 'options_'.$key.'_st_dt_cnct'); + print $form->selectDate('', 'options_'.$key.'_st_dt_cnct', 0, 0, 1); print ''.$langs->trans("AdvTgtEndDt").''; - print $form->selectDate('', 'options_'.$key.'_end_dt_cnct'); + print $form->selectDate('', 'options_'.$key.'_end_dt_cnct', 0, 0, 1); print '
'; print '
'."\n"; print $form->textwithpicto('', $langs->trans("AdvTgtSearchDtHelp"), 1, 'help'); @@ -546,17 +549,17 @@ if (!getDolGlobalString('MAIN_EXTRAFIELDS_DISABLED')) { $array_query['options_'.$key.'_cnct'] ); print ''."\n"; - } elseif (($extrafields->attributes[$elementtype]['type'][$key] == 'select')) { - print $formadvtargetemaling->advMultiselectarray('options_'.$key.'_cnct', $extrafields->attributes[$key]['param']['options'], $array_query['options_'.$key.'_cnct']); + } elseif ($extrafields->attributes[$elementtype]['type'][$key] == 'select') { + print $formadvtargetemaling->advMultiselectarray('options_'.$key.'_cnct', $extrafields->attributes[$elementtype]['param'][$key]['options'], $array_query['options_'.$key.'_cnct']); print ''."\n"; - } elseif (($extrafields->attributes[$elementtype]['type'][$key] == 'sellist')) { - print $formadvtargetemaling->advMultiselectarraySelllist('options_'.$key.'_cnct', $extrafields->attributes[$key]['param']['options'], $array_query['options_'.$key.'_cnct']); + } elseif ($extrafields->attributes[$elementtype]['type'][$key] == 'sellist') { + print $formadvtargetemaling->advMultiselectarraySelllist('options_'.$key.'_cnct', $extrafields->attributes[$elementtype]['param'][$key]['options'], $array_query['options_'.$key.'_cnct']); print ''."\n"; } else { if (is_array($array_query['options_'.$key.'_cnct'])) { - print $extrafields->showInputField($key, implode(',', $array_query['options_'.$key.'_cnct']), '', '_cnct'); + print $extrafields->showInputField($key, implode(',', $array_query['options_'.$key.'_cnct']), '', '_cnct', '', '', 0, 'socpeople', 1); } else { - print $extrafields->showInputField($key, $array_query['options_'.$key.'_cnct'], '', '_cnct'); + print $extrafields->showInputField($key, $array_query['options_'.$key.'_cnct'], '', '_cnct', '', '', 0, 'socpeople', 1); } print ''."\n"; } diff --git a/htdocs/core/tpl/list_print_total.tpl.php b/htdocs/core/tpl/list_print_total.tpl.php index 3e6af0c8a20..d79d844484c 100644 --- a/htdocs/core/tpl/list_print_total.tpl.php +++ b/htdocs/core/tpl/list_print_total.tpl.php @@ -23,6 +23,46 @@ */ '@phan-var-force array{nbfield:int,type?:array,pos?:array,val?:array} $totalarray'; +if (!function_exists('printTotalValCell')) { // allow two list with total on same screen + + /** print a total cell value according to its type + * + * @param string $type of field (duration, string..) + * @param string $val the value to display + * + * @return void (direct print) + */ + function printTotalValCell($type, $val) + { + // if $totalarray['type'] not present we consider it as number + if (empty($type)) { + $type = 'real'; + } + switch ($type) { + case 'duration': + print ''; + print(!empty($val) ? convertSecondToTime((int) $val, 'allhourmin') : 0); + print ''; + print(!empty($val) ? $val : ''); + print ''; + print price2num(!empty($val) ? $val : 0, 'MS'); + print ''; + print price(!empty($val) ? $val : 0); + print ''; - print(!empty($val) ? convertSecondToTime((int) $val, 'allhourmin') : 0); - print ''; - print(!empty($val) ? $val : ''); - print ''; - print price2num(!empty($val) ? $val : 0, 'MS'); - print ''; - print price(!empty($val) ? $val : 0); - print '
'.$langs->trans("AUTHORPAIEMENT").''; - print ''; + print ''; print ''; - print ''; + print ''; print '
'; + print '
'; print ''; print ''; print ''; @@ -486,16 +486,17 @@ if ($step == 1 || !$datatoexport) { //var_dump($objexport->array_export_code_for_sort); //$sortedarrayofmodules = dol_sort_array($objexport->array_export_module, 'module_position', 'asc', 0, 0, 1); foreach ($objexport->array_export_code_for_sort as $key => $value) { - print ''; + if (!$i) { + $totalarray['nbfield']++; + } } // Ref if (!empty($arrayfields['cf.ref']['checked'])) { @@ -2120,9 +2123,9 @@ if ($resql) { print ''; } print ''; - } - if (!$i) { - $totalarray['nbfield']++; + if (!$i) { + $totalarray['nbfield']++; + } } print "\n"; diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index c5694200c8a..1506bc57e17 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -844,7 +844,7 @@ if (empty($reshook)) { $object->fk_incoterms = GETPOSTINT('incoterm_id'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha'); - $object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx'); + $object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx'); $object->transport_mode_id = GETPOSTINT('transport_mode_id'); // Proprietes particulieres a facture de replacement @@ -1347,7 +1347,7 @@ if (empty($reshook)) { } $tva_tx = $lines[$i]->tva_tx; - if (!empty($lines[$i]->vat_src_code) && !preg_match('/\(/', $tva_tx)) { + if (!empty($lines[$i]->vat_src_code) && !preg_match('/\(/', (string) $tva_tx)) { $tva_tx .= ' ('.$lines[$i]->vat_src_code.')'; } @@ -3595,7 +3595,7 @@ if ($action == 'create') { print '
'.$langs->trans("Module").''.$langs->trans("ExportableDatas").'
'; - //print img_object($objexport->array_export_module[$key]->getName(),$export->array_export_module[$key]->picto).' '; - print $objexport->array_export_module[$key]->getName(); + $titleofmodule = $objexport->array_export_module[$key]->getName(); + print '
'; + print dolPrintHTML($titleofmodule); print ''; $entity = preg_replace('/:.*$/', '', $objexport->array_export_icon[$key]); $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); $label = $objexport->array_export_label[$key]; - //print $value.'-'.$icon.'-'.$label."
"; - print img_object($objexport->array_export_module[$key]->getName(), $entityicon).' '; - print $label; + print '
'; + print img_object($objexport->array_export_module[$key]->getName(), $entityicon, 'class="pictofixedwidth"'); + print dolPrintHTML($label); + print '
'; print '
'; if ($objexport->array_export_perms[$key]) { print ''.img_picto($langs->trans("NewExport"), 'next', 'class="fa-15"').''; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index b0b14cf5092..d6a173eef2b 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -733,6 +733,7 @@ class FactureFournisseur extends CommonInvoice */ if (! $error && $this->fac_rec > 0 && $_facrec instanceof FactureFournisseurRec) { foreach ($_facrec->lines as $i => $val) { + $product_type = $_facrec->lines[$i]->product_type; if ($_facrec->lines[$i]->fk_product) { $prod = new Product($this->db); $res = $prod->fetch($_facrec->lines[$i]->fk_product); @@ -794,7 +795,7 @@ class FactureFournisseur extends CommonInvoice 0, $_facrec->lines[$i]->info_bits, 'HT', - 0, + $product_type, $_facrec->lines[$i]->rang, 0, $_facrec->lines[$i]->array_options, diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 5a259070df1..d7db51a8523 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -1025,7 +1025,7 @@ class ProductFournisseur extends Product } } - if ($fourn_unitprice < $min || $min == -1) { + if ($fourn_unitprice_with_discount < $min || $min == -1) { $this->id = $prodid; $this->product_fourn_price_id = $record["product_fourn_price_id"]; $this->ref_supplier = $record["ref_fourn"]; @@ -1050,7 +1050,7 @@ class ProductFournisseur extends Product $this->fourn_multicurrency_id = $record["fk_multicurrency"]; $this->fourn_multicurrency_code = $record["multicurrency_code"]; - $min = $fourn_unitprice; + $min = $fourn_unitprice_with_discount; } } } diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 051e09d453d..4ba693846f4 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -534,7 +534,7 @@ if (empty($reshook)) { } $tva_tx = $lines[$i]->tva_tx; - if (!empty($lines[$i]->vat_src_code) && !preg_match('/\(/', $tva_tx)) { + if (!empty($lines[$i]->vat_src_code) && !preg_match('/\(/', (string) $tva_tx)) { $tva_tx .= ' ('.$lines[$i]->vat_src_code.')'; } @@ -1803,6 +1803,9 @@ if ($resql) { print ''; } print '
'; - // List of payments + // List of payments already done $totalpaid = 0; @@ -3649,8 +3649,8 @@ if ($action == 'create') { print ''; print ''; print ''; - print ''; - print ''; + print ''; + print ''; if (isModEnabled("bank")) { print ''; } @@ -4063,7 +4063,7 @@ if ($action == 'create') { } // Reverse back money or convert to reduction - if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_STANDARD) { + if ($object->status != FactureFournisseur::STATUS_DRAFT && ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_STANDARD)) { // For credit note only if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->status == 1 && $object->paid == 0) { if ($resteapayer == 0) { @@ -4172,7 +4172,7 @@ if ($action == 'create') { $urlsource = $_SERVER['PHP_SELF'].'?id='.$object->id; $genallowed = $usercanread; $delallowed = $usercancreate; - $modelpdf = (!empty($object->model_pdf) ? $object->model_pdf : (!getDolGlobalString('INVOICE_SUPPLIER_ADDON_PDF') ? '' : $conf->global->INVOICE_SUPPLIER_ADDON_PDF)); + $modelpdf = (empty($object->model_pdf) ? getDolGlobalString('INVOICE_SUPPLIER_ADDON_PDF') : $object->model_pdf); print $formfile->showdocuments('facture_fournisseur', $subdir, $filedir, $urlsource, $genallowed, $delallowed, $modelpdf, 1, 0, 0, 40, 0, '', '', '', $societe->default_lang); $somethingshown = $formfile->numoffiles; diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 1e9d77989f4..b66cfc1f399 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -351,7 +351,7 @@ if ($step == 1 || !$datatoimport) { // Affiche les modules d'imports print '
'; // You can use div-table-responsive-no-min if you don't need reserved height for your table - print '
'.($object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("PaymentsBack") : $langs->trans('Payments')).''.$langs->trans('Date').''.$langs->trans('Type').''.$langs->trans('Date').''.$langs->trans('Type').''.$langs->trans('BankAccount').'
'; + print '
'; print ''; print ''; print ''; @@ -362,18 +362,21 @@ if ($step == 1 || !$datatoimport) { $sortedarrayofmodules = dol_sort_array($objimport->array_import_module, 'position_of_profile', 'asc', 0, 0, 1); foreach ($sortedarrayofmodules as $key => $value) { //var_dump($key.' '.$value['position_of_profile'].' '.$value['import_code'].' '.$objimport->array_import_module[$key]['module']->getName().' '.$objimport->array_import_code[$key]); - print '
'.$langs->trans("Module").''.$langs->trans("ImportableDatas").'
'; $titleofmodule = $objimport->array_import_module[$key]['module']->getName(); + print '
'; // Special case for import common to module/services if (in_array($objimport->array_import_code[$key], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) { $titleofmodule = $langs->trans("ProductOrService"); } - print $titleofmodule; + print dolPrintHTML($titleofmodule); print ''; $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[$key]); $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); - print img_object($objimport->array_import_module[$key]['module']->getName(), $entityicon).' '; - print $objimport->array_import_label[$key]; + $label = $objimport->array_import_label[$key]; + print '
'; + print img_object($objimport->array_import_module[$key]['module']->getName(), $entityicon, 'class="pictofixedwidth"'); + print dolPrintHTML($label); + print '
'; print '
'; if ($objimport->array_import_perms[$key]) { print ''.img_picto($langs->trans("NewImport"), 'next', 'class="fa-15"').''; diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index 0fa6d65e907..cbf958ad41b 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -836,7 +836,8 @@ IMG; dol_mkdir($conf->user->dir_temp); // We must be sure the directory exists and is writable // We delete and recreate a subdir because the soffice may have change pemrissions on it - dol_delete_dir_recursive($conf->user->dir_temp.'/odtaspdf'); + $countdeleted = 0; + dol_delete_dir_recursive($conf->user->dir_temp.'/odtaspdf', 0, 0, 0, $countdeleted, 0, 1); dol_mkdir($conf->user->dir_temp.'/odtaspdf'); // Install prerequisites: apt install soffice libreoffice-common libreoffice-writer diff --git a/htdocs/includes/odtphp/zip/PclZipProxy.php b/htdocs/includes/odtphp/zip/PclZipProxy.php index 01d657a80a9..040b735499f 100644 --- a/htdocs/includes/odtphp/zip/PclZipProxy.php +++ b/htdocs/includes/odtphp/zip/PclZipProxy.php @@ -1,5 +1,7 @@ +-- Copyright (C) 2016 Laurent Destailleur +-- Copyright (C) 2024 Regis Houssin -- -- 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 @@ -17,6 +18,6 @@ -- =================================================================== -ALTER TABLE llx_societe_rib ADD UNIQUE INDEX uk_societe_rib(label, fk_soc); +ALTER TABLE llx_societe_rib ADD UNIQUE INDEX uk_societe_rib(entity, label, fk_soc); ALTER TABLE llx_societe_rib ADD CONSTRAINT llx_societe_rib_fk_societe FOREIGN KEY (fk_soc) REFERENCES llx_societe(rowid); diff --git a/htdocs/install/mysql/tables/llx_societe_rib.sql b/htdocs/install/mysql/tables/llx_societe_rib.sql index 9fb4370c243..e5ef25a45b3 100644 --- a/htdocs/install/mysql/tables/llx_societe_rib.sql +++ b/htdocs/install/mysql/tables/llx_societe_rib.sql @@ -1,9 +1,9 @@ -- ============================================================================= --- Copyright (C) 2000-2004 Rodolphe Quiedeville --- Copyright (C) 2005-2009 Regis Houssin --- Copyright (C) 2012 Juanjo Menent --- Copyright (C) 2013 Peter Fontaine --- Copyright (C) 2023 Alexandre Spangaro +-- Copyright (C) 2000-2004 Rodolphe Quiedeville +-- Copyright (C) 2005-2024 Regis Houssin +-- Copyright (C) 2012 Juanjo Menent +-- Copyright (C) 2013 Peter Fontaine +-- Copyright (C) 2023 Alexandre Spangaro -- -- 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 @@ -23,72 +23,73 @@ create table llx_societe_rib ( - rowid integer AUTO_INCREMENT PRIMARY KEY, - type varchar(32) DEFAULT 'ban' NOT NULL, -- 'ban' or 'paypal' or 'card' or 'stripe' - label varchar(200), - fk_soc integer NOT NULL, - datec datetime, - tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + rowid integer AUTO_INCREMENT PRIMARY KEY, + entity integer DEFAULT 1 NOT NULL, -- multi company id + type varchar(32) DEFAULT 'ban' NOT NULL, -- 'ban' or 'paypal' or 'card' or 'stripe' + label varchar(200), + fk_soc integer NOT NULL, + datec datetime, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- For BAN - bank varchar(255), -- bank name - code_banque varchar(128), -- bank code - code_guichet varchar(6), -- desk code - number varchar(255), -- account number - cle_rib varchar(5), -- key of bank account + bank varchar(255), -- bank name + code_banque varchar(128), -- bank code + code_guichet varchar(6), -- desk code + number varchar(255), -- account number + cle_rib varchar(5), -- key of bank account - bic varchar(20), -- 11 according to ISO 9362 (we keep 20 for backward compatibility) - bic_intermediate varchar(11), -- 11 according to ISO 9362. Same as bic but for intermediate bank - iban_prefix varchar(80), -- full iban. 34 according to ISO 13616 but we set 80 to allow to store it with encryption information + bic varchar(20), -- 11 according to ISO 9362 (we keep 20 for backward compatibility) + bic_intermediate varchar(11), -- 11 according to ISO 9362. Same as bic but for intermediate bank + iban_prefix varchar(80), -- full iban. 34 according to ISO 13616 but we set 80 to allow to store it with encryption information - domiciliation varchar(255), - proprio varchar(60), - owner_address varchar(255), - default_rib smallint NOT NULL DEFAULT 0, - state_id integer, - fk_country integer, - currency_code varchar(3), + domiciliation varchar(255), + proprio varchar(60), + owner_address varchar(255), + default_rib smallint NOT NULL DEFAULT 0, + state_id integer, + fk_country integer, + currency_code varchar(3), - model_pdf varchar(255), -- last template used to generate main document - last_main_doc varchar(255), -- relative filepath+filename of last main generated document + model_pdf varchar(255), -- last template used to generate main document + last_main_doc varchar(255), -- relative filepath+filename of last main generated document -- For BAN direct debit feature - rum varchar(32), -- RUM value to use for SEPA generation - date_rum date, -- Date of mandate - frstrecur varchar(16) DEFAULT 'FRST', -- 'FRST' or 'RECUR' + rum varchar(32), -- RUM value to use for SEPA generation + date_rum date, -- Date of mandate + frstrecur varchar(16) DEFAULT 'FRST', -- 'FRST' or 'RECUR' -- For credit card - last_four varchar(4), -- last 4 - card_type varchar(255), -- card type 'VISA', 'MC' , ... - cvn varchar(255), - exp_date_month integer, - exp_date_year integer, - country_code varchar(10), + last_four varchar(4), -- last 4 + card_type varchar(255), -- card type 'VISA', 'MC' , ... + cvn varchar(255), + exp_date_month integer, + exp_date_year integer, + country_code varchar(10), -- For Paypal - approved integer DEFAULT 0, - email varchar(255), - ending_date date, - max_total_amount_of_all_payments double(24,8), - preapproval_key varchar(255), - starting_date date, - total_amount_of_all_payments double(24,8), + approved integer DEFAULT 0, + email varchar(255), + ending_date date, + max_total_amount_of_all_payments double(24,8), + preapproval_key varchar(255), + starting_date date, + total_amount_of_all_payments double(24,8), --For Stripe, Stancer, ... - stripe_card_ref varchar(128), -- card_...' - stripe_account varchar(128), -- 'pk_live_...' + stripe_card_ref varchar(128), -- card_...' + stripe_account varchar(128), -- 'pk_live_...' - ext_payment_site varchar(128), -- name of external paymentmode (for example 'StripeLive') + ext_payment_site varchar(128), -- name of external paymentmode (for example 'StripeLive') - extraparams varchar(255), -- for other parameters with json format + extraparams varchar(255), -- for other parameters with json format -- For Online Sign - date_signature datetime, - online_sign_ip varchar(48), - online_sign_name varchar(64), + date_signature datetime, + online_sign_ip varchar(48), + online_sign_name varchar(64), - comment varchar(255), - ipaddress varchar(68), - status integer NOT NULL DEFAULT 1, -- 1=ACTIVE, 0=IN_TRASH - import_key varchar(14) -- import key + comment varchar(255), + ipaddress varchar(68), + status integer NOT NULL DEFAULT 1, -- 1=ACTIVE, 0=IN_TRASH + import_key varchar(14) -- import key )ENGINE=innodb; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 90e30555733..3a7196da08f 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2144,10 +2144,10 @@ MAIN_PDF_NO_RECIPENT_FRAME=Hide borders on recipient address frame MAIN_PDF_HIDE_CUSTOMER_CODE=Hide customer code MAIN_PDF_HIDE_CUSTOMER_ACCOUNTING_CODE=Hide customer accounting code MAIN_PDF_HIDE_SENDER_NAME=Hide sender/company name in address block -TERMSOFSALE=Conditions de vente -MAIN_PDF_ADD_TERMSOFSALE_PROPAL=Add the conditions of sale after the proposal -MAIN_PDF_ADD_TERMSOFSALE_ORDER=Add the conditions of sale after the order -MAIN_PDF_ADD_TERMSOFSALE_INVOICE=Add the conditions of sale after the invoice +TERMSOFSALE=Terms and conditions of sale +MAIN_PDF_ADD_TERMSOFSALE_PROPAL=Add the terms and conditions of sale after the proposal +MAIN_PDF_ADD_TERMSOFSALE_ORDER=Add the terms and conditions of sale after the order +MAIN_PDF_ADD_TERMSOFSALE_INVOICE=Add the terms and conditions of sale after the invoice PROPOSAL_PDF_HIDE_PAYMENTTERM=Hide payments conditions PROPOSAL_PDF_HIDE_PAYMENTMODE=Hide payment mode MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING=Add a hidden markup into the signature area to allow electronic signature tool to reuse it. May be used by external tools or in the future by the online signature feature. @@ -2582,7 +2582,7 @@ DolibarrStandardCaptcha=A native captcha generated by Dolibarr SALES_ORDER_SHOW_SHIPPING_ADDRESS=Show shipping address SALES_ORDER_SHOW_SHIPPING_ADDRESSMore=Compulsory indication in some countries (France, ...) PDF_INVOICE_SHOW_VAT_ANALYSIS=Show vat analysis per rate -MaxNbOfRecordOnListIsOk=You have a max size for lists is set to %s lines. This is a good value. +MaxNbOfRecordOnListIsOk=You have a max size for lists set to %s lines. This is a good value. YouHaveALargeAmountOfRecordOnLists=You have a default max size for lists set to %s lines. This is a large value that need scrolling to see all answers. It is better to have a value lower than %s and use pagination to see record over this number. Change this in menu Home - Setup - Display. RoundBorders=Round borders CheckIfModuleIsNotBlackListed=Block install for modules found into the Remote blacklist @@ -2593,7 +2593,7 @@ SensitiveData=Sensitive data ToolToDecryptAString=Tool to decrypt a string Decrypt=Decrypt FilesIntegrityDesc=If you want to check the integrity of files instead of database, you can do it by using this tool. -AttributeCodeHelp=A code of your choice (without special char and space) to identify the property.
Note that if an object B is created from an existing object A that has a different type (for example creation of an invoice from an order), the value of the complementary attributes of A are also copied into the complementary attributes of B when the code of the attribute is the same. +AttributeCodeHelp=A code of your choice (without special chars and spaces) to identify the property.
Note that if an object B is created from an existing object A that has a different type (for example creation of an invoice from an order), the value of the complementary attributes of A are also copied into the complementary attributes of B when the code of the attribute is the same. ThereIsMoreThanXAnswers=There is more than %s answers with your filter. Please add more filters... -PdfAddTermOfSaleHelp=Upload the condition of sales from file input at the bottom of this setup page -WarningOnlineSignature=Please note that this function allows a person (customer, supplier...) to insert, online, the image of his signature in the PDF document. As for a handwritten signature, such a signature can be made by anyone and does not have the same legal value as a legal electronic signature system going through a paying trusted third party. If you need this level of security, you can contact an integrator for more information or check for addons on www.dolistore.org. +PdfAddTermOfSaleHelp=You can upload the terms and conditions of sale file at the bottom of this setup page +WarningOnlineSignature=Please note that this function allows a person (customer, supplier...) to insert, online, the image of his signature in the PDF document. As for a handwritten signature, such a signature can be made by anyone and might not have the same legal value as a legal electronic signature system going through an authorized trusted third party. If you need this level of security, you can contact an integrator for more information or check for addons on www.dolistore.org. diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index 4e6e1feef22..e6f04f74572 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -421,6 +421,7 @@ InvoiceAutoValidate=Validate invoices automatically GeneratedFromRecurringInvoice=Generated from template recurring invoice %s DateIsNotEnough=Date not reached yet InvoiceGeneratedFromTemplate=Invoice %s generated from recurring template invoice %s +InvoiceGeneratedFromTemplateError=Error Invoice %s generated from recurring template invoice %s : %s GeneratedFromTemplate=Generated from template invoice %s WarningInvoiceDateInFuture=Warning, the invoice date is higher than current date WarningInvoiceDateTooFarInFuture=Warning, the invoice date is too far from current date @@ -522,6 +523,7 @@ SendTo=sent to PaymentByTransferOnThisBankAccount=Payment by transfer to the following bank account VATIsNotUsedForInvoice=* Non applicable VAT art-293B of CGI VATIsNotUsedForInvoiceAsso=* Non applicable VAT art-261-7 of CGI +VATIsNotUsedReverseChargeProcedure=* Non applicable VAT art-259-1 of CGI LawApplicationPart1=By application of the law 80.335 of 12/05/80 LawApplicationPart2=the goods remain the property of LawApplicationPart3=the seller until full payment of @@ -666,6 +668,7 @@ MentionCategoryOfOperations0=Delivery of goods MentionCategoryOfOperations1=Provision of services MentionCategoryOfOperations2=Mixed - Delivery of goods & provision of services Salaries=Salaries +InvoiceSubtype=Invoice Subtype SalaryInvoice=Salary BillsAndSalaries=Bills & Salaries CreateCreditNoteWhenClientInvoiceExists=This option is enabled only when validated invoice(s) exist for a customer or when constant INVOICE_CREDIT_NOTE_STANDALONE is used(useful for some countries) diff --git a/htdocs/langs/en_US/blockedlog.lang b/htdocs/langs/en_US/blockedlog.lang index 75ab23f6b73..3b399063ad2 100644 --- a/htdocs/langs/en_US/blockedlog.lang +++ b/htdocs/langs/en_US/blockedlog.lang @@ -7,7 +7,7 @@ BrowseBlockedLog=Unalterable logs ShowAllFingerPrintsMightBeTooLong=Show all archived logs (might be long) ShowAllFingerPrintsErrorsMightBeTooLong=Show all non-valid archive logs (might be long) DownloadBlockChain=Download fingerprints -KoCheckFingerprintValidity=Archived log entry is not valid. It means someone (a hacker?) has modified some data of this record after it was recorded, or has erased the previous archived record (check that line with previous # exists) or has modified checksum of the previous record. +KoCheckFingerprintValidity=Archived log entry is not valid. It means someone (a hacker?) has modified some data of this record after it was recorded, OR has erased the previous archived record (check that the line with previous # exists) OR has modified the checksum of the previous record. OkCheckFingerprintValidity=Archived log record is valid. The data on this line was not modified and the entry follows the previous one. OkCheckFingerprintValidityButChainIsKo=Archived log seems valid compared to previous one but the chain was corrupted previously. AddedByAuthority=Stored into remote authority @@ -18,9 +18,9 @@ BlockedlogInfoDialog=Log Details ListOfTrackedEvents=List of tracked events Fingerprint=Fingerprint DownloadLogCSV=Export archived logs (CSV) -DataOfArchivedEvent=Full data of archived event -DataOfArchivedEventHelp=This field contains the unalterable and structured data that was archived on real time. Even if some parent business event could have been purged or modified, the data archived here is the original data, and it can't be modified. -DataOfArchivedEventHelp2=Its integrity is guaranteed if the status of the line is OK +DataOfArchivedEvent=Complementary data of archived event +DataOfArchivedEventHelp=This field contains the complementary data that was archived on real time. Even if some parent business event could have been purged or modified, the data archived here is the original data, and it can't be modified. +DataOfArchivedEventHelp2=The integrity of data on each lines is guaranteed if the status of the line is OK ImpossibleToReloadObject=Original object (type %s, id %s) not linked (see 'Full datas' column to get unalterable saved data) BlockedLogAreRequiredByYourCountryLegislation=Unalterable Logs module may be required by the legislation of your country. Disabling this module may render any future transactions invalid with respect to the law and the use of legal software as they can not be validated by a tax audit. BlockedLogActivatedBecauseRequiredByYourCountryLegislation=Unalterable Logs module was activated because of the legislation of your country. Disabling this module may render any future transactions invalid with respect to the law and the use of legal software as they cannot be validated by a tax audit. diff --git a/htdocs/langs/en_US/categories.lang b/htdocs/langs/en_US/categories.lang index 8a18d426114..65a964564c7 100644 --- a/htdocs/langs/en_US/categories.lang +++ b/htdocs/langs/en_US/categories.lang @@ -91,10 +91,10 @@ CategoriesSetup=Tags/categories setup CategorieRecursiv=Link with parent tag/category automatically CategorieRecursivHelp=If option is on, when you add an object into a subcategory, the object will also be added into the parent categories. AddProductServiceIntoCategory=Assign category to the product/service -AddCustomerIntoCategory=Assign category to customer -AddSupplierIntoCategory=Assign category to supplier -AddFichinterIntoCategory=Assign category to interventional -AssignCategoryTo=Assign category to +AddCustomerIntoCategory=Assign the category to the customer +AddSupplierIntoCategory=Assign the category to the supplier +AddFichinterIntoCategory=Assign the category to the intervention +AssignCategoryTo=Assign the category to ShowCategory=Show tag/category ByDefaultInList=By default in list ChooseCategory=Choose category diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index ad0813153e1..bff22a33e9f 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -383,8 +383,8 @@ ExportCardToFormat=Export card to format ContactNotLinkedToCompany=Contact not linked to any third party DolibarrLogin=Dolibarr login NoDolibarrAccess=No Dolibarr access -ExportDataset_company_1=Third-parties (companies/foundations/physical people) and their properties -ExportDataset_company_2=Contacts and their properties +ExportDataset_company_1=Third-parties (organizations/natural persons) and attributes +ExportDataset_company_2=Third-parties additional contacts/addresses and attributes ExportDataset_company_3=Third-parties payment modes (bank accounts) ImportDataset_company_1=Third-parties and their properties ImportDataset_company_2=Third-parties additional contacts/addresses and attributes diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 1c6073a0189..302f4f0c0ed 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -140,7 +140,7 @@ ErrorBadValueForCode=Bad value for security code. Try again with new value... ErrorBothFieldCantBeNegative=Fields %s and %s can't be both negative ErrorFieldCantBeNegativeOnInvoice=Field %s cannot be negative on this type of invoice. If you need to add a discount line, just create the discount first (from field '%s' in third-party card) and apply it to the invoice. ErrorLinesCantBeNegativeForOneVATRate=Total of lines (net of tax) can't be negative for a given not null VAT rate (Found a negative total for VAT rate %s%%). -ErrorLinesCantBeNegativeOnDeposits=Lines can't be negative in a deposit. You will face problems when you will need to consume the deposit in final invoice if you do so. +ErrorLinesCantBeNegativeOnDeposits=Lines can't be negative in a down payment. You will face problems when you will need to consume the deposit in final invoice if you do so. ErrorQtyForCustomerInvoiceCantBeNegative=Quantity for line into customer invoices can't be negative ErrorQtyForSupplierInvoiceCantBeNegative=Quantity for line into supplier invoices can't be negative ErrorWebServerUserHasNotPermission=User account %s used to execute web server has no permission for that @@ -344,11 +344,12 @@ ErrorStartHourIsNull=Start date field cannot be empty ErrorTooManyLinesToProcessPleaseUseAMoreSelectiveFilter=Too many lines to process. Please use a more selective filter. ErrorEmptyValueForQty=Quantity cannot be zero. ErrorNoCloneWithoutName=The new user must have a name -ErrorNoCloneWithoutEmail=The new user must have a email -ErrorUserClone=Error when clone categories user +ErrorNoCloneWithoutEmail=The new user must have an email +ErrorUserClone=Error in user clone categories ErrorQtyOrderedLessQtyShipped = The quantity ordered cannot be less than the quantity shipped. ErrorVariousPaymentOnBankAccountWithADifferentCurrencyNotYetSupported=Error, creating a various payment on a bank account with a currency different than the currency of the company is not yet supported. ErrorStreamMustBeEnabled=The PHP stream %s is not available. Check your PHP modules and Dolibarr parameter $dolibarr_main_stream_to_disable. +ErrorYouTryToPayInvoicesWithDifferentCurrenciesInSamePayment=Error, you try to pay different invoices with different currencies in the same payment # Warnings WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup. WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user. diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index c2a7d07b030..b7ca6c62f19 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -32,7 +32,7 @@ NewMailing=New mass Email NewSMSing=New smsing EditMailing=Edit mass Email ResetMailing=Resend mass Email -ConfirmResetMailingTargetMassaction=Confirmation of the reset of targets statusin error +ConfirmResetMailingTargetMassaction=Confirmation of the reset of targets status in error ResetMailingTargetMassaction=Reset status in error DeleteMailing=Delete mass Email PreviewMailing=Preview mass Email diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 4b451e58c72..4099d762745 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -498,7 +498,7 @@ ActionRunningNotStarted=To start ActionRunningShort=In progress ActionDoneShort=Finished ActionUncomplete=Incomplete -LatestLinkedEvents=Latest %s linked events +LatestLinkedEvents=The last %s events CompanyFoundation=Company/Organization Accountant=Accountant ContactsForCompany=Contacts for this third party @@ -798,7 +798,7 @@ Notes=Notes AddNewLine=Add new line AddFile=Add file FreeZone=Free-text product -FreeLineOfType=Free-text item, type: +FreeLineOfType=Free-text item, type CloneMainAttributes=Clone object with its main attributes ReGeneratePDF=Re-generate PDF PDFMerge=PDF Merge @@ -1341,3 +1341,6 @@ Operator=Operator AllFieldsRequired=All fields are required. IsDefined=Is defined IsNotDefined=Is not defined +SpecialLine=Special Line +EcoTax=Eco-Tax +GroupingLine=Grouping line diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang index 22a9411997d..3c45a60d556 100644 --- a/htdocs/langs/fr_FR/main.lang +++ b/htdocs/langs/fr_FR/main.lang @@ -496,7 +496,7 @@ ActionRunningNotStarted=A réaliser ActionRunningShort=En cours ActionDoneShort=Terminé ActionUncomplete=Incomplet -LatestLinkedEvents=Les %s derniers événements liés +LatestLinkedEvents=Les %s derniers événements CompanyFoundation=Société/Organisation Accountant=Comptable ContactsForCompany=Contacts de ce tiers diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index cd06cb211ef..ac31dc344dd 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -284,7 +284,9 @@ class MyObject extends CommonObject { $resultcreate = $this->createCommon($user, $notrigger); - //$resultvalidate = $this->validate($user, $notrigger); + // uncomment lines below if you want to validate object after creation + // $this->fetch($this->id); // needed to retrieve some fields (ie date_creation for masked ref) + // $resultcreate = $this->validate($user, $notrigger); return $resultcreate; } diff --git a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php index 89e4ed53480..b9391aa6afa 100644 --- a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php +++ b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php @@ -143,7 +143,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'ORDER_CLASSIFY_UNBILLED': // TODO Replace it with ORDER_UNBILLED //case 'ORDER_SETDRAFT': //case 'LINEORDER_INSERT': - //case 'LINEORDER_UPDATE': + //case 'LINEORDER_MODIFY': //case 'LINEORDER_DELETE': // Supplier orders @@ -160,7 +160,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'ORDER_SUPPLIER_RECEIVE': //case 'LINEORDER_SUPPLIER_DISPATCH': //case 'LINEORDER_SUPPLIER_CREATE': - //case 'LINEORDER_SUPPLIER_UPDATE': + //case 'LINEORDER_SUPPLIER_MODIFY': //case 'LINEORDER_SUPPLIER_DELETE': // Proposals @@ -174,7 +174,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'PROPAL_CLOSE_REFUSED': //case 'PROPAL_DELETE': //case 'LINEPROPAL_INSERT': - //case 'LINEPROPAL_UPDATE': + //case 'LINEPROPAL_MODIFY': //case 'LINEPROPAL_DELETE': // SupplierProposal @@ -186,7 +186,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'SUPPLIER_PROPOSAL_CLOSE_REFUSED': //case 'SUPPLIER_PROPOSAL_DELETE': //case 'LINESUPPLIER_PROPOSAL_INSERT': - //case 'LINESUPPLIER_PROPOSAL_UPDATE': + //case 'LINESUPPLIER_PROPOSAL_MODIFY': //case 'LINESUPPLIER_PROPOSAL_DELETE': // Contracts @@ -197,7 +197,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'CONTRACT_CLOSE': //case 'CONTRACT_DELETE': //case 'LINECONTRACT_INSERT': - //case 'LINECONTRACT_UPDATE': + //case 'LINECONTRACT_MODIFY': //case 'LINECONTRACT_DELETE': // Bills @@ -210,7 +210,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'BILL_DELETE': //case 'BILL_PAYED': //case 'LINEBILL_INSERT': - //case 'LINEBILL_UPDATE': + //case 'LINEBILL_MODIFY': //case 'LINEBILL_DELETE': // Recurring Bills @@ -222,14 +222,14 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //Supplier Bill //case 'BILL_SUPPLIER_CREATE': - //case 'BILL_SUPPLIER_UPDATE': + //case 'BILL_SUPPLIER_MODIFY': //case 'BILL_SUPPLIER_DELETE': //case 'BILL_SUPPLIER_PAYED': //case 'BILL_SUPPLIER_UNPAYED': //case 'BILL_SUPPLIER_VALIDATE': //case 'BILL_SUPPLIER_UNVALIDATE': //case 'LINEBILL_SUPPLIER_CREATE': - //case 'LINEBILL_SUPPLIER_UPDATE': + //case 'LINEBILL_SUPPLIER_MODIFY': //case 'LINEBILL_SUPPLIER_DELETE': // Payments @@ -245,7 +245,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers // Donation //case 'DON_CREATE': - //case 'DON_UPDATE': + //case 'DON_MODIFY': //case 'DON_DELETE': // Interventions @@ -256,7 +256,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'FICHINTER_CLASSIFY_UNBILLED': // TODO Replace it with FICHINTER_UNBILLED //case 'FICHINTER_DELETE': //case 'LINEFICHINTER_CREATE': - //case 'LINEFICHINTER_UPDATE': + //case 'LINEFICHINTER_MODIFY': //case 'LINEFICHINTER_DELETE': // Members diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 6bde6bf10d1..864ad8adf9d 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -343,8 +343,14 @@ foreach ($search as $key => $val) { } $mode_search = 2; } - if ($search[$key] != '') { - $sql .= natural_search("t.".$db->sanitize($key), $search[$key], (($key == 'status') ? 2 : $mode_search)); + if (empty($object->fields[$key]['searchmulti'])) { + if (!is_array($search[$key]) && $search[$key] != '') { + $sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search)); + } + } else { + if (is_array($search[$key]) && !empty($search[$key])) { + $sql .= natural_search("t.".$db->escape($key), implode(',', $search[$key]), (($key == 'status') ? 2 : $mode_search)); + } } } else { if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') { @@ -632,7 +638,11 @@ foreach ($object->fields as $key => $val) { if (!empty($arrayfields['t.'.$key]['checked'])) { print '
'; if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { - print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), 1, 0, 0, '', 1, 0, 0, '', 'maxwidth100'.($key == 'status' ? ' search_status width100 onrightofpage' : ''), 1); + if (empty($val['searchmulti'])) { + print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), 1, 0, 0, '', 1, 0, 0, '', 'maxwidth100'.($key == 'status' ? ' search_status width100 onrightofpage' : ''), 1); + } else { + print $form->multiselectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), 0, 0, 'maxwidth100'.($key == 'status' ? ' search_status width100 onrightofpage' : ''), 1); + } } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) { print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth250', 1); } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { diff --git a/htdocs/mrp/js/lib_dispatch.js.php b/htdocs/mrp/js/lib_dispatch.js.php index c36c59b6f3b..d63cc494c2b 100644 --- a/htdocs/mrp/js/lib_dispatch.js.php +++ b/htdocs/mrp/js/lib_dispatch.js.php @@ -76,14 +76,14 @@ if (empty($dolibarr_nocache)) { * * @param index int index of product line. 0 = first product line * @param type string type of dispatch (batch = batch dispatch, dispatch = non batch dispatch) - * @param mode string 'qtymissing' will create new line with qty missing, 'lessone' will keep 1 in old line and the rest in new one + * @param mode string If mode is 'qtymissing' the split button will create a new line with qty missing, If 'lessone' it will keep 1 in old line and the rest in new one */ function addDispatchLine(index, type, mode) { mode = mode || 'qtymissing' console.log("mrp/js/lib_dispatch.js.php Split line type="+type+" index="+index+" mode="+mode); - if(mode == 'qtymissingconsume' || mode == 'allmissingconsume') { + if (mode == 'qtymissingconsume' || mode == 'allmissingconsume') { var inputId = 'qtytoconsume'; var warehouseId = 'idwarehouse'; } @@ -94,7 +94,10 @@ function addDispatchLine(index, type, mode) var nbrTrs = $("tr[name^='"+type+"_"+index+"']").length; // position of line for batch var $row = $("tr[name='"+type+'_'+index+"_1']").clone(true); // clone last batch line to jQuery object var qtyOrdered = parseFloat($("#qty_ordered_"+index).val()); // Qty ordered is same for all rows - var qty = parseFloat($("#"+inputId+"-"+index+"-"+nbrTrs).val()); + var qty = parseFloat($("#"+inputId+"-"+index+"-"+nbrTrs).val()); // qty entered in field to consume + + console.log("#"+inputId+"-"+index+"-"+nbrTrs+" => "+qty); + var qtyDispatched; if (mode === 'lessone') @@ -103,21 +106,22 @@ function addDispatchLine(index, type, mode) } else { - qtyDispatched = parseFloat($("#qty_dispatched_"+index).val()) + qty; console.log($("#qty_dispatched_"+index).val()); + qtyDispatched = parseFloat($("#qty_dispatched_"+index).val()) + qty; // If user did not reduced the qty to dispatch on old line, we keep only 1 on old line and the rest on new line if (qtyDispatched == qtyOrdered && qtyDispatched > 1) { qtyDispatched = parseFloat($("#qty_dispatched_" + index).val()) + 1; - } - if(mode == 'allmissingconsume' || mode == 'alltoproduce') { - var qtymax = parseFloat($($row).data('max-qty')); - if(qtymax === 'undefined') qtymax = 1; + if (mode == 'allmissingconsume' || mode == 'alltoproduce') { + var qtymax = parseFloat($($row).data('max-qty')); + if (qtymax === 'undefined') { + qtymax = 1; + } } } - if(mode == 'allmissingconsume' || mode == 'alltoproduce') { + if (mode == 'allmissingconsume' || mode == 'alltoproduce') { var count = 0; var qtyalreadyused = 0; var error = 0; @@ -141,11 +145,12 @@ function addDispatchLine(index, type, mode) $row = $("tr[name='" + type + '_' + index + "_1']").clone(true); } - if(error === 0) { + if (error === 0) { addDispatchTR(qtyOrdered, qtyDispatched, index, nbrTrs, warehouseId, inputId, type, '', mode, $row); } + } else { + addDispatchTR(qtyOrdered, qtyDispatched, index, nbrTrs, warehouseId, inputId, type, qty, mode, $row); } - else addDispatchTR(qtyOrdered, qtyDispatched, index, nbrTrs, warehouseId, inputId, type, qty, mode, $row) } diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php index 8f5e4080fa7..13f5aca1700 100644 --- a/htdocs/mrp/mo_production.php +++ b/htdocs/mrp/mo_production.php @@ -213,10 +213,21 @@ if (empty($reshook)) { $tmpproduct->fetch($moline->fk_product); if ($tmpproduct->type == Product::TYPE_SERVICE) { $moline->fk_default_workstation = $tmpproduct->fk_default_workstation; - } - $moline->disable_stock_change = ($tmpproduct->type == Product::TYPE_SERVICE ? 1 : 0); - if (getDolGlobalInt('PRODUCT_USE_UNITS')) { - $moline->fk_unit = $tmpproduct->fk_unit; + $moline->disable_stock_change = 1; + if ($tmpproduct->duration_unit) { + $moline->qty = $tmpproduct->duration_value; + include_once DOL_DOCUMENT_ROOT.'/core/class/cunits.class.php'; + $cunits = new CUnits($db); + $res = $cunits->fetch(0, '', $tmpproduct->duration_unit, 'time'); + if ($res > 0) { + $moline->fk_unit = $cunits->id; + } + } + } else { + $moline->disable_stock_change = 0; + if (getDolGlobalInt('PRODUCT_USE_UNITS')) { + $moline->fk_unit = $tmpproduct->fk_unit; + } } } // Extrafields @@ -494,7 +505,15 @@ if (empty($reshook)) { $moline->array_options["options_".$key] = $value; } $moline->qty = GETPOSTFLOAT('qty_lineProduce'); + if (GETPOSTISSET('warehouse_lineProduce')) { + $moline->fk_warehouse = (GETPOSTINT('warehouse_lineProduce') > 0 ? GETPOSTINT('warehouse_lineProduce') : 0); + } + if (GETPOSTISSET('workstation_lineProduce')) { + $moline->fk_default_workstation = (GETPOSTINT('workstation_lineProduce') > 0 ? GETPOSTINT('workstation_lineProduce') : 0); + } + $res = $moline->update($user); + if ($res < 0) { setEventMessages($moline->error, $moline->errors, 'errors'); header("Location: ".$_SERVER["PHP_SELF"].'?id='.$object->id); @@ -851,7 +870,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print ''."\n"; - print ''; + print ''; // Product print ''; // Qty @@ -863,7 +882,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; } // Qty already consumed - print ''; + print ''; // Warehouse print ''; // Unit - print ''; + print ''; // Cost price if ($permissiontoupdatecost && getDolGlobalString('MRP_SHOW_COST_FOR_CONSUMPTION')) { print ''; @@ -1085,8 +1110,13 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ' ' . price2num($alreadyconsumed, 'MS'); print ''; - // Entrepot + // Warehouse / Workstation print ''; // Stock @@ -1198,9 +1228,18 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; // Warehouse and/or workstation - print '
'.$langs->trans("Product").''.$langs->trans("UnitCost").''.$form->textwithpicto($langs->trans("QtyAlreadyConsumedShort"), $langs->trans("QtyAlreadyConsumed")).''; + print $langs->trans("QtyAlreadyConsumedShort"); + print ''; if ($collapse || in_array($action, array('consumeorproduce', 'consumeandproduceall'))) { @@ -928,7 +949,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Qty print ''; + if (getDolGlobalInt('PRODUCT_USE_UNITS')) { + //... + } + print ''; + if ($tmpproduct->type == Product::TYPE_PRODUCT) { + print $formproduct->selectWarehouses($line->fk_warehouse, 'warehouse_lineProduce', 'warehouseopen', 1); + } elseif (isModEnabled('workstation')) { + print $formproduct->selectWorkstations($line->fk_default_workstation, 'workstation_lineProduce', 1); + } print ''; - if (getDolGlobalString('STOCK_CONSUMPTION_FROM_MANUFACTURING_WAREHOUSE') && $tmpwarehouse->id > 0) { - print img_picto('', $tmpwarehouse->picto) . " " . $tmpwarehouse->label; + print ''; + if ($tmpproduct->isStockManaged()) { + // When STOCK_CONSUMPTION_FROM_MANUFACTURING_WAREHOUSE is set, we always use the warehouse of the MO, the same than production. + if (getDolGlobalString('STOCK_CONSUMPTION_FROM_MANUFACTURING_WAREHOUSE') && $tmpwarehouse->id > 0) { + print img_picto('', $tmpwarehouse->picto) . " " . $tmpwarehouse->label; + } else { + if ($line->fk_warehouse > 0) { + $warehouseline = new Entrepot($db); + $warehouseline->fetch($line->fk_warehouse); + print $warehouseline->getNomUrl(1); + } + } } if (isModEnabled('workstation') && $line->fk_default_workstation > 0) { $tmpworkstation = new Workstation($db); @@ -1499,7 +1538,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
'; print ''; - print ''; + print ''; // Product print ''; // Qty @@ -1511,13 +1550,19 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Cost price if ($permissiontoupdatecost) { if (empty($bomcostupdated)) { - print ''; + print ''; } else { - print ''; + print ''; } } // Already produced - print ''; + print ''; // Warehouse print ''; @@ -374,17 +374,19 @@ print 'Your API authentication information can be found with following steps. We print ''; if (!empty($conf->use_javascript_ajax)) { - print "\n".''; + print ' + + '; } print '

'; diff --git a/htdocs/paypal/lib/paypal.lib.php b/htdocs/paypal/lib/paypal.lib.php index 15ed29f8d9f..cd942116585 100644 --- a/htdocs/paypal/lib/paypal.lib.php +++ b/htdocs/paypal/lib/paypal.lib.php @@ -1,7 +1,8 @@ - * Copyright (C) 2011-2012 Regis Houssin - * Copyright (C) 2024 MDW +/* Copyright (C) 2008-2012 Laurent Destailleur + * Copyright (C) 2011-2012 Regis Houssin + * Copyright (C) 2024 MDW + * Copyright (C) 2024 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 @@ -467,22 +468,10 @@ function hash_call($methodName, $nvpStr) } // Clean parameters - $PAYPAL_API_USER = ""; - if (getDolGlobalString('PAYPAL_API_USER')) { - $PAYPAL_API_USER = getDolGlobalString('PAYPAL_API_USER'); - } - $PAYPAL_API_PASSWORD = ""; - if (getDolGlobalString('PAYPAL_API_PASSWORD')) { - $PAYPAL_API_PASSWORD = getDolGlobalString('PAYPAL_API_PASSWORD'); - } - $PAYPAL_API_SIGNATURE = ""; - if (getDolGlobalString('PAYPAL_API_SIGNATURE')) { - $PAYPAL_API_SIGNATURE = getDolGlobalString('PAYPAL_API_SIGNATURE'); - } - $PAYPAL_API_SANDBOX = ""; - if (getDolGlobalString('PAYPAL_API_SANDBOX')) { - $PAYPAL_API_SANDBOX = getDolGlobalString('PAYPAL_API_SANDBOX'); - } + $PAYPAL_API_USER = getDolGlobalString('PAYPAL_API_USER'); + $PAYPAL_API_PASSWORD = getDolGlobalString('PAYPAL_API_PASSWORD'); + $PAYPAL_API_SIGNATURE = getDolGlobalString('PAYPAL_API_SIGNATURE'); + $PAYPAL_API_SANDBOX = getDolGlobalString('PAYPAL_API_SANDBOX'); // TODO END problem with triggers dol_syslog("Paypal API endpoint ".$API_Endpoint); @@ -514,8 +503,8 @@ function hash_call($methodName, $nvpStr) curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, ($ssl_verifypeer ? true : false)); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, ($ssl_verifypeer ? true : false)); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, !getDolGlobalString('MAIN_USE_CONNECT_TIMEOUT') ? 5 : $conf->global->MAIN_USE_CONNECT_TIMEOUT); - curl_setopt($ch, CURLOPT_TIMEOUT, !getDolGlobalString('MAIN_USE_RESPONSE_TIMEOUT') ? 30 : $conf->global->MAIN_USE_RESPONSE_TIMEOUT); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, getDolGlobalInt('MAIN_USE_CONNECT_TIMEOUT', 5)); + curl_setopt($ch, CURLOPT_TIMEOUT, getDolGlobalInt('MAIN_USE_RESPONSE_TIMEOUT', 30)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); diff --git a/htdocs/paypal/lib/paypalfunctions.lib.php b/htdocs/paypal/lib/paypalfunctions.lib.php index b3a714489a2..eba524caab4 100644 --- a/htdocs/paypal/lib/paypalfunctions.lib.php +++ b/htdocs/paypal/lib/paypalfunctions.lib.php @@ -1,7 +1,8 @@ - * Copyright (C) 2011 Regis Houssin - * Copyright (C) 2024 MDW +/* Copyright (C) 2010-2011 Laurent Destailleur + * Copyright (C) 2011 Regis Houssin + * Copyright (C) 2024 MDW + * Copyright (C) 2024 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 @@ -57,22 +58,10 @@ if (getDolGlobalString('PAYPAL_API_SANDBOX') || GETPOST('forcesandbox', 'alpha') } // Clean parameters -$PAYPAL_API_USER = ""; -if (getDolGlobalString('PAYPAL_API_USER')) { - $PAYPAL_API_USER = getDolGlobalString('PAYPAL_API_USER'); -} -$PAYPAL_API_PASSWORD = ""; -if (getDolGlobalString('PAYPAL_API_PASSWORD')) { - $PAYPAL_API_PASSWORD = getDolGlobalString('PAYPAL_API_PASSWORD'); -} -$PAYPAL_API_SIGNATURE = ""; -if (getDolGlobalString('PAYPAL_API_SIGNATURE')) { - $PAYPAL_API_SIGNATURE = getDolGlobalString('PAYPAL_API_SIGNATURE'); -} -$PAYPAL_API_SANDBOX = ""; -if (getDolGlobalString('PAYPAL_API_SANDBOX')) { - $PAYPAL_API_SANDBOX = getDolGlobalString('PAYPAL_API_SANDBOX'); -} +$PAYPAL_API_USER = getDolGlobalString('PAYPAL_API_USER'); +$PAYPAL_API_PASSWORD = getDolGlobalString('PAYPAL_API_PASSWORD'); +$PAYPAL_API_SIGNATURE = getDolGlobalString('PAYPAL_API_SIGNATURE'); +$PAYPAL_API_SANDBOX = getDolGlobalString('PAYPAL_API_SANDBOX'); // Proxy $PROXY_HOST = getDolGlobalString('MAIN_PROXY_HOST'); diff --git a/htdocs/product/class/html.formproduct.class.php b/htdocs/product/class/html.formproduct.class.php index bc8a42046a2..2b2c1d0a198 100644 --- a/htdocs/product/class/html.formproduct.class.php +++ b/htdocs/product/class/html.formproduct.class.php @@ -335,6 +335,7 @@ class FormProduct } } + $out .= ''; $out .= '
'.$langs->trans("Product").''.$form->textwithpicto($langs->trans("UnitCost"), $langs->trans("AmountUsedToUpdateWAP")).''; + print $langs->trans("UnitCost"); + print ''.$form->textwithpicto($langs->trans("ManufacturingPrice"), $langs->trans("AmountUsedToUpdateWAP")).''; + print $langs->trans("ManufacturingPrice"); + print ''.$form->textwithpicto($langs->trans("QtyAlreadyProducedShort"), $langs->trans("QtyAlreadyProduced")).''; + print $langs->trans("QtyAlreadyProducedShort"); + print ''; if ($collapse || in_array($action, array('consumeorproduce', 'consumeandproduceall'))) { @@ -1700,6 +1745,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $href = $_SERVER["PHP_SELF"]; $href .= '?id='.$object->id; $href .= '&action=deleteline'; + $href .= '&token='.newToken(); $href .= '&lineid='.$line->id; print ''; print ''; diff --git a/htdocs/multicurrency/class/multicurrency.class.php b/htdocs/multicurrency/class/multicurrency.class.php index b02c662f514..8f4af567800 100644 --- a/htdocs/multicurrency/class/multicurrency.class.php +++ b/htdocs/multicurrency/class/multicurrency.class.php @@ -528,8 +528,6 @@ class MultiCurrency extends CommonObject */ public static function getIdAndTxFromCode($dbs, $code, $date_document = '') { - global $conf; - $sql1 = "SELECT m.rowid, mc.rate FROM ".MAIN_DB_PREFIX."multicurrency m"; $sql1 .= ' LEFT JOIN '.MAIN_DB_PREFIX.'multicurrency_rate mc ON (m.rowid = mc.fk_multicurrency)'; @@ -574,7 +572,8 @@ class MultiCurrency extends CommonObject if (!is_null($invoice_rate)) { $multicurrency_tx = $invoice_rate; } else { - $multicurrency_tx = self::getInvoiceRate($fk_facture, $table); + $tmparray = self::getInvoiceRate($fk_facture, $table); + $multicurrency_tx = $tmparray['invoice_multicurrency_tx']; } if ($multicurrency_tx) { @@ -593,18 +592,20 @@ class MultiCurrency extends CommonObject * * @param int $fk_facture id of facture * @param string $table facture or facture_fourn - * @return float|bool Rate of currency or false if error + * @return array{invoice_multicurrency_tx: float,invoice_multicurrency_code: string}|bool Rate and code of currency or false if error */ public static function getInvoiceRate($fk_facture, $table = 'facture') { global $db; - $sql = "SELECT multicurrency_tx FROM ".MAIN_DB_PREFIX.$table." WHERE rowid = ".((int) $fk_facture); + $sql = "SELECT multicurrency_tx, multicurrency_code"; + $sql .= " FROM ".MAIN_DB_PREFIX.$db->sanitize($table); + $sql .= " WHERE rowid = ".((int) $fk_facture); dol_syslog(__METHOD__, LOG_DEBUG); $resql = $db->query($sql); if ($resql && ($line = $db->fetch_object($resql))) { - return $line->multicurrency_tx; + return array('invoice_multicurrency_tx' => $line->multicurrency_tx, 'invoice_multicurrency_code' => $line->multicurrency_code); } return false; diff --git a/htdocs/opensurvey/card.php b/htdocs/opensurvey/card.php index 3bd4f303daf..f1dcd56ce4e 100644 --- a/htdocs/opensurvey/card.php +++ b/htdocs/opensurvey/card.php @@ -321,7 +321,7 @@ if ($action == 'edit') { print $form->selectDate($expiredate ? $expiredate : $object->date_fin, 'expire', 0, 0, 0, '', 1, 0); } else { print dol_print_date($object->date_fin, 'day'); - if ($object->date_fin && $object->date_fin < dol_now() && $object->status == Opensurveysondage::STATUS_VALIDATED) { + if ($object->date_fin && dol_get_last_hour($object->date_fin) < dol_now() && $object->status == Opensurveysondage::STATUS_VALIDATED) { print img_warning($langs->trans("Expired")); } } diff --git a/htdocs/paypal/admin/paypal.php b/htdocs/paypal/admin/paypal.php index 22a53c5d1ef..0c3f08e241d 100644 --- a/htdocs/paypal/admin/paypal.php +++ b/htdocs/paypal/admin/paypal.php @@ -267,7 +267,7 @@ if (isModEnabled("bank")) { print '
'; print $langs->trans("CSSUrlForPaymentForm").''; print ''; -print '   '.$langs->trans("Example").': http://mysite/mycss.css'; +print '   '.$langs->trans("Example").': https://mysite/mycss.css'; print '
"; + print '
'; print ''; print ""; @@ -102,7 +102,7 @@ if ($resql) { print "\n"; } print "\n"; - print ''; + print ''; print ""; $i++; } diff --git a/htdocs/public/fichinter/agendaexport.php b/htdocs/public/fichinter/agendaexport.php index a5c6f843041..c122767cf85 100644 --- a/htdocs/public/fichinter/agendaexport.php +++ b/htdocs/public/fichinter/agendaexport.php @@ -474,22 +474,22 @@ function build_exportfile($format, $type, $cachedelay, $filename, $filters) } if ($key == 'year') { $sql .= " AND fd.date BETWEEN '".$db->idate(dol_get_first_day($value, 1))."'"; - $sql .= " AND '".$db->idate(dol_get_last_day($value, 12))."'"; + $sql .= " AND '".$db->idate(dol_get_last_day($value, 12))."'"; } if ($key == 'id') { - $sql .= " AND f.rowid = ".(is_numeric($value) ? $value : 0); + $sql .= " AND f.rowid = ".((int) $value); } if ($key == 'idfrom') { - $sql .= " AND f.rowid >= ".(is_numeric($value) ? $value : 0); + $sql .= " AND f.rowid >= ".((int) $value); } if ($key == 'idto') { - $sql .= " AND f.rowid <= ".(is_numeric($value) ? $value : 0); + $sql .= " AND f.rowid <= ".((int) $value); } if ($key == 'project') { - $sql .= " AND f.fk_project = ".(is_numeric($value) ? $value : 0); + $sql .= " AND f.fk_project = ".((int) $value); } if ($key == 'contract') { - $sql .= " AND f.fk_contract = ".(is_numeric($value) ? $value : 0); + $sql .= " AND f.fk_contract = ".((int) $value); } if ($key == 'logina') { @@ -502,7 +502,7 @@ function build_exportfile($format, $type, $cachedelay, $filename, $filters) $userforfilter = new User($db); $result = $userforfilter->fetch(0, $logina); if ($result > 0) { - $sql .= " AND a.fk_user_author ".$condition." ".$userforfilter->id; + $sql .= " AND a.fk_user_author ".$condition." ".((int) $userforfilter->id); } elseif ($result < 0 || $condition == '=') { $sql .= " AND a.fk_user_author = 0"; } @@ -518,7 +518,7 @@ function build_exportfile($format, $type, $cachedelay, $filename, $filters) $result = $userforfilter->fetch(0, $logini); $sql .= " AND EXISTS (SELECT ec.rowid FROM ".MAIN_DB_PREFIX."element_contact as ec"; $sql .= " WHERE ec.element_id = f.rowid"; - $sql .= " AND ec.fk_c_type_contact = 26"; + $sql .= " AND ec.fk_c_type_contact = 26"; // FIXME do not use hardcoded ID if ($result > 0) { $sql .= " AND ec.fk_socpeople = ".((int) $userforfilter->id); } elseif ($result < 0 || $condition == '=') { @@ -537,7 +537,7 @@ function build_exportfile($format, $type, $cachedelay, $filename, $filters) $result = $userforfilter->fetch(0, $loginr); $sql .= " AND EXISTS (SELECT ecr.rowid FROM ".MAIN_DB_PREFIX."element_contact as ecr"; $sql .= " WHERE ecr.element_id = f.rowid"; - $sql .= " WHERE AND ecr.fk_c_type_contact = 27"; + $sql .= " WHERE AND ecr.fk_c_type_contact = 27"; // FIXME do not use hardcoded ID if ($result > 0) { $sql .= " AND ecr.fk_socpeople = ".((int) $userforfilter->id); } elseif ($result < 0 || $condition == '=') { diff --git a/htdocs/public/members/public_list.php b/htdocs/public/members/public_list.php index 5445587309c..0df9b10a12b 100644 --- a/htdocs/public/members/public_list.php +++ b/htdocs/public/members/public_list.php @@ -168,10 +168,6 @@ if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) { $sql .= $db->order($sortfield, $sortorder); $sql .= $db->plimit($conf->liste_limit + 1, $offset); -//$sql = "SELECT d.rowid, d.firstname, d.lastname, d.societe, zip, town, d.email, t.libelle as type, d.morphy, d.statut, t.subscription"; -//$sql .= " FROM ".MAIN_DB_PREFIX."adherent as d, ".MAIN_DB_PREFIX."adherent_type as t"; -//$sql .= " WHERE d.fk_adherent_type = t.rowid AND d.statut = $statut"; -//$sql .= " ORDER BY $sortfield $sortorder " . $db->plimit($conf->liste_limit, $offset); $result = $db->query($sql); diff --git a/htdocs/public/onlinesign/newonlinesign.php b/htdocs/public/onlinesign/newonlinesign.php index 802d8996853..17506fc264a 100644 --- a/htdocs/public/onlinesign/newonlinesign.php +++ b/htdocs/public/onlinesign/newonlinesign.php @@ -194,7 +194,7 @@ if ($action == 'confirm_refusepropal' && $confirm == 'yes') { // Test on pemriss $db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; - $sql .= " SET fk_statut = ".((int) $object::STATUS_NOTSIGNED).", note_private = '".$db->escape($object->note_private)."', date_signature='".$db->idate(dol_now())."'"; + $sql .= " SET fk_statut = ".((int) $object::STATUS_NOTSIGNED).", note_private = '".$db->escape($object->note_private)."', date_signature = '".$db->idate(dol_now())."'"; $sql .= " WHERE rowid = ".((int) $object->id); dol_syslog(__FILE__, LOG_DEBUG); diff --git a/htdocs/public/opensurvey/studs.php b/htdocs/public/opensurvey/studs.php index 37051fda92d..bd8e73efa7f 100644 --- a/htdocs/public/opensurvey/studs.php +++ b/htdocs/public/opensurvey/studs.php @@ -65,7 +65,7 @@ $result = $object->fetch(0, $numsondage); $nblines = $object->fetch_lines(); //If the survey has not yet finished, then it can be modified -$canbemodified = ((empty($object->date_fin) || $object->date_fin > dol_now()) && $object->status != Opensurveysondage::STATUS_CLOSED); +$canbemodified = ((empty($object->date_fin) || dol_get_last_hour($object->date_fin) > dol_now()) && $object->status != Opensurveysondage::STATUS_CLOSED); // Security check if (!isModEnabled('opensurvey')) { @@ -191,7 +191,7 @@ if (GETPOST("boutonp") || GETPOST("boutonp.x") || GETPOST("boutonp_x")) { // bo // Check if vote already exists $sql = 'SELECT id_users, nom as name'; $sql .= ' FROM '.MAIN_DB_PREFIX.'opensurvey_user_studs'; - $sql .= " WHERE id_sondage='".$db->escape($numsondage)."' AND nom = '".$db->escape($nom)."' ORDER BY id_users"; + $sql .= " WHERE id_sondage = '".$db->escape($numsondage)."' AND nom = '".$db->escape($nom)."' ORDER BY id_users"; $resql = $db->query($sql); if (!$resql) { dol_print_error($db); diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 54af1723370..94c1ae17167 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -231,6 +231,12 @@ $ref = $REF = GETPOST('ref', 'alpha'); $TAG = GETPOST("tag", 'alpha'); $FULLTAG = GETPOST("fulltag", 'alpha'); // fulltag is tag with more information $SECUREKEY = GETPOST("securekey"); // Secure key +$PAYPAL_API_OK = ""; +$PAYPAL_API_KO = ""; +$PAYPAL_API_SANDBOX = ""; +$PAYPAL_API_USER = ""; +$PAYPAL_API_PASSWORD = ""; +$PAYPAL_API_SIGNATURE = ""; if ($paymentmethod && !preg_match('/'.preg_quote('PM='.$paymentmethod, '/').'/', $FULLTAG)) { $FULLTAG .= ($FULLTAG ? '.' : '').'PM='.$paymentmethod; @@ -286,6 +292,7 @@ $urlko = preg_replace('/&$/', '', $urlko); // Remove last & '; if ((empty($paymentmethod) || $paymentmethod == 'paypal') && isModEnabled('paypal')) { + global $PAYPAL_API_SANDBOX, $PAYPAL_API_OK, $PAYPAL_API_KO, $PAYPAL_API_USER, $PAYPAL_API_PASSWORD, $PAYPAL_API_SIGNATURE; require_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php'; require_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypalfunctions.lib.php'; @@ -1554,9 +1561,8 @@ if ($source == 'member' || $source == 'membersubscription') { $member = new Adherent($db); $adht = new AdherentType($db); - $subscription = new Subscription($db); - $result = $member->fetch(0, $ref); + $result = $member->fetch(0, $ref, 0, '', true, true); // This fetch also ->last_subscription_amount if ($result <= 0) { $mesg = $member->error; $error++; @@ -1568,7 +1574,7 @@ if ($source == 'member' || $source == 'membersubscription') { $object = $member; if ($action != 'dopayment') { // Do not change amount if we just click on first dopayment - $amount = $subscription->total_ttc; + $amount = $member->last_subscription_amount; if (GETPOST("amount", 'alpha')) { $amount = price2num(GETPOST("amount", 'alpha'), 'MT', 2); } @@ -1705,6 +1711,10 @@ if ($source == 'member' || $source == 'membersubscription') { if (empty($amount) && getDolGlobalString('MEMBER_NEWFORM_AMOUNT')) { $amount = getDolGlobalString('MEMBER_NEWFORM_AMOUNT'); } + // - If an amount was posted from the form (for example from page with types of membership) + if ($caneditamount && GETPOSTISSET('amount') && GETPOSTFLOAT('amount', 'MT') > 0) { + $amount = GETPOSTFLOAT('amount', 'MT'); + } // - If a new amount was posted from the form if ($caneditamount && GETPOSTISSET('newamount') && GETPOSTFLOAT('newamount', 'MT') > 0) { $amount = GETPOSTFLOAT('newamount', 'MT'); diff --git a/htdocs/public/payment/paymentko.php b/htdocs/public/payment/paymentko.php index f99deda6845..a8ae18fb64d 100644 --- a/htdocs/public/payment/paymentko.php +++ b/htdocs/public/payment/paymentko.php @@ -71,7 +71,8 @@ if (isModEnabled('paypal')) { */ $langs->loadLangs(array("main", "other", "dict", "bills", "companies", "paybox", "paypal", "stripe")); - +$PAYPALTOKEN = ""; +$PAYPALPAYERID = ""; if (isModEnabled('paypal')) { $PAYPALTOKEN = GETPOST('TOKEN'); if (empty($PAYPALTOKEN)) { diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 8fa92e88b89..972c78675ba 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -77,23 +77,17 @@ $hookmanager->initHooks(array('newpayment')); $langs->loadLangs(array("main", "other", "dict", "bills", "companies", "paybox", "paypal", "stripe")); // Clean parameters +$PAYPAL_API_USER = ""; +$PAYPAL_API_PASSWORD = ""; +$PAYPAL_API_SIGNATURE = ""; +$PAYPAL_API_SANDBOX = ""; +$PAYPALTOKEN = ""; +$PAYPALPAYERID = ""; if (isModEnabled('paypal')) { - $PAYPAL_API_USER = ""; - if (getDolGlobalString('PAYPAL_API_USER')) { - $PAYPAL_API_USER = getDolGlobalString('PAYPAL_API_USER'); - } - $PAYPAL_API_PASSWORD = ""; - if (getDolGlobalString('PAYPAL_API_PASSWORD')) { - $PAYPAL_API_PASSWORD = getDolGlobalString('PAYPAL_API_PASSWORD'); - } - $PAYPAL_API_SIGNATURE = ""; - if (getDolGlobalString('PAYPAL_API_SIGNATURE')) { - $PAYPAL_API_SIGNATURE = getDolGlobalString('PAYPAL_API_SIGNATURE'); - } - $PAYPAL_API_SANDBOX = ""; - if (getDolGlobalString('PAYPAL_API_SANDBOX')) { - $PAYPAL_API_SANDBOX = getDolGlobalString('PAYPAL_API_SANDBOX'); - } + $PAYPAL_API_USER = getDolGlobalString('PAYPAL_API_USER'); + $PAYPAL_API_PASSWORD = getDolGlobalString('PAYPAL_API_PASSWORD'); + $PAYPAL_API_SIGNATURE = getDolGlobalString('PAYPAL_API_SIGNATURE'); + $PAYPAL_API_SANDBOX = getDolGlobalString('PAYPAL_API_SANDBOX'); /*$PAYPAL_API_OK = ""; if ($urlok) { $PAYPAL_API_OK = $urlok; @@ -173,17 +167,23 @@ $object = new stdClass(); // For triggers $error = 0; +// Check if we have redirtodomain to do. +$ws_virtuelhost = null; +if ($ws) { + $doactionsthenredirect = 1; + include_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php'; + $website = new Website($db); + $result = $website->fetch(0, $ws); + if ($result > 0) { + $ws_virtuelhost = $website->virtualhost; + } +} + /* * Actions and view */ -// Check if we have redirtodomain to do. -if ($ws) { - $doactionsthenredirect = 1; -} - - $now = dol_now(); dol_syslog("Callback url when a payment was done. query_string=".(empty($_SERVER["QUERY_STRING"]) ? '' : dol_escape_htmltag($_SERVER["QUERY_STRING"]))." script_uri=".(empty($_SERVER["SCRIPT_URI"]) ? '' : dol_escape_htmltag($_SERVER["SCRIPT_URI"])), LOG_DEBUG, 0, '_payment'); @@ -278,11 +278,11 @@ if (empty($doactionsthenredirect)) { // Another step to validate the payment (for payment modes like Paypal that need another step after the callback return for this). if (isModEnabled('paypal') && $paymentmethod === 'paypal') { // We call this page only if payment is ok on payment system - if ($PAYPALTOKEN) { + if (!empty($PAYPALTOKEN)) { // Get on url call $onlinetoken = $PAYPALTOKEN; $fulltag = $FULLTAG; - $payerID = $PAYPALPAYERID; + $payerID = !empty($PAYPALPAYERID) ? $PAYPALPAYERID : ''; // Set by newpayment.php $currencyCodeType = $_SESSION['currencyCodeType']; $FinalPaymentAmt = $_SESSION["FinalPaymentAmt"]; @@ -740,7 +740,7 @@ if ($ispaymentok) { } } else { $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_account (fk_soc, login, key_account, site, site_account, status, entity, date_creation, fk_user_creat)"; - $sql .= " VALUES (".$thirdparty_id.", '', '".$db->escape($stripecu)."', 'stripe', '".$db->escape($stripearrayofkeysbyenv[$servicestatus]['publishable_key'])."', ".((int) $servicestatus).", ".((int) $conf->entity).", '".$db->idate(dol_now())."', 0)"; + $sql .= " VALUES (".((int) $thirdparty_id).", '', '".$db->escape($stripecu)."', 'stripe', '".$db->escape($stripearrayofkeysbyenv[$servicestatus]['publishable_key'])."', ".((int) $servicestatus).", ".((int) $conf->entity).", '".$db->idate(dol_now())."', 0)"; $resql = $db->query($sql); if (!$resql) { // should not happen $error++; @@ -2124,12 +2124,20 @@ if (!empty($doactionsthenredirect)) { if ($ispaymentok) { // Redirect to a success page // Paymentok page must be created for the specific website - $ext_urlok = DOL_URL_ROOT.'/public/website/index.php?website='.urlencode($ws).'&pageref=paymentok&fulltag='.$FULLTAG; + if (!defined('USEDOLIBARRSERVER') && !empty($ws_virtuelhost)) { + $ext_urlok = $ws_virtuelhost . '/paymentok.php?fulltag='.$FULLTAG; + } else { + $ext_urlok = DOL_URL_ROOT.'/public/website/index.php?website='.urlencode($ws).'&pageref=paymentok&fulltag='.$FULLTAG; + } print ""; } else { // Redirect to an error page // Paymentko page must be created for the specific website - $ext_urlko = DOL_URL_ROOT.'/public/website/index.php?website='.urlencode($ws).'&pageref=paymentko&fulltag='.$FULLTAG; + if (!defined('USEDOLIBARRSERVER') && !empty($ws_virtuelhost)) { + $ext_urlko = $ws_virtuelhost . '/paymentko.php?fulltag='.$FULLTAG; + } else { + $ext_urlko = DOL_URL_ROOT.'/public/website/index.php?website='.urlencode($ws).'&pageref=paymentko&fulltag='.$FULLTAG; + } print ""; } } diff --git a/htdocs/public/project/viewandvote.php b/htdocs/public/project/viewandvote.php index 47d5893ae8a..5b9404e2515 100644 --- a/htdocs/public/project/viewandvote.php +++ b/htdocs/public/project/viewandvote.php @@ -122,8 +122,8 @@ $listOfConferences .= ''; $sql = "SELECT a.id, a.fk_action, a.datep, a.datep2, a.label, a.fk_soc, a.note, ca.libelle as label FROM ".MAIN_DB_PREFIX."actioncomm as a - INNER JOIN ".MAIN_DB_PREFIX."c_actioncomm as ca ON (a.fk_action=ca.id) - WHERE a.status<2"; + INNER JOIN ".MAIN_DB_PREFIX."c_actioncomm as ca ON (a.fk_action = ca.id) + WHERE a.status < 2"; $sqlforconf = $sql." AND ca.module='conference@eventorganization'"; //$sqlforbooth = $sql." AND ca.module='booth@eventorganization'"; diff --git a/htdocs/public/recruitment/view.php b/htdocs/public/recruitment/view.php index bdcf71420c2..87127f7f906 100644 --- a/htdocs/public/recruitment/view.php +++ b/htdocs/public/recruitment/view.php @@ -139,7 +139,7 @@ if ($action == "dosubmit") { // Test on permission not required here (anonymous if (!$error) { $sql = "SELECT rrc.rowid FROM ".MAIN_DB_PREFIX."recruitment_recruitmentcandidature as rrc"; $sql .= " WHERE rrc.email = '". $db->escape($email)."'"; - $sql .= " AND rrc.entity = ". getEntity($object->element, 0); + $sql .= " AND rrc.entity IN (". getEntity($object->element, 0).")"; $resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index 9e547eacb6c..0a2c982258d 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -321,7 +321,7 @@ if ($event->type == 'payout.created') { } elseif ($event->type == 'customer.deleted') { // When a customer account is delete on Stripe side $db->begin(); - $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_account WHERE key_account = '".$db->escape($event->data->object->id)."' and site='stripe'"; + $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_account WHERE key_account = '".$db->escape($event->data->object->id)."' AND site = 'stripe'"; $db->query($sql); $db->commit(); } elseif ($event->type == 'payment_intent.succeeded') { diff --git a/htdocs/public/ticket/list.php b/htdocs/public/ticket/list.php index 86645c9a6ec..c835bdd1cf2 100644 --- a/htdocs/public/ticket/list.php +++ b/htdocs/public/ticket/list.php @@ -98,7 +98,6 @@ if (!isModEnabled('ticket')) { } - /* * Actions */ @@ -397,26 +396,26 @@ if ($action == "view_ticketlist") { } $sql .= " WHERE t.entity IN (".getEntity('ticket').")"; $sql .= " AND ((tc.source = 'external'"; - $sql .= " AND tc.element='".$db->escape($object->element)."'"; - $sql .= " AND tc.active=1"; - $sql .= " AND sp.email='".$db->escape($_SESSION['email_customer'])."')"; // email found into an external contact - $sql .= " OR s.email='".$db->escape($_SESSION['email_customer'])."'"; // or email of the linked company - $sql .= " OR t.origin_email='".$db->escape($_SESSION['email_customer'])."')"; // or email of the requester + $sql .= " AND tc.element = '".$db->escape($object->element)."'"; + $sql .= " AND tc.active = 1"; + $sql .= " AND sp.email = '".$db->escape($_SESSION['email_customer'])."')"; // email found into an external contact + $sql .= " OR s.email = '".$db->escape($_SESSION['email_customer'])."'"; // or email of the linked company + $sql .= " OR t.origin_email = '".$db->escape($_SESSION['email_customer'])."')"; // or email of the requester // Manage filter if (!empty($filter)) { foreach ($filter as $key => $value) { if (strpos($key, 'date')) { // To allow $filter['YEAR(s.dated)']=>$year - $sql .= " AND ".$key." = '".$db->escape($value)."'"; + $sql .= " AND ".$db->sanitize($key)." = '".$db->escape($value)."'"; } elseif (($key == 't.fk_user_assign') || ($key == 't.type_code') || ($key == 't.category_code') || ($key == 't.severity_code')) { - $sql .= " AND ".$key." = '".$db->escape($value)."'"; + $sql .= " AND ".$db->sanitize($key)." = '".$db->escape($value)."'"; } elseif ($key == 't.fk_statut') { if (is_array($value) && count($value) > 0) { - $sql .= " AND ".$key." IN (".$db->sanitize(implode(',', $value)).")"; + $sql .= " AND ".$db->sanitize($key)." IN (".$db->sanitize(implode(',', $value)).")"; } else { - $sql .= " AND ".$key." = ".((int) $value); + $sql .= " AND ".$db->sanitize($key)." = ".((int) $value); } } else { - $sql .= " AND ".$key." LIKE '%".$db->escape($value)."%'"; + $sql .= " AND ".$db->sanitize($key)." LIKE '%".$db->escape($value)."%'"; } } } diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 86e8d046ff9..22c1ad326ba 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -647,8 +647,7 @@ class Reception extends CommonObject if (intval($result) < 0) { $error++; - $this->errors[] = $mouvS->error; - $this->errors = array_merge($this->errors, $mouvS->errors); + $this->setErrorsFromObject($mouvS); break; } } else { @@ -661,8 +660,7 @@ class Reception extends CommonObject if (intval($result) < 0) { $error++; - $this->errors[] = $mouvS->error; - $this->errors = array_merge($this->errors, $mouvS->errors); + $this->setErrorsFromObject($mouvS); break; } } @@ -809,8 +807,7 @@ class Reception extends CommonObject $ret = $supplierorderdispatch->fetchAll('', '', 0, 0, $filter); if ($ret < 0) { - $this->error = $supplierorderdispatch->error; - $this->errors = $supplierorderdispatch->errors; + $this->setErrorsFromObject($supplierorderdispatch); return $ret; } else { // build array with quantity received by product in all supplier orders (origin) @@ -895,8 +892,7 @@ class Reception extends CommonObject $supplierorderline = new CommandeFournisseurLigne($this->db); $result = $supplierorderline->fetch($id); if ($result <= 0) { - $this->error = $supplierorderline->error; - $this->errors = $supplierorderline->errors; + $this->setErrorsFromObject($supplierorderline); return -1; } diff --git a/htdocs/recruitment/class/recruitmentcandidature.class.php b/htdocs/recruitment/class/recruitmentcandidature.class.php index 30ce84dfe04..ed7aa6f3934 100644 --- a/htdocs/recruitment/class/recruitmentcandidature.class.php +++ b/htdocs/recruitment/class/recruitmentcandidature.class.php @@ -103,7 +103,7 @@ class RecruitmentCandidature extends CommonObject 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'comment' => "Id"), 'entity' => array('type' => 'integer', 'label' => 'Entity', 'enabled' => 1, 'visible' => 0, 'position' => 5, 'notnull' => 1, 'default' => '1', 'index' => 1), 'ref' => array('type' => 'varchar(128)', 'label' => 'Ref', 'enabled' => 1, 'position' => 10, 'notnull' => 1, 'visible' => 4, 'noteditable' => 1, 'default' => '(PROV)', 'index' => 1, 'searchall' => 1, 'showoncombobox' => 1, 'comment' => "Reference of candidature", 'csslist' => 'nowraponall'), - 'fk_recruitmentjobposition' => array('type' => 'integer:RecruitmentJobPosition:recruitment/class/recruitmentjobposition.class.php:0:(t.status:=:1)', 'label' => 'Job', 'enabled' => 1, 'position' => 15, 'notnull' => 0, 'visible' => 1, 'index' => 1, 'picto' => 'recruitmentjobposition', 'css' => 'minwidth300 maxwidth500 widthcentpercentminusx', 'csslist' => 'minwidth100 nowraponall'), + 'fk_recruitmentjobposition' => array('type' => 'integer:RecruitmentJobPosition:recruitment/class/recruitmentjobposition.class.php:0', 'label' => 'Job', 'enabled' => '1', 'position' => 15, 'notnull' => 0, 'visible' => 1, 'index' => 1, 'picto' => 'recruitmentjobposition', 'css' => 'minwidth300 maxwidth500 widthcentpercentminusx', 'csslist' => 'minwidth100 nowraponall'), 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 61, 'notnull' => 0, 'visible' => 0,), 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 62, 'notnull' => 0, 'visible' => 0,), 'fk_user_creat' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'position' => 510, 'notnull' => -1, 'visible' => -2, 'foreignkey' => 'user.rowid', 'csslist' => 'tdoverflowmax100'), @@ -224,7 +224,7 @@ class RecruitmentCandidature extends CommonObject */ public function __construct(DoliDB $db) { - global $conf, $langs; + global $langs; $this->db = $db; diff --git a/htdocs/recruitment/class/recruitmentjobposition.class.php b/htdocs/recruitment/class/recruitmentjobposition.class.php index 0e5a14e12ea..bb64a3ccb34 100644 --- a/htdocs/recruitment/class/recruitmentjobposition.class.php +++ b/htdocs/recruitment/class/recruitmentjobposition.class.php @@ -552,20 +552,12 @@ class RecruitmentJobPosition extends CommonObject return 0; } - /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitmentjobposition->create)) - || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitmentjobposition->recruitmentjobposition_advance->validate)))) - { - $this->error='NotEnoughPermissions'; - dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); - return -1; - }*/ - $now = dol_now(); $this->db->begin(); // Define new ref - if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life + if (/* !$error && */ (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life $num = $this->getNextNumRef(); } else { $num = $this->ref; @@ -765,14 +757,12 @@ class RecruitmentJobPosition extends CommonObject $this->generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } - if (!$error) { - $this->oldcopy = clone $this; - $this->status = $status; - $this->date_cloture = $now; - $this->note_private = $newprivatenote; - } + $this->oldcopy = clone $this; + $this->status = $status; + $this->date_cloture = $now; + $this->note_private = $newprivatenote; - if (!$notrigger && empty($error)) { + if (!$notrigger /* && empty($error) */) { // Call trigger $result = $this->call_trigger($triggerName, $user); if ($result < 0) { diff --git a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php index 475cb21f216..7402190de2b 100644 --- a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php +++ b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php @@ -210,8 +210,9 @@ class pdf_standard_recruitmentjobposition extends ModelePDFRecruitmentJobPositio // Load translation files required by the page $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies")); + global $outputlangsbis; + $outputlangsbis = null; if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && $outputlangs->defaultlang != getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE')) { - global $outputlangsbis; $outputlangsbis = new Translate('', $conf); $outputlangsbis->setDefaultLang(getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE')); $outputlangsbis->loadLangs(array("main", "bills", "products", "dict", "companies")); diff --git a/htdocs/recruitment/core/modules/recruitment/mod_recruitmentcandidature_advanced.php b/htdocs/recruitment/core/modules/recruitment/mod_recruitmentcandidature_advanced.php index e5feff9f403..5be97a45988 100644 --- a/htdocs/recruitment/core/modules/recruitment/mod_recruitmentcandidature_advanced.php +++ b/htdocs/recruitment/core/modules/recruitment/mod_recruitmentcandidature_advanced.php @@ -82,7 +82,7 @@ class mod_recruitmentcandidature_advanced extends ModeleNumRefRecruitmentCandida // Parametrage du prefix $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; diff --git a/htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php b/htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php index e7d6b1d918c..0ada1a5e802 100644 --- a/htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php +++ b/htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php @@ -82,7 +82,7 @@ class mod_recruitmentjobposition_advanced extends ModeleNumRefRecruitmentJobPosi // Parametrage du prefix $texte .= ''; - $texte .= ''; + $texte .= ''; $texte .= ''; diff --git a/htdocs/recruitment/recruitmentcandidature_card.php b/htdocs/recruitment/recruitmentcandidature_card.php index fe80fcb63de..b47557d5f45 100644 --- a/htdocs/recruitment/recruitmentcandidature_card.php +++ b/htdocs/recruitment/recruitmentcandidature_card.php @@ -97,6 +97,17 @@ $isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); $result = restrictedArea($user, 'recruitment', $object->id, 'recruitment_recruitmentcandidature', 'recruitmentjobposition', '', 'rowid', $isdraft); +if (GETPOST("action", "aZ09") == 'create') { + $reg = array(); + preg_match('/^(integer|link):(.*):(.*):(.*):(.*)/i', $object->fields['fk_recruitmentjobposition']['type'], $reg); + if (!empty($reg)) { + $object->fields['fk_recruitmentjobposition']['type'] .= " AND (t.status:=:1)"; + } else { + $object->fields['fk_recruitmentjobposition']['type'] .= ":(t.status:=:1)"; + } +} + + /* * Actions */ diff --git a/htdocs/salaries/class/salary.class.php b/htdocs/salaries/class/salary.class.php index a70fce80e07..e0d3abf655c 100644 --- a/htdocs/salaries/class/salary.class.php +++ b/htdocs/salaries/class/salary.class.php @@ -120,6 +120,7 @@ class Salary extends CommonObject /** * @var int + * @deprecated see $accountid * @see $accountid */ public $fk_account; @@ -154,7 +155,7 @@ class Salary extends CommonObject const STATUS_PAID = 1; /** - * @var string + * @var float amount remain to pay */ public $resteapayer; diff --git a/htdocs/salaries/list.php b/htdocs/salaries/list.php index c26a609536b..f72c3a4512f 100644 --- a/htdocs/salaries/list.php +++ b/htdocs/salaries/list.php @@ -193,8 +193,8 @@ if ($massaction == 'withdrawrequest') { $objecttmp = new Salary($db); $result = $objecttmp->fetch($toselectid); if ($result > 0) { - $totalpaid = $objecttmp->getSommePaiement(); - $objecttmp->resteapayer = price2num((float) $objecttmp->amount - $totalpaid, 'MT'); + $totalpaid = (float) $objecttmp->getSommePaiement(); + $objecttmp->resteapayer = (float) price2num((float) $objecttmp->amount - $totalpaid, 'MT'); // hook to finalize the remaining amount, considering e.g. cash discount agreements $parameters = array('remaintopay' => $objecttmp->resteapayer); @@ -211,7 +211,7 @@ if ($massaction == 'withdrawrequest') { if ($objecttmp->status == Salary::STATUS_PAID || $objecttmp->resteapayer == 0) { $error++; setEventMessages($langs->trans("Salary").' '.$objecttmp->ref.' : '.$langs->trans("AlreadyPaid"), $objecttmp->errors, 'errors'); - } elseif ($resteapayer < 0) { + } elseif ($objecttmp->resteapayer < 0) { $error++; setEventMessages($langs->trans("Salary").' '.$objecttmp->ref.' : '.$langs->trans("AmountMustBePositive"), $objecttmp->errors, 'errors'); } diff --git a/htdocs/salaries/paiement_salary.php b/htdocs/salaries/paiement_salary.php index fcb4cb9ad53..f084e5e1a07 100644 --- a/htdocs/salaries/paiement_salary.php +++ b/htdocs/salaries/paiement_salary.php @@ -167,6 +167,7 @@ $help_url = ''; llxHeader('', '', $help_url); $salary = $object; +$sumpaid = 0.0; // Formulaire de creation d'un paiement de charge if ($action == 'create') { @@ -214,7 +215,7 @@ if ($action == 'create') { $resql = $db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); - $sumpaid = $obj->total; + $sumpaid = (float) $obj->total; $db->free($resql); } /*print ''; diff --git a/htdocs/societe/canvas/company/tpl/card_create.tpl.php b/htdocs/societe/canvas/company/tpl/card_create.tpl.php index 379abf2e8cc..dc2ef93fc6f 100644 --- a/htdocs/societe/canvas/company/tpl/card_create.tpl.php +++ b/htdocs/societe/canvas/company/tpl/card_create.tpl.php @@ -1,6 +1,6 @@ - * Copyright (C) 2010-2012 Laurent Destailleur +/* Copyright (C) 2010 Regis Houssin + * Copyright (C) 2010-2012 Laurent Destailleur * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -18,10 +18,13 @@ */ /** + * @var Canvas $this * @var Conf $conf * @var CommonObject $this * @var Translate $langs * @var User $user + * + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/societe/canvas/company/tpl/card_edit.tpl.php b/htdocs/societe/canvas/company/tpl/card_edit.tpl.php index 5143b84ea73..03a353f7eb8 100644 --- a/htdocs/societe/canvas/company/tpl/card_edit.tpl.php +++ b/htdocs/societe/canvas/company/tpl/card_edit.tpl.php @@ -18,10 +18,12 @@ */ /** + * @var Canvas $this * @var Conf $conf * @var CommonObject $this * @var Translate $langs * @var User $user + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/societe/canvas/company/tpl/card_view.tpl.php b/htdocs/societe/canvas/company/tpl/card_view.tpl.php index 82191b9faa0..f1246e4bb66 100644 --- a/htdocs/societe/canvas/company/tpl/card_view.tpl.php +++ b/htdocs/societe/canvas/company/tpl/card_view.tpl.php @@ -16,10 +16,13 @@ * along with this program. If not, see . */ /** + * @var Canvas $this * @var Conf $conf * @var CommonObject $this * @var Translate $langs * @var User $user + * + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { @@ -37,17 +40,16 @@ $head = societe_prepare_head($soc); print dol_get_fiche_head($head, 'card', $langs->trans("ThirdParty"), 0, 'company'); -?> - -control->tpl['error']) { +if ($this->control->tpl['error']) { echo $this->control->tpl['error']; -} ?> -control->tpl['action_delete']) { +} +if ($this->control->tpl['action_delete']) { echo $this->control->tpl['action_delete']; -} ?> -control->tpl['js_checkVatPopup']) { +} +if ($this->control->tpl['js_checkVatPopup']) { echo $this->control->tpl['js_checkVatPopup']; -} ?> +} +?>
".$langs->trans("Name")." / ".$langs->trans("Company")."".$langs->trans("Anonymous")."".dol_print_date($db->jdate($objp->datedon))."'.number_format($objp->amount, 2, '.', ' ').' '.$langs->trans("Currency".$conf->currency).''.price($objp->amount).' '.$langs->trans("Currency".$conf->currency).'
'.$langs->trans('Note').'
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).' 
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).' 
'.$langs->trans("AlreadyPaid").''.price($sumpaid,0,$outputlangs,1,-1,-1,$conf->currency).'
diff --git a/htdocs/societe/canvas/individual/tpl/card_view.tpl.php b/htdocs/societe/canvas/individual/tpl/card_view.tpl.php index 2c0a6277ac4..07e2afc2ae0 100644 --- a/htdocs/societe/canvas/individual/tpl/card_view.tpl.php +++ b/htdocs/societe/canvas/individual/tpl/card_view.tpl.php @@ -17,12 +17,15 @@ */ /** + * @var Canvas $this * @var Conf $conf * @var CommonObject $this * @var DoliDB $db * @var FormFile $formfile * @var Translate $langs * @var User $user + * + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index e4a3c6c47d5..9e149817d83 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1960,7 +1960,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayactio print ''; print ''; print ''; print ''; } +if (!empty($arrayfields['s.ref_ext']['checked'])) { + print ''; +} // Barcode if (!empty($arrayfields['s.barcode']['checked'])) { print '\n"; + if (!$i) { + $totalarray['nbfield']++; + } + } // Barcode if (!empty($arrayfields['s.barcode']['checked'])) { print ''; diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index e557d95de02..604fb1dd176 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -290,28 +290,35 @@ if (empty($reshook)) { $remaintopay = $invoice->getRemainToPay(); if ($remaintopay > 0) { $payment = new Paiement($db); + $payment->datepaye = $now; $payment->fk_account = $bankaccount; - $payment->amounts[$invoice->id] = $amountofpayment; if ($pay == 'LIQ') { $payment->pos_change = GETPOSTFLOAT('excess'); } + $payment->amounts[$invoice->id] = $amountofpayment; // If user has not used change control, add total invoice payment // Or if user has used change control and the amount of payment is higher than remain to pay, add the remain to pay if ($amountofpayment <= 0 || $amountofpayment > $remaintopay) { $payment->amounts[$invoice->id] = $remaintopay; } + // We do not set $payments->multicurrency_amounts because we want payment to be in main currency. $payment->paiementid = $paiementid; $payment->num_payment = $invoice->ref; if ($pay != "delayed") { - $payment->create($user); + $res = $payment->create($user); + if ($res < 0) { + $error++; + dol_htmloutput_errors($langs->trans('Error').' '.$payment->error, $payment->errors, 1); + } + $res = $payment->addPaymentToBank($user, 'payment', '(CustomerInvoicePayment)', $bankaccount, '', ''); if ($res < 0) { $error++; - dol_htmloutput_errors($langs->trans('ErrorNoPaymentDefined'), $payment->errors, 1); + dol_htmloutput_errors($langs->trans('ErrorNoPaymentDefined').' '.$payment->error, $payment->errors, 1); } $remaintopay = $invoice->getRemainToPay(); // Recalculate remain to pay after the payment is recorded } elseif (getDolGlobalInt("TAKEPOS_DELAYED_TERMS")) { @@ -324,6 +331,7 @@ if (empty($reshook)) { $result = $invoice->setPaid($user); if ($result > 0) { $invoice->paye = 1; + $invoice->status = $invoice::STATUS_CLOSED; } // set payment method $invoice->setPaymentMethods($paiementid); diff --git a/htdocs/takepos/pay.php b/htdocs/takepos/pay.php index f60e08dd546..4bc6cf0d0b3 100644 --- a/htdocs/takepos/pay.php +++ b/htdocs/takepos/pay.php @@ -539,6 +539,7 @@ if (getDolGlobalString('TAKEPOS_CUSTOMER_DISPLAY')) { currency = '.$conf->currency.' - sessioncurrency = '.$sessioncurrency.' -->'."\n"; if (isModEnabled('multicurrency') && $sessioncurrency != "" && $conf->currency != $sessioncurrency) { // Only show customer currency if multicurrency module is enabled, if currency selected and if this currency selected is not the same as main currency $showothercurrency = 1; @@ -560,7 +561,7 @@ if (isModEnabled('multicurrency') && $sessioncurrency != "" && $conf->currency ! total_ttc) { ?>
trans('RemainToPay'); ?>: multicurrency_code); + echo price($remaintopay, 1, '', 1, -1, -1, $conf->currency); if ($showothercurrency) { print '   (' . price($remaintopay * $multicurrency->rate->rate) . ' ' . $sessioncurrency . ')'; } @@ -569,7 +570,7 @@ if (isModEnabled('multicurrency') && $sessioncurrency != "" && $conf->currency !
trans("Received"); ?>: multicurrency_code); + echo price(0, 1, '', 1, -1, -1, $conf->currency); if ($showothercurrency) { print '   (' . price(0 * $multicurrency->rate->rate) . ' ' . $sessioncurrency . ')'; } @@ -577,7 +578,7 @@ if (isModEnabled('multicurrency') && $sessioncurrency != "" && $conf->currency !
trans("Change"); ?>: multicurrency_code); + echo price(0, 1, '', 1, -1, -1, $conf->currency); if ($showothercurrency) { print '   (' . price(0 * $multicurrency->rate->rate) . ' ' . $sessioncurrency . ')'; } diff --git a/htdocs/takepos/public/auto_order.php b/htdocs/takepos/public/auto_order.php index 970044e2773..bb8472f5cab 100644 --- a/htdocs/takepos/public/auto_order.php +++ b/htdocs/takepos/public/auto_order.php @@ -35,7 +35,7 @@ if (!defined('NOBROWSERNOTIF')) { require '../../main.inc.php'; if (!getDolGlobalString('TAKEPOS_AUTO_ORDER')) { - accessforbidden('Auto order is not allwed'); // If Auto Order is disabled never allow access to this page (that is a NO LOGIN access) + accessforbidden('Auto order is not allowed'); // If Auto Order is disabled never allow access to this page (that is a NO LOGIN access) } $_SESSION["basiclayout"] = 1; // For the simple layout for public submission @@ -43,9 +43,9 @@ $_SESSION["takeposterminal"] = getDolGlobalInt('TAKEPOS_TERMINAL_NB_FOR_PUBLIC', define('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE', 1); if (GETPOSTISSET("mobilepage")) { - require DOL_URL_ROOT.'/takepos/invoice.php'; + require DOL_DOCUMENT_ROOT.'/takepos/invoice.php'; } elseif (GETPOSTISSET("genimg")) { require DOL_DOCUMENT_ROOT.'/takepos/genimg/index.php'; } else { - require DOL_URL_ROOT.'/takepos/phone.php'; + require DOL_DOCUMENT_ROOT.'/takepos/phone.php'; } diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 15558ad11d7..e6b4e156a26 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -317,6 +317,9 @@ tr.liste_titre th.liste_titre_sel:not(.maxwidthsearch), tr.liste_titre td.liste_ tr.liste_titre th.liste_titre:not(.maxwidthsearch), tr.liste_titre td.liste_titre:not(.maxwidthsearch) { opacity: 0.8; } /* th.liste_titre_sel a, th.liste_titre a, td.liste_titre_sel a, td.liste_titre a { color: #766; } */ tr.liste_titre_filter th.liste_titre { text-align: unset; } +.liste_titre.trheight5em { + height: 4em !important; +} input { font-size: unset; @@ -745,8 +748,12 @@ input:-webkit-autofill { /* CSS for placeholder */ .placeholder { color: #ccc; } +select.placeholder { color: #ccc; } ::-webkit-input-placeholder { color: #ccc; } input:-moz-placeholder { color: #ccc; } +select.placeholder option:not(.opacitymediumbycolor):not(.opacitymedium) { + color: var(--colortext); +} input[name=price], input[name=weight], input[name=volume], input[name=surface], input[name=sizeheight], input[name=net_measure], select[name=incoterm_id] { margin-right: 6px; } fieldset { @@ -763,6 +770,7 @@ input#onlinepaymenturl, input#directdownloadlink { opacity: 0.7; } + .formconsumeproduce { background: #f3f3f3; padding: 20px 0px 0px 0px; @@ -1709,7 +1717,7 @@ select.flat.selectlimit { -webkit-line-clamp: 2; overflow: hidden; } -.twolinesmax { +.twolinesmax, .twolinesmax-normallineheight { /* To be used into a
into a td for example */ display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; @@ -1717,6 +1725,9 @@ select.flat.selectlimit { height: auto !important; word-break: break-word; } +.twolinesmax-normallineheight { + line-height: normal; +} .tenlinesmax { display: -webkit-box; -webkit-box-orient: vertical; @@ -3872,7 +3883,7 @@ a.fmdirlia { /* ============================================================================== */ -/* Onglets */ +/* Tabs */ /* ============================================================================== */ div.tabs { text-align: ; @@ -4478,8 +4489,8 @@ table.tableforfield td, .tagtr.table-border-row .tagtd { } table.liste td, table.noborder td, div.noborder form div, table.tableforservicepart1 td, table.tableforservicepart2 td { padding: 6px 10px 6px 12px; /* t r b l */ - /* line-height: 22px; This create trouble on cell login on list of last events of a contract*/ - height: 30px; + /* line-height: 22px; This create trouble on cell login on list of last events of a contract */ + height: 32px; } table.liste tr.trkanban td { padding: 12px 15px 12px 15px; /* t r b l */ @@ -4695,12 +4706,11 @@ table.hidepaginationnext .paginationnext { } - /* Set the color for hover lines */ -.oddeven:hover, .evenodd:hover, .oddevenimport:hover, .evenoddimport:hover, .impair:hover, .pair:hover -{ +.oddeven:hover:not(.nohover), .evenodd:hover:not(.nohover), .oddevenimport:hover:not(.nohover), .evenoddimport:hover:not(.nohover), .impair:hover:not(.nohover), .pair:hover:not(.nohover) { background: var(--colorbacklinepairhover) !important; /* Must be background to be stronger than background of odd or even */ } + .tredited, .tredited td { background: var(--colorbacklinepairchecked) !important; /* Must be background to be stronger than background of odd or even */ border-bottom: 0 !important; diff --git a/htdocs/theme/eldy/info-box.inc.php b/htdocs/theme/eldy/info-box.inc.php index b2abe2b3f96..14b631fe9e3 100644 --- a/htdocs/theme/eldy/info-box.inc.php +++ b/htdocs/theme/eldy/info-box.inc.php @@ -453,9 +453,6 @@ a.vmenu span, span.vmenu, span.vmenu span { .infobox-order_supplier:not(.error) { color: #599caf; } -.infobox-order_supplier::before { - margin-left: 5px; -} .infobox-contrat, .infobox-ticket{ color: #3bbfa8; } diff --git a/htdocs/theme/md/info-box.inc.php b/htdocs/theme/md/info-box.inc.php index fddad3058c0..d399f475ec3 100644 --- a/htdocs/theme/md/info-box.inc.php +++ b/htdocs/theme/md/info-box.inc.php @@ -149,9 +149,6 @@ div.login_block_other a { .infobox-order_supplier:not(.pictotitle):not(.error) { color: #599caf; } -.infobox-order_supplier::before { - margin-left: 3px; -} .infobox-contrat, .infobox-ticket{ color: #46a676; diff --git a/htdocs/theme/md/main_menu_fa_icons.inc.php b/htdocs/theme/md/main_menu_fa_icons.inc.php index d5373467280..a08b85c27c1 100644 --- a/htdocs/theme/md/main_menu_fa_icons.inc.php +++ b/htdocs/theme/md/main_menu_fa_icons.inc.php @@ -107,14 +107,15 @@ div.mainmenu.generic4::before { text-align: center; } -.menu_titre .em092 { + +.em092 { font-size: 0.92em; } -.menu_titre .em088 { +.em088 { font-size: 0.88em; } -.menu_titre .em080 { +.em080 { font-size: 0.80em; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index fcdc79aeb95..b333f13f1ca 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -600,19 +600,6 @@ th.wrapcolumntitle dl dt a span.fas.fa-list { padding-bottom: 1px; } -/*.liste_titre input[name=month_date_when], .liste_titre input[name=monthvalid], .liste_titre input[name=search_ordermonth], .liste_titre input[name=search_deliverymonth], -.liste_titre input[name=search_smonth], .liste_titre input[name=search_month], .liste_titre input[name=search_emonth], .liste_titre input[name=smonth], .liste_titre input[name=month], -.liste_titre input[name=month_lim], .liste_titre input[name=month_start], .liste_titre input[name=month_end], .liste_titre input[name=month_create], -.liste_titre input[name=search_month_lim], .liste_titre input[name=search_month_start], .liste_titre input[name=search_month_end], .liste_titre input[name=search_month_create], -.liste_titre input[name=search_month_create], .liste_titre input[name=search_month_start], .liste_titre input[name=search_month_end], -.liste_titre input[name=day_date_when], .liste_titre input[name=dayvalid], .liste_titre input[name=search_orderday], .liste_titre input[name=search_deliveryday], -.liste_titre input[name=search_sday], .liste_titre input[name=search_day], .liste_titre input[name=search_eday], .liste_titre input[name=sday], .liste_titre input[name=day], .liste_titre select[name=day], -.liste_titre input[name=day_lim], .liste_titre input[name=day_start], .liste_titre input[name=day_end], .liste_titre input[name=day_create], -.liste_titre input[name=search_day_lim], .liste_titre input[name=search_day_start], .liste_titre input[name=search_day_end], .liste_titre input[name=search_day_create], -.liste_titre input[name=search_day_create], .liste_titre input[name=search_day_start], .liste_titre input[name=search_day_end], -.liste_titre input[name=search_day_date_when], .liste_titre input[name=search_month_date_when], .liste_titre input[name=search_year_date_when], -.liste_titre input[name=search_dtstartday], .liste_titre input[name=search_dtendday], .liste_titre input[name=search_dtstartmonth], .liste_titre input[name=search_dtendmonth], -*/ .liste_titre input[name=search_month], .liste_titre input[name=search_month_start], .liste_titre input[name=search_month_end] { margin-right: 4px; } @@ -946,11 +933,15 @@ input[type=checkbox], input[type=radio] { /* CSS for placeholder */ .placeholder { color: #ccc; } +select.placeholder { color: #ccc; } ::-webkit-input-placeholder { color:#ccc; } :-moz-placeholder { color:#bbb; } /* firefox 18- */ ::-moz-placeholder { color:#bbb; } /* firefox 19+ */ :-ms-input-placeholder { color:#ccc; } /* ie */ input:-moz-placeholder { color:#ccc; } +select.placeholder option:not(.opacitymediumbycolor):not(.opacitymedium) { + color: var(--colortext); +} input[name=price], input[name=weight], input[name=volume], input[name=surface], input[name=sizeheight], input[name=net_measure], select[name=incoterm_id] { margin-right: 6px; } fieldset { @@ -1876,7 +1867,7 @@ select.flat.selectlimit { -webkit-line-clamp: 2; overflow: hidden; } -.twolinesmax { +.twolinesmax, .twolinesmax-normallineheight { /* To be used into a
into a td for example */ display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; @@ -1884,6 +1875,9 @@ select.flat.selectlimit { height: auto !important; word-break: break-word; } +.twolinesmax-normallineheight { + line-height: normal; +} .tenlinesmax { display: -webkit-box; -webkit-box-orient: vertical; @@ -4256,6 +4250,9 @@ div.tabBar table.border tr, div.tabBar table.border tr td, div.tabBar div.border tr.liste_titre.box_titre td table td, .bordernooddeven tr td { height: 28px; } +.liste_titre.trheight5em { + height: 4em !important; +} table.border td, table.bordernooddeven td, div.border div div.tagtd { padding: 3px 4px 3px 4px; @@ -4497,7 +4494,7 @@ tr.liste_titre_filter td.liste_titre { padding-top: 4px; padding-bottom: 3px; } -.liste_titre_create td, .liste_titre_create th, .liste_titre_create .tagtd +.liste_titre_create td:not(.linecoldescription), .liste_titre_create th, .liste_titre_create .tagtd { border-top-width: 1px; border-top-color: var(--colortopbordertitle1); @@ -4519,13 +4516,17 @@ tr#trlinefordates td { border-top-style: solid; } +td.linecoldescription { + padding: 6px 10px 6px 12px !important; /* t r b l */ +} + table.liste th, table.noborder th, table.noborder tr.liste_titre td, table.noborder tr.box_titre td { padding: 8px 8px 8px 10px; /* t r b l */ } table.liste td, table.noborder td, div.noborder form div, table.tableforservicepart1 td, table.tableforservicepart2 td { padding: 4px 8px 4px 10px; /* t r b l */ - height: 22px; + height: 28px; } table.liste tr.trkanban td { padding: 12px 15px 12px 15px; /* t r b l */ @@ -4761,7 +4762,6 @@ ul.noborder li:nth-child(odd):not(.liste_titre) { /* Set the color for hover lines */ - .tmenucompanylogo.nohover, .tmenucompanylogo.nohover:hover { opacity: unset !important; } @@ -4770,11 +4770,10 @@ ul.noborder li:nth-child(odd):not(.liste_titre) { box-shadow: unset; -webkit-box-shadow: unset; } - -.oddeven:hover, .evenodd:hover, .oddevenimport:hover, .evenoddimport:hover, .impair:hover, .pair:hover -{ +.oddeven:hover:not(.nohover), .evenodd:hover:not(.nohover), .oddevenimport:hover:not(.nohover), .evenoddimport:hover:not(.nohover), .impair:hover:not(.nohover), .pair:hover:not(.nohover) { background: rgb() !important; } + .tredited { background: rgb() !important; /* Must be background to be stronger than background of odd or even */ } diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php index f885e2fe1d7..e62e78d332a 100644 --- a/htdocs/ticket/card.php +++ b/htdocs/ticket/card.php @@ -855,7 +855,7 @@ if ($action == 'create' || $action == 'presend') { // Define a complementary filter for search of next/prev ref. if (!$user->hasRight('projet', 'all', 'lire')) { $objectsListId = $projectstat->getProjectsAuthorizedForUser($user, $mine, 0); - $projectstat->next_prev_filter = "rowid:IN:(".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0').")"; + $projectstat->next_prev_filter = "rowid:IN:".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0'); } print $form->showrefnav($projectstat, 'ref', $linkback, 1, 'ref', 'ref', ''); print '
'; diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index d9c82030344..c54ebd897f0 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -620,7 +620,7 @@ if ($projectid > 0 || $project_ref) { // Define a complementary filter for search of next/prev ref. if (!$user->hasRight('projet', 'all', 'lire')) { $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0); - $object->next_prev_filter = "rowid:IN:(".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0').")"; + $object->next_prev_filter = "rowid:IN:".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0'); } dol_banner_tab($object, 'project_ref', $linkback, 1, 'ref', 'ref', $morehtmlref); diff --git a/htdocs/user/card.php b/htdocs/user/card.php index da755e4c775..b3d02e0d72d 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -1217,7 +1217,7 @@ if ($action == 'create' || $action == 'adduserldap') { } // Other form for user password - $parameters = array('valuetoshow' => $valuetoshow, 'password' => $password); + $parameters = array('valuetoshow' => $valuetoshow, 'password' => $password, 'caneditpasswordandsee' => $permissiontoeditpasswordandsee, 'caneditpasswordandsend' => $permissiontoeditpasswordandsend); $reshook = $hookmanager->executeHooks('printUserPasswordField', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if ($reshook > 0) { $valuetoshow = $hookmanager->resPrint; // to replace @@ -2041,7 +2041,7 @@ if ($action == 'create' || $action == 'adduserldap') { */ // Other form for user password - $parameters = array('valuetoshow' => $valuetoshow); + $parameters = array('valuetoshow' => $valuetoshow, 'caneditpasswordandsee' => $permissiontoeditpasswordandsee, 'caneditpasswordandsend' => $permissiontoeditpasswordandsend); $reshook = $hookmanager->executeHooks('printUserPasswordField', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if ($reshook > 0) { $valuetoshow = $hookmanager->resPrint; // to replace diff --git a/htdocs/user/group/card.php b/htdocs/user/group/card.php index 1b7816b5bb6..2748f069cae 100644 --- a/htdocs/user/group/card.php +++ b/htdocs/user/group/card.php @@ -88,7 +88,7 @@ $hookmanager->initHooks(array('groupcard', 'globalcard')); $result = restrictedArea($user, 'user', $id, 'usergroup&usergroup', $feature2); // Users/Groups management only in master entity if transverse mode -if (isModEnabled('multicompany') && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE) { +if (isModEnabled('multicompany') && $conf->entity > 1 && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) { accessforbidden(); } diff --git a/htdocs/variants/class/ProductAttribute.class.php b/htdocs/variants/class/ProductAttribute.class.php index 2ce516a245b..698d6f211fe 100644 --- a/htdocs/variants/class/ProductAttribute.class.php +++ b/htdocs/variants/class/ProductAttribute.class.php @@ -976,7 +976,7 @@ class ProductAttribute extends CommonObject public function getPositionOfAttribute($rowid) { $sql = "SELECT position FROM " . MAIN_DB_PREFIX . $this->table_element; - $sql .= " WHERE entity IN (" . getEntity('product') . ")"; + $sql .= " WHERE rowid=".(int) $rowid." AND entity IN (" . getEntity('product') . ")"; dol_syslog(__METHOD__, LOG_DEBUG); $resql = $this->db->query($sql); diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index adc2322e526..b7c9d5e3c45 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -550,13 +550,13 @@ class ProductCombination // MultiPrix if (getDolGlobalString('PRODUIT_MULTIPRICES')) { - $produit_multiprices_limit = getDolGlobalString('PRODUIT_MULTIPRICES_LIMIT'); + $produit_multiprices_limit = getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); for ($i = 1; $i <= $produit_multiprices_limit; $i++) { if ($parent->multiprices[$i] != '' || isset($this->combination_price_levels[$i]->variation_price)) { $new_type = empty($parent->multiprices_base_type[$i]) ? 'HT' : $parent->multiprices_base_type[$i]; $new_min_price = $parent->multiprices_min[$i]; $variation_price = (float) (!isset($this->combination_price_levels[$i]->variation_price) ? $this->variation_price : $this->combination_price_levels[$i]->variation_price); - $variation_price_percentage = (float) (!isset($this->combination_price_levels[$i]->variation_price_percentage) ? $this->variation_price_percentage : $this->combination_price_levels[$i]->variation_price_percentage); + $variation_price_percentage = (bool) (!isset($this->combination_price_levels[$i]->variation_price_percentage) ? $this->variation_price_percentage : $this->combination_price_levels[$i]->variation_price_percentage); if ($parent->prices_by_qty_list[$i]) { $new_psq = 1; @@ -867,14 +867,14 @@ class ProductCombination $newproduct->description .= ''.$prodattr->label.': '.$prodattrval->value; } - $newcomb->variation_price_percentage = $price_var_percent[1]; + $newcomb->variation_price_percentage = (bool) $price_var_percent[1]; $newcomb->variation_price = $price_impact[1]; $newcomb->variation_weight = $weight_impact; $newcomb->variation_ref_ext = $this->db->escape($ref_ext); // Init price level if (getDolGlobalString('PRODUIT_MULTIPRICES')) { - $produit_multiprices_limit = getDolGlobalString('PRODUIT_MULTIPRICES_LIMIT'); + $produit_multiprices_limit = getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); for ($i = 1; $i <= $produit_multiprices_limit; $i++) { $productCombinationLevel = new ProductCombinationLevel($this->db); $productCombinationLevel->fk_product_attribute_combination = $newcomb->id; @@ -882,7 +882,7 @@ class ProductCombination $productCombinationLevel->variation_price = $price_impact[$i]; if (is_array($price_var_percent)) { - $productCombinationLevel->variation_price_percentage = (empty($price_var_percent[$i]) ? false : $price_var_percent[$i]); + $productCombinationLevel->variation_price_percentage = (bool) $price_var_percent[$i] ; } else { $productCombinationLevel->variation_price_percentage = $price_var_percent; } diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index 0e31f37cba9..e32143113c6 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -302,7 +302,8 @@ if (($action == 'add' || $action == 'create') && $usercancreate && empty($massac if (getDolGlobalString('PRODUIT_MULTIPRICES')) { $prodcomb->combination_price_levels = array(); - for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { + $maxi = getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); + for ($i = 1; $i <= $maxi; $i++) { $productCombinationLevel = new ProductCombinationLevel($db); $productCombinationLevel->fk_product_attribute_combination = $prodcomb->id; $productCombinationLevel->fk_price_level = $i; @@ -723,14 +724,16 @@ if (!empty($id) || !empty($ref)) { fetchCombinationPriceLevels(); - for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { + $maxi = getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); + for ($i = 1; $i <= $maxi; $i++) { $keyforlabel = 'PRODUIT_MULTIPRICES_LABEL'.$i; $text = $langs->trans('ImpactOnPriceLevel', $i).' - '.getDolGlobalString($keyforlabel); print ''; @@ -740,7 +743,7 @@ if (!empty($id) || !empty($ref)) { } print ''; print ''; print ''; @@ -767,7 +770,7 @@ if (!empty($id) || !empty($ref)) { let priceImpact = $( "#level_price_impact_1" ).val(); let priceImpactPrecent = $( "#level_price_impact_percent_1" ).prop("checked"); - var multipricelimit = global->PRODUIT_MULTIPRICES_LIMIT); ?> + let multipricelimit = for (let i = 2; i <= multipricelimit; i++) { $( "#level_price_impact_" + i ).val(priceImpact); diff --git a/htdocs/variants/list.php b/htdocs/variants/list.php index fbec288d582..0ce02d3624c 100644 --- a/htdocs/variants/list.php +++ b/htdocs/variants/list.php @@ -53,6 +53,7 @@ $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' $mode = GETPOST('mode', 'aZ'); // The display mode ('list', 'kanban', 'hierarchy', 'calendar', 'gantt', ...) $id = GETPOSTINT('id'); +$rowid = GETPOSTINT('rowid'); // for line reordering in not ajax mode // Load variable for pagination $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit; diff --git a/htdocs/workstation/class/workstation.class.php b/htdocs/workstation/class/workstation.class.php index 6acaf6d6762..5df09475419 100644 --- a/htdocs/workstation/class/workstation.class.php +++ b/htdocs/workstation/class/workstation.class.php @@ -111,9 +111,9 @@ class Workstation extends CommonObject 'fk_user_creat' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'position' => 510, 'notnull' => 1, 'visible' => -2, 'foreignkey' => 'user.rowid',), 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'position' => 511, 'notnull' => -1, 'visible' => -2,), 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'position' => 512, 'notnull' => -1, 'visible' => -2,), - 'nb_operators_required' => array('type' => 'integer', 'label' => 'NbOperatorsRequired', 'enabled' => 1, 'position' => 50, 'notnull' => 0, 'visible' => 1, 'css' => 'right', 'csslist' => 'maxwidth75imp'), - 'thm_operator_estimated' => array('type' => 'double', 'help' => 'THMOperatorEstimatedHelp','label' => 'THMOperatorEstimated', 'enabled' => 1, 'position' => 50, 'notnull' => 0, 'visible' => 1, 'css' => 'right', 'csslist' => 'maxwidth75imp'), - 'thm_machine_estimated' => array('type' => 'double', 'help' => 'THMMachineEstimatedHelp', 'label' => 'THMMachineEstimated', 'enabled' => 1, 'position' => 50, 'notnull' => 0, 'visible' => 1, 'css' => 'right', 'csslist' => 'maxwidth75imp'), + 'nb_operators_required' => array('type' => 'integer', 'label' => 'NbOperatorsRequired', 'enabled' => 1, 'position' => 50, 'notnull' => 0, 'visible' => 1, 'css' => 'right maxwidth50imp', 'csslist' => 'maxwidth50imp'), + 'thm_operator_estimated' => array('type' => 'price', 'help' => 'THMOperatorEstimatedHelp','label' => 'THMOperatorEstimated', 'enabled' => 1, 'position' => 50, 'notnull' => 0, 'visible' => 1, 'css' => 'right maxwidth75imp', 'csslist' => 'maxwidth75imp'), + 'thm_machine_estimated' => array('type' => 'price', 'help' => 'THMMachineEstimatedHelp', 'label' => 'THMMachineEstimated', 'enabled' => 1, 'position' => 50, 'notnull' => 0, 'visible' => 1, 'css' => 'right maxwidth75imp', 'csslist' => 'maxwidth75imp'), 'status' => array('type' => 'smallint', 'label' => 'Status', 'enabled' => 1, 'position' => 1000, 'default' => '1', 'notnull' => 1, 'visible' => 1, 'index' => 1, 'arrayofkeyval' => array(0 => 'Disabled', 1 => 'Enabled'),), ); diff --git a/htdocs/workstation/workstation_card.php b/htdocs/workstation/workstation_card.php index b4ae42344e2..15e4f76a034 100644 --- a/htdocs/workstation/workstation_card.php +++ b/htdocs/workstation/workstation_card.php @@ -233,9 +233,9 @@ if ($action == 'create') { // Common attributes include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php'; - print ''; + print ''; print ''; print '
'.$form->editfieldkey('AllocateCommercial', 'commercial_id', '', $object, 0).''; // TODO Use select_doluser in multiselect mode - $userlist = $form->select_dolusers($selected, '', 0, null, 0, '', '', '0', 0, 0, 'AND u.statut = 1', 0, '', '', 0, 2); + $userlist = $form->select_dolusers($selected, '', 0, null, 0, '', '', '0', 0, 0, 'u.statut:=:1', 0, '', '', 0, 2); // Note: If user has no right to "see all thirdparties", we force selection of sale representative to him, so after creation he can see the record. $selected = (GETPOSTISARRAY('commercial') ? GETPOST('commercial', 'array:int') : (GETPOSTINT('commercial') > 0 ? array(GETPOSTINT('commercial')) : array($user->id))); print img_picto('', 'user').$form->multiselectarray('commercial', $userlist, $selected, 0, 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0); @@ -2812,7 +2812,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayactio print '
'.$form->editfieldkey('AllocateCommercial', 'commercial_id', '', $object, 0).''; - $userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, 'AND u.statut = 1', 0, '', '', 0, 1); + $userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, 'u.statut:=:1', 0, '', '', 0, 1); $arrayselected = GETPOST('commercial', 'array'); if (empty($arrayselected)) { $arrayselected = $object->getSalesRepresentatives($user, 1); diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php index 0af1d485070..365d2968f0b 100644 --- a/htdocs/societe/class/api_contacts.class.php +++ b/htdocs/societe/class/api_contacts.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2019 Frédéric France + * Copyright (C) 2019-2024 Frédéric France * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify @@ -194,9 +194,6 @@ class Contacts extends DolibarrApi $sql = "SELECT t.rowid"; $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as t"; - if ($category > 0) { - $sql .= ", ".MAIN_DB_PREFIX."categorie_contact as c"; - } $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople_extrafields as te ON te.fk_object = t.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON t.fk_soc = s.rowid"; $sql .= ' WHERE t.entity IN ('.getEntity('contact').')'; @@ -213,8 +210,37 @@ class Contacts extends DolibarrApi } // Select contacts of given category if ($category > 0) { - $sql .= " AND c.fk_categorie = ".((int) $category); - $sql .= " AND c.fk_socpeople = t.rowid "; + // Search Contact Categories + $searchCategoryContactList = $category ? array($category) : array(); + // $searchCategoryContactOperator = 0; + // Search for tag/category ($searchCategoryContactList is an array of ID) + if (!empty($searchCategoryContactList)) { + $searchCategoryContactSqlList = array(); + // $listofcategoryid = ''; + foreach ($searchCategoryContactList as $searchCategoryContact) { + if (intval($searchCategoryContact) == -2) { + $searchCategoryContactSqlList[] = "NOT EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE t.rowid = ck.fk_socpeople)"; + } elseif (intval($searchCategoryContact) > 0) { + // if ($searchCategoryContactOperator == 0) { + $searchCategoryContactSqlList[] = " EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE t.rowid = ck.fk_socpeople AND ck.fk_categorie = ".((int) $searchCategoryContact).")"; + // } else { + // $listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategoryContact); + // } + } + } + // if ($listofcategoryid) { + // $searchCategoryContactSqlList[] = " EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE t.rowid = ck.fk_socpeople AND ck.fk_categorie IN (".$this->db->sanitize($listofcategoryid)."))"; + // } + // if ($searchCategoryContactOperator == 1) { + // if (!empty($searchCategoryContactSqlList)) { + // $sql .= " AND (".implode(' OR ', $searchCategoryContactSqlList).")"; + // } + // } else { + if (!empty($searchCategoryContactSqlList)) { + $sql .= " AND (".implode(' AND ', $searchCategoryContactSqlList).")"; + } + // } + } } // Add sql filters diff --git a/htdocs/societe/class/client.class.php b/htdocs/societe/class/client.class.php index 45e47ab21b2..81187942d6e 100644 --- a/htdocs/societe/class/client.class.php +++ b/htdocs/societe/class/client.class.php @@ -34,7 +34,7 @@ class Client extends Societe /** * @var string Used to add a filter in Form::showrefnav method */ - public $next_prev_filter = "te.client:in:(1,2,3)"; + public $next_prev_filter = "te.client:in:1,2,3"; /** * @var array diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index a8167de49da..70fe8a2f34f 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -85,6 +85,7 @@ $search_id = GETPOST("search_id", 'int'); $search_nom = trim(GETPOST("search_nom", 'restricthtml')); $search_alias = trim(GETPOST("search_alias", 'restricthtml')); $search_nom_only = trim(GETPOST("search_nom_only", 'restricthtml')); +$search_ref_ext = trim(GETPOST("search_ref_ext", 'restricthtml')); $search_barcode = trim(GETPOST("search_barcode", 'alpha')); $search_customer_code = trim(GETPOST('search_customer_code', 'alpha')); $search_supplier_code = trim(GETPOST('search_supplier_code', 'alpha')); @@ -287,7 +288,8 @@ $arrayfields = array( 's.rowid' => array('label' => "TechnicalID", 'position' => 1, 'checked' => -1, 'enabled' => 1), 's.nom' => array('label' => "ThirdPartyName", 'position' => 2, 'checked' => 1), 's.name_alias' => array('label' => "AliasNameShort", 'position' => 3, 'checked' => 1), - 's.barcode' => array('label' => "Gencod", 'position' => 5, 'checked' => 1, 'enabled' => (isModEnabled('barcode'))), + 's.ref_ext' => array('label' => "RefExt", 'position' => 4, 'checked' => -1, 'enabled' => getDolGlobalInt('MAIN_LIST_SHOW_REF_EXT')), + 's.barcode' => array('label' => "Gencod", 'position' => 5, 'checked' => 1, 'enabled' => isModEnabled('barcode')), 's.code_client' => array('label' => "CustomerCodeShort", 'position' => 10, 'checked' => $checkedcustomercode), 's.code_fournisseur' => array('label' => "SupplierCodeShort", 'position' => 11, 'checked' => $checkedsuppliercode, 'enabled' => (isModEnabled("supplier_order") || isModEnabled("supplier_invoice"))), 's.code_compta' => array('label' => "CustomerAccountancyCodeShort", 'position' => 13, 'checked' => $checkedcustomeraccountcode), @@ -411,6 +413,7 @@ if (empty($reshook)) { $search_id = ''; $search_nom = ''; $search_alias = ''; + $search_ref_ext = ''; $search_categ_cus = 0; $search_categ_sup = 0; $searchCategoryCustomerOperator = 0; @@ -562,7 +565,7 @@ if ($resql) { // Build and execute select // -------------------------------------------------------------------- -$sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.barcode, s.address, s.town, s.zip, s.datec, s.code_client, s.code_fournisseur, s.logo,"; +$sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.ref_ext, s.barcode, s.address, s.town, s.zip, s.datec, s.code_client, s.code_fournisseur, s.logo,"; $sql .= " s.entity,"; $sql .= " st.libelle as stcomm, st.picto as stcomm_picto, s.fk_stcomm as stcomm_id, s.fk_prospectlevel, s.prefix_comm, s.client, s.fournisseur, s.canvas, s.status as status, s.note_private, s.note_public,"; $sql .= " s.email, s.phone, s.phone_mobile, s.fax, s.url, s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4 as idprof4, s.idprof5 as idprof5, s.idprof6 as idprof6, s.tva_intra, s.fk_pays,"; @@ -611,6 +614,11 @@ $sql .= " WHERE s.entity IN (".getEntity('societe').")"; if (!$user->hasRight('fournisseur', 'lire')) { $sql .= " AND (s.fournisseur <> 1 OR s.client <> 0)"; // client=0, fournisseur=0 must be visible } + +// Force the sales representative if they don't have permissions +if (!$user->hasRight('societe', 'client', 'voir') && !$socid) { + $search_sale = $user->id; +} // Search on sale representative if (!empty($search_sale) && $search_sale != '-1') { $search_sale_req = array_filter($search_sale, function (string $value): bool { @@ -710,6 +718,9 @@ if (empty($arrayfields['s.name_alias']['checked']) && $search_nom) { if ($search_nom_only) { $sql .= natural_search("s.nom", $search_nom_only); } +if ($search_ref_ext) { + $sql .= natural_search("s.ref_ext", $search_ref_ext); +} if ($search_customer_code) { $sql .= natural_search("s.code_client", $search_customer_code); } @@ -965,6 +976,9 @@ if ($search_nom != '') { if ($search_alias != '') { $param .= "&search_alias=".urlencode($search_alias); } +if ($search_ref_ext != '') { + $param .= "&search_ref_ext=".urlencode($search_ref_ext); +} if ($search_address != '') { $param .= '&search_address='.urlencode($search_address); } @@ -1276,7 +1290,7 @@ if (empty($type) || $type == 'f') { } // If the user can view prospects other than his' -$userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, 'AND u.statut = 1', 0, '', '', 0, 1); +$userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, 'u.statut:=:1', 0, '', '', 0, 1); $userlist[-2] = $langs->trans("NoSalesRepresentativeAffected"); if ($user->hasRight("societe", "client", "voir") || $socid) { $moreforfilter .= '
'; @@ -1330,6 +1344,11 @@ if (!empty($arrayfields['s.name_alias']['checked'])) { print ''; print '
'; + print ''; + print ''; @@ -1614,6 +1633,11 @@ if (!empty($arrayfields['s.name_alias']['checked'])) { print_liste_field_titre($arrayfields['s.name_alias']['label'], $_SERVER["PHP_SELF"], "s.name_alias", "", $param, "", $sortfield, $sortorder); $totalarray['nbfield']++; } +if (!empty($arrayfields['s.ref_ext']['checked'])) { + // @phan-suppress-next-line PhanTypeInvalidDimOffset + print_liste_field_titre($arrayfields['s.ref_ext']['label'], $_SERVER["PHP_SELF"], "s.ref_ext", "", $param, "", $sortfield, $sortorder); + $totalarray['nbfield']++; +} if (!empty($arrayfields['s.barcode']['checked'])) { print_liste_field_titre($arrayfields['s.barcode']['label'], $_SERVER["PHP_SELF"], "s.barcode", $param, '', '', $sortfield, $sortorder); $totalarray['nbfield']++; @@ -1802,6 +1826,7 @@ while ($i < $imaxinloop) { $companystatic->id = $obj->rowid; $companystatic->name = $obj->name; $companystatic->name_alias = $obj->name_alias; + $companystatic->ref_ext = $obj->ref_ext; $companystatic->logo = $obj->logo; $companystatic->barcode = $obj->barcode; $companystatic->canvas = $obj->canvas; @@ -1894,6 +1919,15 @@ while ($i < $imaxinloop) { $totalarray['nbfield']++; } } + // Ref ext + if (!empty($arrayfields['s.ref_ext']['checked'])) { + print ''; + print dol_escape_htmltag($companystatic->ref_ext); + print "'.dol_escape_htmltag($companystatic->barcode).'
- > + + >
'; - print 'combination_price_levels[$i]->variation_price_percentage) ? ' checked' : '').'> '; + print 'combination_price_levels[$i]->variation_price_percentage ? ' checked' : '').'> '; print '
'; - print $langs->trans('Groups'); + print '
'; + print $langs->trans('UserGroups'); print ''; print img_picto('', 'group'); @@ -288,7 +288,7 @@ if (($id || $ref) && $action == 'edit') { print '
'; - print $langs->trans('Groups'); + print $langs->trans('UserGroups'); print ''; print img_picto('', 'group'); diff --git a/scripts/bank/export-bank-receipts.php b/scripts/bank/export-bank-receipts.php index 5bea3fe5f34..e25a7c03b3c 100755 --- a/scripts/bank/export-bank-receipts.php +++ b/scripts/bank/export-bank-receipts.php @@ -1,8 +1,9 @@ #!/usr/bin/env php - * Copyright (C) 2024 MDW + * Copyright (C) 2013 Laurent Destailleur + * Copyright (C) 2024 MDW + * Copyright (C) 2024 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 @@ -53,7 +54,12 @@ require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/tva/class/tva.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/paymentsocialcontribution.class.php'; - +/** + * @var Conf $conf + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + */ // Global variables $version = DOL_VERSION; $error = 0; diff --git a/scripts/emailings/reset-invalid-emails.php b/scripts/emailings/reset-invalid-emails.php index cb78837d1bd..317c40abc16 100755 --- a/scripts/emailings/reset-invalid-emails.php +++ b/scripts/emailings/reset-invalid-emails.php @@ -1,6 +1,7 @@ #!/usr/bin/env php +/* Copyright (C) 2020 Laurent Destailleur + * Copyright (C) 2024 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 @@ -53,7 +54,12 @@ require_once $path."../../htdocs/master.inc.php"; require_once DOL_DOCUMENT_ROOT.'/core/lib/functionscli.lib.php'; require_once DOL_DOCUMENT_ROOT."/core/class/CMailFile.class.php"; require_once DOL_DOCUMENT_ROOT."/comm/mailing/class/mailing.class.php"; - +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * + * @var int $dolibarr_main_db_readonly + */ // Global variables $version = DOL_VERSION; $error = 0; diff --git a/scripts/invoices/email_unpaid_invoices_to_customers.php b/scripts/invoices/email_unpaid_invoices_to_customers.php index 0a1bfa90d60..8a0534cc5c1 100755 --- a/scripts/invoices/email_unpaid_invoices_to_customers.php +++ b/scripts/invoices/email_unpaid_invoices_to_customers.php @@ -57,7 +57,12 @@ $targettype = $argv[2]; require $path."../../htdocs/master.inc.php"; require_once DOL_DOCUMENT_ROOT.'/core/lib/functionscli.lib.php'; require_once DOL_DOCUMENT_ROOT."/core/class/CMailFile.class.php"; - +/** + * @var Conf $conf + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + */ $langs->load('main'); // Global variables diff --git a/scripts/invoices/email_unpaid_invoices_to_representatives.php b/scripts/invoices/email_unpaid_invoices_to_representatives.php index ce4347d8ebc..42433c0fea0 100755 --- a/scripts/invoices/email_unpaid_invoices_to_representatives.php +++ b/scripts/invoices/email_unpaid_invoices_to_representatives.php @@ -55,7 +55,12 @@ $mode = $argv[1]; require $path."../../htdocs/master.inc.php"; require_once DOL_DOCUMENT_ROOT.'/core/lib/functionscli.lib.php'; require_once DOL_DOCUMENT_ROOT."/core/class/CMailFile.class.php"; - +/** + * @var Conf $conf + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + */ $langs->load('main'); // Global variables diff --git a/scripts/invoices/rebuild_merge_pdf.php b/scripts/invoices/rebuild_merge_pdf.php index 774d5a78754..d7ee2915281 100755 --- a/scripts/invoices/rebuild_merge_pdf.php +++ b/scripts/invoices/rebuild_merge_pdf.php @@ -47,6 +47,12 @@ require_once DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php"; require_once DOL_DOCUMENT_ROOT."/core/modules/facture/modules_facture.php"; require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php"; require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice2.lib.php'; +/** + * @var Conf $conf + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + */ // Load main language strings $langs->load("main"); @@ -77,7 +83,7 @@ if (!empty($dolibarr_main_db_readonly)) { exit(1); } -$diroutputpdf = $conf->facture->dir_output.'/temp'; +$diroutputpdf = $conf->invoice->dir_output.'/temp'; $newlangid = 'en_EN'; // To force a new lang id $filter = array(); $regenerate = ''; // Ask regenerate (contains name of model to use) diff --git a/test/other/test_dol_escape_htmltag.php b/test/other/test_dol_escape_htmltag.php index ab0c913d882..ad85469be68 100755 --- a/test/other/test_dol_escape_htmltag.php +++ b/test/other/test_dol_escape_htmltag.php @@ -50,6 +50,8 @@ print "\n\n\n"; //print dolGetFirstLineOfText($a, 7); print dol_escape_htmltag($a, 1, 1); +print forgeSQLFromUniversalSearchCriteria("te.client:IN:1,2"); + print "\n"; //print print_r(unserialize(serialize($object))); diff --git a/test/phpunit/AccountancySystemTest.php b/test/phpunit/AccountancySystemTest.php new file mode 100644 index 00000000000..c3bda7074ae --- /dev/null +++ b/test/phpunit/AccountancySystemTest.php @@ -0,0 +1,111 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + * + * \file test/phpunit/AccountancySystemTest.php + * \ingroup test + * \brief PHPUnit test + * \remarks To run this script as CLI: phpunit filename.php + */ + +global $conf,$user,$langs,$db; +require_once dirname(__FILE__).'/../../htdocs/master.inc.php'; +require_once dirname(__FILE__).'/../../htdocs/accountancy/class/accountancysystem.class.php'; +require_once dirname(__FILE__).'/CommonClassTest.class.php'; + +if (empty($user->id)) { + print "Load permissions for admin user nb 1\n"; + $user->fetch(1); + $user->loadRights(); +} +$conf->global->MAIN_DISABLE_ALL_MAILS = 1; + + +/** + * Class for PHPUnit tests + * + * @backupGlobals disabled + * @backupStaticAttributes enabled + * @remarks backupGlobals must be disabled to have db,conf,user and lang not erased. + */ +class AccountancySystemTest extends CommonClassTest +{ + /** + * Setup some global objects before the test. + * + * @return void + */ + public static function setUpBeforeClass(): void + { + parent::setUpBeforeClass(); + global $conf, $user, $mysoc; + global $db; + + $soc = new Societe($db); + $soc->name = "AccountancySystem Unittest"; + $socid = $soc->create($user); + $mysoc = $soc; + + /* Errors are caught in later tests. */ + if ($socid <= 0) + return; + } + + /** + * testAccountancySystemCreate + * + * @return int the ID of the created object + */ + public function testAccountancySystemCreate(): int + { + global $user, $db, $mysoc; + + $this->assertLessThan($mysoc->id, 0, "Cannot create Societe: " . $mysoc->errorsToString()); + + $accountancySystem = new AccountancySystem($db); + $accountancySystem->pcg_version = 'PCG99-CUSTOMTEST'; + $result = $accountancySystem->create($user); + + print __METHOD__." result=".$result." id=".$accountancySystem->id."\n"; + $this->assertLessThan($result, 0, 'Cannot create accountancySystem:' . $accountancySystem->errorsToString()); + + return $accountancySystem->id; + } + + /** + * testAccountancySystemFetch + * + * @param int $id Id of accountancySystem entry + * @return AccountancySystem AccountancySystem record object + * + * @depends testAccountancySystemCreate + * The depends says test is run only if previous is ok + */ + public function testAccountancySystemFetch($id) + { + global $db; + + $accountancySystem = new AccountancySystem($db); + $result = $accountancySystem->fetch($id); + print __METHOD__." id=".$id." result=".$result."\n"; + $this->assertLessThan($result, 0); + $this->assertEquals($accountancySystem->pcg_version, 'PCG99-CUSTOMTEST'); + $this->assertEquals($accountancySystem->ref, $accountancySystem->pcg_version); + + return $accountancySystem; + } +} diff --git a/test/phpunit/AllTests.php b/test/phpunit/AllTests.php index 7a2c903b14b..ae5b2c03595 100644 --- a/test/phpunit/AllTests.php +++ b/test/phpunit/AllTests.php @@ -134,6 +134,8 @@ class AllTests $suite->addTestSuite('SecurityTest'); require_once dirname(__FILE__).'/SecurityGETPOSTTest.php'; $suite->addTestSuite('SecurityGETPOSTTest'); + require_once dirname(__FILE__).'/SecurityLoginTest.php'; + $suite->addTestSuite('SecurityLoginTest'); require_once dirname(__FILE__).'/UserTest.php'; $suite->addTestSuite('UserTest'); @@ -241,6 +243,9 @@ class AllTests require_once dirname(__FILE__).'/KnowledgeRecordTest.php'; $suite->addTestSuite('KnowledgeRecordTest'); + require_once dirname(__FILE__).'/AccountancySystemTest.php'; + $suite->addTestSuite('AccountancySystemTest'); + require_once dirname(__FILE__).'/AccountingAccountTest.php'; $suite->addTestSuite('AccountingAccountTest'); require_once dirname(__FILE__).'/AssetModelTest.php'; diff --git a/test/phpunit/SecurityLoginTest.php b/test/phpunit/SecurityLoginTest.php new file mode 100644 index 00000000000..2e4d190567c --- /dev/null +++ b/test/phpunit/SecurityLoginTest.php @@ -0,0 +1,106 @@ + + * Copyright (C) 2023 Alexandre Janniaux + * Copyright (C) 2024 Frédéric France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file test/phpunit/SecurityTest.php + * \ingroup test + * \brief PHPUnit test + * \remarks To run this script as CLI: phpunit filename.php + */ + +global $conf,$user,$langs,$db; +//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver +//require_once 'PHPUnit/Autoload.php'; + +if (! defined('NOREQUIRESOC')) { + define('NOREQUIRESOC', '1'); +} +if (! defined('NOCSRFCHECK')) { + define('NOCSRFCHECK', '1'); +} +if (! defined('NOTOKENRENEWAL')) { + define('NOTOKENRENEWAL', '1'); +} +if (! defined('NOREQUIREMENU')) { + define('NOREQUIREMENU', '1'); // If there is no menu to show +} +if (! defined('NOREQUIREHTML')) { + define('NOREQUIREHTML', '1'); // If we don't need to load the html.form.class.php +} +if (! defined('NOREQUIREAJAX')) { + define('NOREQUIREAJAX', '1'); +} +if (! defined("NOLOGIN")) { + define("NOLOGIN", '1'); // If this page is public (can be called outside logged session) +} +if (! defined("NOSESSION")) { + define("NOSESSION", '1'); +} + +require_once dirname(__FILE__).'/../../htdocs/main.inc.php'; // We force include of main.inc.php instead of master.inc.php even if we are in CLI mode because it contains a lot of security components we want to test. +require_once dirname(__FILE__).'/../../htdocs/core/lib/security.lib.php'; +require_once dirname(__FILE__).'/../../htdocs/core/lib/security2.lib.php'; +require_once dirname(__FILE__).'/CommonClassTest.class.php'; + +if (empty($user->id)) { + print "Load permissions for admin user nb 1\n"; + $user->fetch(1); + $user->loadRights(); +} +$conf->global->MAIN_DISABLE_ALL_MAILS = 1; + + +/** + * Class for PHPUnit tests + * + * @backupGlobals disabled + * @backupStaticAttributes enabled + * @remarks backupGlobals must be disabled to have db,conf,user and lang not erased. + */ +class SecurityLoginTest extends CommonClassTest +{ + /** + * testCheckLoginPassEntity + * + * @return void + */ + public function testCheckLoginPassEntity() + { + $login = checkLoginPassEntity('loginbidon', 'passwordbidon', 1, array('dolibarr')); + print __METHOD__." login=".$login."\n"; + $this->assertEquals($login, ''); + + $login = checkLoginPassEntity('admin', 'passwordbidon', 1, array('dolibarr')); + print __METHOD__." login=".$login."\n"; + $this->assertEquals($login, ''); + + $login = checkLoginPassEntity('admin', 'admin', 1, array('dolibarr')); // Should works because admin/admin exists + print __METHOD__." login=".$login."\n"; + $this->assertEquals($login, 'admin', 'The test to check if pass of user "admin" is "admin" has failed'); + + $login = checkLoginPassEntity('admin', 'admin', 1, array('http','dolibarr')); // Should work because of second authentication method + print __METHOD__." login=".$login."\n"; + $this->assertEquals($login, 'admin'); + + $login = checkLoginPassEntity('admin', 'admin', 1, array('forceuser')); + print __METHOD__." login=".$login."\n"; + $this->assertEquals('', $login, 'Error'); // Expected '' because should failed because login 'auto' does not exists + } +} diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 294d1596fec..9b5db827bc3 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -636,13 +636,13 @@ class SecurityTest extends CommonClassTest $this->assertEquals('Bad string syntax to evaluate: new __forbiddenstring__(\'abc\')', $result); - $result = (string) dol_eval('$a=function() { }; $a;', 1, 1, '0'); - print "result5 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $result = dol_eval('$a=function() { }; $a', 1, 1, '0'); // result of dol_eval may be an object Closure + print "result5 = ".json_encode($result)."\n"; + $this->assertStringContainsString('Bad string syntax to evaluate', json_encode($result)); - $result = (string) dol_eval('$a=function() { }; $a;', 1, 1, '1'); - print "result6 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $result = dol_eval('$a=function() { }; $a();', 1, 1, '1'); + print "result6 = ".json_encode($result)."\n"; + $this->assertStringContainsString('Bad string syntax to evaluate', json_encode($result)); $result = (string) dol_eval('$a=exec("ls");', 1, 1); print "result7 = ".$result."\n"; @@ -723,6 +723,11 @@ class SecurityTest extends CommonClassTest $result = (string) dol_eval('($a = "ex") && ($b = "ec") && ($cmd = "$a$b") && $cmd ("curl localhost:5555")', 1, 0); print "result22 = ".$result."\n"; $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 22'); + + + $result = (string) dol_eval('\'exec\'("aaa")', 1, 0); + print "result1 = ".$result."\n"; + $this->assertStringContainsString('Bad string syntax to evaluate', json_encode($result), 'Cant find the string Bad string syntaxwhen i should'); } /** @@ -966,33 +971,4 @@ class SecurityTest extends CommonClassTest return 0; } - - - /** - * testCheckLoginPassEntity - * - * @return void - */ - public function testCheckLoginPassEntity() - { - $login = checkLoginPassEntity('loginbidon', 'passwordbidon', 1, array('dolibarr')); - print __METHOD__." login=".$login."\n"; - $this->assertEquals($login, ''); - - $login = checkLoginPassEntity('admin', 'passwordbidon', 1, array('dolibarr')); - print __METHOD__." login=".$login."\n"; - $this->assertEquals($login, ''); - - $login = checkLoginPassEntity('admin', 'admin', 1, array('dolibarr')); // Should works because admin/admin exists - print __METHOD__." login=".$login."\n"; - $this->assertEquals($login, 'admin', 'The test to check if pass of user "admin" is "admin" has failed'); - - $login = checkLoginPassEntity('admin', 'admin', 1, array('http','dolibarr')); // Should work because of second authentication method - print __METHOD__." login=".$login."\n"; - $this->assertEquals($login, 'admin'); - - $login = checkLoginPassEntity('admin', 'admin', 1, array('forceuser')); - print __METHOD__." login=".$login."\n"; - $this->assertEquals('', $login, 'Error'); // Expected '' because should failed because login 'auto' does not exists - } } diff --git a/test/phpunit/WebsiteTest.php b/test/phpunit/WebsiteTest.php index 6ccccb17b23..bbf80cad4c5 100644 --- a/test/phpunit/WebsiteTest.php +++ b/test/phpunit/WebsiteTest.php @@ -65,11 +65,11 @@ if (empty($user->id)) { print "Load permissions for admin user nb 1\n"; $user->fetch(1); $user->loadRights(); - - if (empty($user->rights->website)) { - $user->rights->website = new stdClass(); - } } +if (empty($user->rights->website)) { + $user->rights->website = new stdClass(); +} + $conf->global->MAIN_DISABLE_ALL_MAILS = 1; @@ -132,22 +132,61 @@ class WebsiteTest extends CommonClassTest */ public function testCheckPHPCode() { - global $user; + global $conf, $user; // Force permission so this is not the permission that will affect result of checkPHPCode $user->rights->website->writephp = 1; + // Legitimate + + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 0, 'checkPHPCode detect string as dangerous when it is legitimate'); + + + // Dangerous + $t = ''; $s = ''; $result = checkPHPCode($t, $s); print __METHOD__." result checkPHPCode=".$result."\n"; $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + $t = ''; $s = ';").($_^"/"); ?>'; $result = checkPHPCode($t, $s); print __METHOD__." result checkPHPCode=".$result."\n"; $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + + // Dangerous but legitimate due to option WEBSITE_PHP_ALLOW_EXEC + + $conf->global->WEBSITE_PHP_ALLOW_EXEC = 1; + + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 0, 'checkPHPCode did not accept the exec. it should when WEBSITE_PHP_ALLOW_EXEC is set.'); } /**