From 34e3717dda5266d71a7a97b2f3fe1b553e4fb1ad Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 6 Oct 2024 13:03:43 +0200 Subject: [PATCH] Qual: Fix phan/phpstan notices (#31289) * Qual: Fix phan/phpstan notices # Qual: Fix phan/phpstan notices Fix several phan/phpstan notices * Fix spelling in Changelog --- ChangeLog | 4 +- dev/tools/codespell/codespell-dict.txt | 3 +- dev/tools/phan/baseline.txt | 45 +++---- htdocs/admin/system/dolibarr.php | 6 +- htdocs/core/lib/functions.lib.php | 24 ++-- .../modules/project/mod_project_simple.php | 2 +- .../modules/project/mod_project_universal.php | 2 +- .../core/modules/project/modules_project.php | 2 +- htdocs/product/card.php | 22 ++-- .../class/productfournisseurprice.class.php | 121 ++++++++++++++++-- htdocs/product/stock/massstockmove.php | 13 +- .../class/stocktransfer.class.php | 32 ++++- .../class/stocktransferline.class.php | 30 ++++- .../lib/stocktransfer_stocktransfer.lib.php | 3 +- .../stocktransfer/stocktransfer_card.php | 8 +- .../product/stock/tpl/stockcorrection.tpl.php | 12 +- .../product/stock/tpl/stocktransfer.tpl.php | 11 +- htdocs/projet/activity/index.php | 3 + htdocs/projet/admin/project.php | 6 +- htdocs/projet/card.php | 11 +- htdocs/projet/class/api_projects.class.php | 29 ++++- htdocs/projet/class/project.class.php | 2 +- htdocs/projet/element.php | 13 +- htdocs/projet/tasks/time.php | 12 +- htdocs/public/cron/cron_run_jobs_by_url.php | 5 +- htdocs/public/project/new.php | 2 + htdocs/societe/class/societe.class.php | 2 +- phpstan.neon.dist | 5 +- 28 files changed, 317 insertions(+), 113 deletions(-) diff --git a/ChangeLog b/ChangeLog index 73f9213db94..a5a0368f783 100644 --- a/ChangeLog +++ b/ChangeLog @@ -165,7 +165,7 @@ NEW: Module Website: Can link/unlink translation between web pages NEW: Move dir of cache for widgets NEW: multiselect with checkbox in categories/tags search for thirdparty list (#28335) NEW: new consts to redirect from massaction createbills (#29436) -NEW: new global string to preselect yes for one bill per thirparty in orderlist massaction (#29359) +NEW: new global string to preselect yes for one bill per third party in orderlist massaction (#29359) NEW: notification action triggers for cancelling orders and invoices NEW: now button when editing an event NEW: online signature of shipments (#29559) @@ -3303,7 +3303,7 @@ FIX: fix checkbox displayed according to module project setup parameters - work FIX: inconsistency in margin recording with option "Force to sale price" FIX: invoice PDF generation after payment FIX: mask selector fournisseur if module not activate -FIX: merge thirparty also work for bank URL entry +FIX: merge third party also works for bank URL entry FIX: Missing extrafields into export of agenda record FIX: missing parameter in select for POP FIX: missing return edit if update error diff --git a/dev/tools/codespell/codespell-dict.txt b/dev/tools/codespell/codespell-dict.txt index 9b3a3e36f02..f26d7250488 100644 --- a/dev/tools/codespell/codespell-dict.txt +++ b/dev/tools/codespell/codespell-dict.txt @@ -43,7 +43,8 @@ tableau de bord->state board tagret->target tdoverflowmax100aaa->tdoverflowmax100 tdoverlowmax200->tdoverflowmax200 -thridparty->thirdparty +thirparty->thirdparty, third party, +thridparty->thirdparty, third party, with100->width100 with75->width75 wysiwig->wysiwyg diff --git a/dev/tools/phan/baseline.txt b/dev/tools/phan/baseline.txt index 781764f5fe1..e30ba6f11ff 100644 --- a/dev/tools/phan/baseline.txt +++ b/dev/tools/phan/baseline.txt @@ -9,35 +9,35 @@ */ return [ // # Issue statistics: - // PhanPluginUnknownPropertyType : 1150+ occurrences - // PhanUndeclaredProperty : 850+ occurrences - // PhanPossiblyUndeclaredGlobalVariable : 660+ occurrences - // PhanTypeMismatchArgumentProbablyReal : 500+ occurrences + // PhanPluginUnknownPropertyType : 1100+ occurrences + // PhanUndeclaredProperty : 840+ occurrences + // PhanPossiblyUndeclaredGlobalVariable : 640+ occurrences + // PhanTypeMismatchArgumentProbablyReal : 490+ occurrences // PhanUndeclaredGlobalVariable : 420+ occurrences // PhanPluginUnknownArrayMethodReturnType : 410+ occurrences - // PhanPluginUnknownArrayMethodParamType : 310+ occurrences + // PhanPluginUnknownArrayMethodParamType : 300+ occurrences // PhanPossiblyUndeclaredVariable : 270+ occurrences // PhanTypeMismatchProperty : 180+ occurrences // PhanPluginUnknownArrayFunctionReturnType : 140+ occurrences // PhanPluginUnknownArrayFunctionParamType : 120+ occurrences - // PhanTypeMismatchArgumentNullableInternal : 75+ occurrences // PhanPluginUnknownArrayPropertyType : 70+ occurrences + // PhanTypeMismatchArgumentNullableInternal : 70+ occurrences // PhanPluginUndeclaredVariableIsset : 65+ occurrences // PhanPluginEmptyStatementIf : 50+ occurrences - // PhanPluginUnknownObjectMethodCall : 50+ occurrences // PhanRedefineFunction : 50+ occurrences // PhanTypeSuspiciousNonTraversableForeach : 50+ occurrences + // PhanPluginUnknownObjectMethodCall : 40+ occurrences // PhanTypeInvalidDimOffset : 35+ occurrences // PhanTypeMismatchDimFetch : 30+ occurrences // PhanTypeExpectedObjectPropAccess : 25+ occurrences // PhanPossiblyNullTypeMismatchProperty : 15+ occurrences // PhanTypeComparisonFromArray : 15+ occurrences // PhanUndeclaredConstant : 15+ occurrences - // PhanUndeclaredMethod : 15+ occurrences // PhanEmptyForeach : 10+ occurrences // PhanPluginConstantVariableNull : 10+ occurrences // PhanPluginSuspiciousParamPosition : 10+ occurrences // PhanTypeMismatchDimFetchNullable : 10+ occurrences + // PhanUndeclaredMethod : 10+ occurrences // PhanPluginBothLiteralsBinaryOp : 8 occurrences // PhanPluginDuplicateExpressionBinaryOp : 7 occurrences // PhanParamTooMany : 5 occurrences @@ -709,13 +709,13 @@ return [ 'htdocs/product/ajax/products.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/product/canvas/product/actions_card_product.class.php' => ['PhanTypeSuspiciousNonTraversableForeach'], 'htdocs/product/canvas/service/actions_card_service.class.php' => ['PhanPluginUnknownPropertyType', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeSuspiciousNonTraversableForeach'], - 'htdocs/product/card.php' => ['PhanPossiblyNullTypeMismatchProperty', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchProperty', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredMethod', 'PhanUndeclaredProperty'], + 'htdocs/product/card.php' => ['PhanPossiblyNullTypeMismatchProperty', 'PhanTypeMismatchProperty', 'PhanUndeclaredGlobalVariable'], 'htdocs/product/class/api_products.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanTypeSuspiciousNonTraversableForeach', 'PhanUndeclaredProperty'], 'htdocs/product/class/html.formproduct.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/product/class/product.class.php' => ['PhanPluginUnknownArrayMethodParamType'], 'htdocs/product/class/productbatch.class.php' => ['PhanPluginEmptyStatementIf', 'PhanPluginUnknownPropertyType'], 'htdocs/product/class/productcustomerprice.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownPropertyType'], - 'htdocs/product/class/productfournisseurprice.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownObjectMethodCall', 'PhanPluginUnknownPropertyType', 'PhanUndeclaredProperty'], + 'htdocs/product/class/productfournisseurprice.class.php' => ['PhanUndeclaredMethod', 'PhanUndeclaredProperty'], 'htdocs/product/class/propalmergepdfproduct.class.php' => ['PhanPluginUnknownPropertyType'], 'htdocs/product/document.php' => ['PhanPossiblyNullTypeMismatchProperty', 'PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/product/dynamic_price/class/price_global_variable.class.php' => ['PhanPluginEmptyStatementIf', 'PhanPluginUnknownPropertyType'], @@ -740,7 +740,6 @@ return [ 'htdocs/product/stock/class/productstockentrepot.class.php' => ['PhanPluginUnknownPropertyType'], 'htdocs/product/stock/info.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/product/stock/list.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], - 'htdocs/product/stock/massstockmove.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanTypeMismatchArgumentNullableInternal'], 'htdocs/product/stock/movement_card.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/product/stock/movement_list.php' => ['PhanPluginBothLiteralsBinaryOp', 'PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchProperty', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/product/stock/product.php' => ['PhanPossiblyUndeclaredGlobalVariable'], @@ -752,28 +751,24 @@ return [ 'htdocs/product/stock/stats/mo.php' => ['PhanUndeclaredProperty'], 'htdocs/product/stock/stats/reception.php' => ['PhanUndeclaredProperty'], 'htdocs/product/stock/stockatdate.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/product/stock/stocktransfer/class/stocktransfer.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownObjectMethodCall', 'PhanPluginUnknownPropertyType'], - 'htdocs/product/stock/stocktransfer/class/stocktransferline.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownObjectMethodCall', 'PhanPluginUnknownPropertyType', 'PhanUndeclaredProperty'], + 'htdocs/product/stock/stocktransfer/class/stocktransferline.class.php' => ['PhanUndeclaredProperty'], 'htdocs/product/stock/stocktransfer/lib/stocktransfer.lib.php' => ['PhanPluginUnknownArrayFunctionReturnType'], - 'htdocs/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php' => ['PhanPluginUnknownArrayFunctionReturnType'], - 'htdocs/product/stock/stocktransfer/stocktransfer_card.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable'], + 'htdocs/product/stock/stocktransfer/stocktransfer_card.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/product/stock/stocktransfer/stocktransfer_list.php' => ['PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/product/stock/tpl/stockcorrection.tpl.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], - 'htdocs/product/stock/tpl/stocktransfer.tpl.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], - 'htdocs/projet/activity/index.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeExpectedObjectPropAccessButGotNull', 'PhanUndeclaredGlobalVariable'], + 'htdocs/product/stock/tpl/stockcorrection.tpl.php' => ['PhanUndeclaredProperty'], + 'htdocs/product/stock/tpl/stocktransfer.tpl.php' => ['PhanUndeclaredProperty'], + 'htdocs/projet/activity/index.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanTypeExpectedObjectPropAccessButGotNull', 'PhanUndeclaredGlobalVariable'], 'htdocs/projet/activity/perday.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/projet/activity/perweek.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/projet/admin/project.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanTypeMismatchArgumentProbablyReal'], + 'htdocs/projet/admin/project.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/projet/ajax/projects.php' => ['PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/projet/card.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable'], - 'htdocs/projet/class/api_projects.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanPluginUnknownObjectMethodCall'], + 'htdocs/projet/card.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/projet/class/api_tasks.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType'], - 'htdocs/projet/class/project.class.php' => ['PhanPossiblyUndeclaredVariable'], 'htdocs/projet/class/projectstats.class.php' => ['PhanPluginUnknownArrayMethodReturnType', 'PhanPluginUnknownPropertyType', 'PhanPossiblyUndeclaredVariable'], 'htdocs/projet/class/task.class.php' => ['PhanPluginEmptyStatementIf', 'PhanPluginUnknownArrayMethodReturnType', 'PhanPluginUnknownPropertyType'], 'htdocs/projet/class/taskstats.class.php' => ['PhanPluginUnknownArrayMethodReturnType', 'PhanPluginUnknownPropertyType'], 'htdocs/projet/contact.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeComparisonFromArray', 'PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/projet/element.php' => ['PhanPluginUnknownArrayFunctionParamType', 'PhanPluginUnknownArrayFunctionReturnType', 'PhanPluginUnknownObjectMethodCall', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], + 'htdocs/projet/element.php' => ['PhanUndeclaredProperty'], 'htdocs/projet/ganttchart.inc.php' => ['PhanPluginUnknownArrayFunctionParamType', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable'], 'htdocs/projet/ganttview.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/projet/graph_opportunities.inc.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanUndeclaredGlobalVariable'], @@ -792,7 +787,7 @@ return [ 'htdocs/public/agenda/agendaexport.php' => ['PhanRedefineFunction'], 'htdocs/public/bookcal/index.php' => ['PhanRedefineFunction'], 'htdocs/public/company/new.php' => ['PhanRedefineFunction', 'PhanUndeclaredGlobalVariable'], - 'htdocs/public/cron/cron_run_jobs_by_url.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], + 'htdocs/public/cron/cron_run_jobs_by_url.php' => ['PhanUndeclaredProperty'], 'htdocs/public/demo/index.php' => ['PhanRedefineFunction'], 'htdocs/public/donations/donateurs_code.php' => ['PhanRedefineFunction'], 'htdocs/public/emailing/mailing-read.php' => ['PhanRedefineFunction'], @@ -808,7 +803,7 @@ return [ 'htdocs/public/payment/paymentko.php' => ['PhanPluginEmptyStatementIf', 'PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/public/payment/paymentok.php' => ['PhanPluginSuspiciousParamPosition', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeExpectedObjectPropAccess', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable'], 'htdocs/public/project/index.php' => ['PhanRedefineFunction', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable'], - 'htdocs/public/project/new.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanRedefineFunction', 'PhanUndeclaredProperty'], + 'htdocs/public/project/new.php' => ['PhanRedefineFunction', 'PhanUndeclaredProperty'], 'htdocs/public/project/suggestbooth.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanRedefineFunction', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/public/project/suggestconference.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanRedefineFunction', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/public/project/viewandvote.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredGlobalVariable'], diff --git a/htdocs/admin/system/dolibarr.php b/htdocs/admin/system/dolibarr.php index 19c7ec5f819..a216e256d55 100644 --- a/htdocs/admin/system/dolibarr.php +++ b/htdocs/admin/system/dolibarr.php @@ -244,10 +244,10 @@ print ''.$langs->trans("CurrentValueSeparatorThousand"). $dec = $langs->transnoentitiesnoconv("SeparatorDecimal"); print ''.$langs->trans("CurrentValueSeparatorDecimal").''.$dec.''."\n"; // Show results of functions to see if everything works -print '  => price2num(1233.56+1)'.price2num(1233.56 + 1, '2').''."\n"; -print '  => price2num('."'1".$thousand."234".$dec."56')".price2num("1".$thousand."234".$dec."56", '2')."\n"; +print '  => price2num(1233.56+1)'.price2num(1233.56 + 1, 2).''."\n"; +print '  => price2num('."'1".$thousand."234".$dec."56')".price2num("1".$thousand."234".$dec."56", 2)."\n"; if (($thousand != ',' && $thousand != '.') || ($thousand != ' ')) { - print '  => price2num('."'1 234.56')".price2num("1 234.56", '2').""; + print '  => price2num('."'1 234.56')".price2num("1 234.56", 2).""; print "\n"; } print '  => price(1234.56)'.price(1234.56).''."\n"; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 36320d98fb5..f0c1d6c19aa 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1102,7 +1102,7 @@ function GETPOSTINT($paramname, $method = 0) * Return the value of a $_GET or $_POST supervariable, converted into float. * * @param string $paramname Name of the $_GET or $_POST parameter - * @param string|int $rounding Type of rounding ('', 'MU', 'MT, 'MS', 'CU', 'CT', integer) {@see price2num()} + * @param ''|'MU'|'MT'|'MS'|'CU'|'CT'|int $rounding Type of rounding ('', 'MU', 'MT, 'MS', 'CU', 'CT', integer) {@see price2num()} * @return float Value converted into float * @since Dolibarr V20 */ @@ -6670,8 +6670,8 @@ function vatrate($rate, $addpercent = false, $info_bits = 0, $usestarfornpr = 0, * @param int<0,1> $form Type of formatting: 1=HTML, 0=no formatting (no by default) * @param Translate|string|null $outlangs Object langs for output. '' use default lang. 'none' use international separators. * @param int $trunc 1=Truncate if there is more decimals than MAIN_MAX_DECIMALS_SHOWN (default), 0=Does not truncate. Deprecated because amount are rounded (to unit or total amount accuracy) before being inserted into database or after a computation, so this parameter should be useless. - * @param int $rounding MINIMUM number of decimal to show: 0=no change, -1=we use min(getDolGlobalString('MAIN_MAX_DECIMALS_UNIT'), getDolGlobalString('MAIN_MAX_DECIMALS_TOT')) - * @param int|string $forcerounding MAXIMUM number of decimal to forcerounding decimal: -1=no change, -2=keep non zero part, 'MU' or 'MT' or a numeric to round to MU or MT or to a given number of decimal + * @param int<-1,max> $rounding MINIMUM number of decimal to show: 0=no change, -1=we use min(getDolGlobalString('MAIN_MAX_DECIMALS_UNIT'), getDolGlobalString('MAIN_MAX_DECIMALS_TOT')) + * @param ''|'MU'|'MT'|'MS'|'CU'|'CT'|int<-2,max> $forcerounding MAXIMUM number of decimal to forcerounding decimal: -1=no change, -2=keep non zero part, 'MU' or 'MT' or a numeric to round to MU or MT or to a given number of decimal * @param string $currency_code To add currency symbol (''=add nothing, 'auto'=Use default currency, 'XXX'=add currency symbols for XXX currency) * @return string String with formatted amount * @@ -6786,14 +6786,14 @@ function price($amount, $form = 0, $outlangs = '', $trunc = 1, $rounding = -1, $ * should be roundtext2num(). * * @param string|float $amount Amount to convert/clean or round - * @param string|int $rounding ''=No rounding - * 'MU'=Round to Max unit price (MAIN_MAX_DECIMALS_UNIT) - * 'MT'=Round to Max for totals with Tax (MAIN_MAX_DECIMALS_TOT) - * 'MS'=Round to Max for stock quantity (MAIN_MAX_DECIMALS_STOCK) - * 'CU'=Round to Max unit price of foreign currency accuracy - * 'CT'=Round to Max for totals with Tax of foreign currency accuracy - * Numeric = Nb of digits for rounding (For example 2 for a percentage) - * @param int $option Put 1 if you know that content is already universal format number (so no correction on decimal will be done) + * @param ''|'MU'|'MT'|'MS'|'CU'|'CT'|int<0,max> $rounding ''=No rounding + * 'MU'=Round to Max unit price (MAIN_MAX_DECIMALS_UNIT) + * 'MT'=Round to Max for totals with Tax (MAIN_MAX_DECIMALS_TOT) + * 'MS'=Round to Max for stock quantity (MAIN_MAX_DECIMALS_STOCK) + * 'CU'=Round to Max unit price of foreign currency accuracy + * 'CT'=Round to Max for totals with Tax of foreign currency accuracy + * Numeric = Nb of digits for rounding (For example 2 for a percentage) + * @param int<0,2> $option Put 1 if you know that content is already universal format number (so no correction on decimal will be done) * Put 2 if you know that number is a user input (so we know we have to fix decimal separator). * @return string Amount with universal numeric format (Example: '99.99999'), or error message. * If conversion fails to return a numeric, it returns: @@ -6931,7 +6931,7 @@ function price2num($amount, $rounding = '', $option = 0) * @param int $unit Unit scale of dimension (Example: 0=kg, -3=g, -6=mg, 98=ounce, 99=pound, ...) * @param string $type 'weight', 'volume', ... * @param Translate $outputlangs Translate language object - * @param int $round -1 = non rounding, x = number of decimal + * @param int<-1,max> $round -1 = non rounding, x = number of decimal * @param string $forceunitoutput 'no' or numeric (-3, -6, ...) compared to $unit (In most case, this value is value defined into $conf->global->MAIN_WEIGHT_DEFAULT_UNIT) * @param int $use_short_label 1=Use short label ('g' instead of 'gram'). Short labels are not translated. * @return string String to show dimensions diff --git a/htdocs/core/modules/project/mod_project_simple.php b/htdocs/core/modules/project/mod_project_simple.php index 1d4df75aaf2..5319b83156e 100644 --- a/htdocs/core/modules/project/mod_project_simple.php +++ b/htdocs/core/modules/project/mod_project_simple.php @@ -123,7 +123,7 @@ class mod_project_simple extends ModeleNumRefProjects /** * Return next value * - * @param Societe $objsoc Object third party + * @param ?Societe $objsoc Object third party * @param Project $project Object project * @return string|int<-1,0> Value if OK, 0 if KO */ diff --git a/htdocs/core/modules/project/mod_project_universal.php b/htdocs/core/modules/project/mod_project_universal.php index 93215ba2bf0..2be62efa5f3 100644 --- a/htdocs/core/modules/project/mod_project_universal.php +++ b/htdocs/core/modules/project/mod_project_universal.php @@ -133,7 +133,7 @@ class mod_project_universal extends ModeleNumRefProjects /** * Return next value * - * @param Societe $objsoc Object third party + * @param ?Societe $objsoc Object third party * @param Project $project Object project * @return string|int<-1,0> Value if OK, 0 if KO */ diff --git a/htdocs/core/modules/project/modules_project.php b/htdocs/core/modules/project/modules_project.php index 92bd6d61c77..48885f0e4c7 100644 --- a/htdocs/core/modules/project/modules_project.php +++ b/htdocs/core/modules/project/modules_project.php @@ -87,7 +87,7 @@ abstract class ModeleNumRefProjects extends CommonNumRefGenerator /** * Return next value * - * @param Societe $objsoc Object third party + * @param ?Societe $objsoc Object third party * @param Project $project Object project * @return string|int<-1,0> Value if OK, 0 if KO */ diff --git a/htdocs/product/card.php b/htdocs/product/card.php index a2634994085..331ff7d85fc 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -518,14 +518,14 @@ if (empty($reshook)) { $object->price_base_type = GETPOST('price_base_type', 'aZ09'); $object->mandatory_period = !empty(GETPOST("mandatoryperiod", 'alpha')) ? 1 : 0; if ($object->price_base_type == 'TTC') { - $object->price_ttc = GETPOST('price'); + $object->price_ttc = GETPOSTFLOAT('price'); } else { - $object->price = GETPOST('price'); + $object->price = GETPOSTFLOAT('price'); } if ($object->price_base_type == 'TTC') { - $object->price_min_ttc = GETPOST('price_min'); + $object->price_min_ttc = GETPOSTFLOAT('price_min'); } else { - $object->price_min = GETPOST('price_min'); + $object->price_min = GETPOSTFLOAT('price_min'); } $tva_tx_txt = GETPOST('tva_tx', 'alpha'); // tva_tx can be '8.5' or '8.5*' or '8.5 (XXX)' or '8.5* (XXX)' @@ -570,13 +570,13 @@ if (empty($reshook)) { $object->localtax2_type = $localtax2_type; $object->type = $type; - $object->status = GETPOST('statut'); - $object->status_buy = GETPOST('statut_buy'); - $object->status_batch = GETPOST('status_batch'); + $object->status = GETPOSTINT('statut'); + $object->status_buy = GETPOSTINT('statut_buy'); + $object->status_batch = GETPOSTINT('status_batch'); $object->sell_or_eat_by_mandatory = GETPOSTINT('sell_or_eat_by_mandatory'); $object->batch_mask = GETPOST('batch_mask'); - $object->barcode_type = GETPOST('fk_barcode_type'); + $object->barcode_type = GETPOSTINT('fk_barcode_type'); $object->barcode = GETPOST('barcode'); // Set barcode_type_xxx from barcode_type id $stdobject = new GenericObject($db); @@ -821,7 +821,7 @@ if (empty($reshook)) { $object->fk_unit = null; } - $object->barcode_type = GETPOST('fk_barcode_type'); + $object->barcode_type = GETPOSTINT('fk_barcode_type'); $object->barcode = GETPOST('barcode'); // Set barcode_type_xxx from barcode_type id $stdobject = new GenericObject($db); @@ -1183,7 +1183,7 @@ if (empty($reshook)) { '', '', '', - 0, + array(), $object->fk_unit ); if ($result > 0) { @@ -1344,7 +1344,7 @@ if (isModEnabled('barcode') && getDolGlobalString('BARCODE_PRODUCT_ADDON_NUM')) } if ($res > 0) { $modBarCodeProduct = new $module(); - '@phan-var-force ModeleBarCode $modBarCodeProduct'; + '@phan-var-force ModeleNumRefBarCode $modBarCodeProduct'; } } diff --git a/htdocs/product/class/productfournisseurprice.class.php b/htdocs/product/class/productfournisseurprice.class.php index 27636098c5a..b0f9850423f 100644 --- a/htdocs/product/class/productfournisseurprice.class.php +++ b/htdocs/product/class/productfournisseurprice.class.php @@ -120,39 +120,141 @@ class ProductFournisseurPrice extends CommonObject 'fk_barcode_type' => array('type' => 'integer', 'label' => 'Fkbarcodetype', 'enabled' => '1', 'position' => 175, 'notnull' => 0, 'visible' => -1,), 'packaging' => array('type' => 'varchar(64)', 'label' => 'Packaging', 'enabled' => '1', 'position' => 180, 'notnull' => 0, 'visible' => -1,), ); + /** + * @var int + */ public $rowid; + /** + * @var int + */ public $entity; + /** + * @var int|string + */ public $datec; + /** + * @var int + */ public $fk_product; + /** + * @var int + */ public $fk_soc; + /** + * @var string + */ public $ref_fourn; + /** + * @var string + */ public $desc_fourn; + /** + * @var int + */ public $fk_availability; + /** + * @var float + */ public $price; + /** + * @var float + */ public $quantity; + /** + * @var float + */ public $remise_percent; + /** + * @var float + */ public $remise; + /** + * @var float + */ public $unitprice; + /** + * @var float + */ public $charges; + /** + * @var string + */ public $default_vat_code; + /** + * @var float + */ public $tva_tx; + /** + * @var int + */ public $info_bits; + /** + * @var int + */ public $fk_user; + /** + * @var int + */ public $fk_supplier_price_expression; + /** + * @var string + */ public $import_key; + /** + * @var int + */ public $delivery_time_days; + /** + * @var string + */ public $supplier_reputation; + /** + * @var int + */ public $fk_multicurrency; + /** + * @var string + */ public $multicurrency_code; + /** + * @var float + */ public $multicurrency_tx; + /** + * @var float + */ public $multicurrency_price; + /** + * @var float + */ public $multicurrency_unitprice; + /** + * @var float + */ public $localtax1_tx; + /** + * @var string + */ public $localtax1_type; + /** + * @var float + */ public $localtax2_tx; + /** + * @var string + */ public $localtax2_type; + /** + * @var string + */ public $barcode; + /** + * @var int + */ public $fk_barcode_type; + /** + * @var string + */ public $packaging; // END MODULEBUILDER PROPERTIES @@ -601,11 +703,11 @@ class ProductFournisseurPrice extends CommonObject /** * Return a link to the object card (with optionally the picto) * - * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) - * @param string $option On what the link point to ('nolink', ...) - * @param int $notooltip 1=Disable tooltip - * @param string $morecss Add more css on link - * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @param int<0,2> $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) + * @param string $option On what the link point to ('nolink', ...) + * @param int<0,1> $notooltip 1=Disable tooltip + * @param string $morecss Add more css on link + * @param int<-1,1> $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking * @return string String with URL */ public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1) @@ -826,6 +928,7 @@ class ProductFournisseurPrice extends CommonObject if (class_exists($classname)) { $obj = new $classname(); + '@phan-var-force CommonNumRefGenerator $obj'; $numref = $obj->getNextValue($this); if ($numref != '' && $numref != '-1') { @@ -850,10 +953,10 @@ class ProductFournisseurPrice extends CommonObject * * @param string $modele Force template to use ('' to not force) * @param Translate $outputlangs object lang a utiliser pour traduction - * @param int $hidedetails Hide details of lines - * @param int $hidedesc Hide description - * @param int $hideref Hide ref - * @param null|array $moreparams Array to provide more information + * @param int<0,1> $hidedetails Hide details of lines + * @param int<0,1> $hidedesc Hide description + * @param int<0,1> $hideref Hide ref + * @param ?array $moreparams Array to provide more information * @return int 0 if KO, 1 if OK */ public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null) diff --git a/htdocs/product/stock/massstockmove.php b/htdocs/product/stock/massstockmove.php index e1d9b2cdf8b..463b39d5723 100644 --- a/htdocs/product/stock/massstockmove.php +++ b/htdocs/product/stock/massstockmove.php @@ -88,6 +88,9 @@ if (GETPOST('init')) { $listofdata = array(); if (!empty($_SESSION['massstockmove'])) { $listofdata = json_decode($_SESSION['massstockmove'], true); + if (!is_array($listofdata)) { + $listofdata = array(); + } } $error = 0; @@ -693,17 +696,17 @@ if (getDolGlobalInt('PRODUIT_LIMIT_SIZE') <= 0) { $limit = getDolGlobalString('PRODUIT_LIMIT_SIZE'); } print img_picto($langs->trans("Product"), 'product', 'class="paddingright"'); -print $form->select_produits((isset($id_product)?$id_product:0), 'productid', $filtertype, $limit, 0, -1, 2, '', 1, array(), 0, '1', 0, 'minwidth200imp maxwidth300', 1, '', null, 1); +print $form->select_produits((isset($id_product) ? $id_product : 0), 'productid', $filtertype, $limit, 0, -1, 2, '', 1, array(), 0, '1', 0, 'minwidth200imp maxwidth300', 1, '', null, 1); print ''; // Batch number if (isModEnabled('productbatch')) { print ''; print img_picto($langs->trans("LotSerial"), 'lot', 'class="paddingright"'); - print ''; + print ''; print ''; } // Qty -print ''; +print ''; // Button to add line print ''; @@ -821,7 +824,7 @@ function startsWith($haystack, $needle) /** * Fetch object with ref * - * @param Object $static_object static object to fetch + * @param CommonObject $static_object static object to fetch * @param string $tmp_ref ref of the object to fetch * @return int Return integer <0 if Ko or Id of object */ @@ -831,6 +834,6 @@ function fetchref($static_object, $tmp_ref) $tmp_ref = str_replace('ref:', '', $tmp_ref); } $static_object->id = 0; - $static_object->fetch('', $tmp_ref); + $static_object->fetch(0, $tmp_ref); return $static_object->id; } diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index 4ba9ea6f01e..b5dcf359398 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -169,22 +169,41 @@ class StockTransfer extends CommonObject 'location_incoterms' => array('type' => 'varchar(255)', 'label' => 'IncotermLabel', 'enabled' => '$conf->incoterm->enabled', 'visible' => -2, 'position' => 225), 'status' => array('type' => 'smallint', 'label' => 'Status', 'enabled' => 1, 'position' => 1000, 'notnull' => 1, 'visible' => 5, 'index' => 1, 'arrayofkeyval' => array('0' => 'Draft', '1' => 'Validated', '2' => 'StockStransferDecremented', '3' => 'StockStransferIncremented'),), ); + /** + * @var int + */ public $rowid; + /** + * @var string + */ public $ref; + /** + * @var string + */ public $label; + + /** + * @var string + */ public $description; /** - * @var int ID of thirparty + * @var int ID of third party */ public $socid; /** - * @var int ID of thirparty + * @var int ID of third party * @deprecated */ public $fk_soc; + /** + * @var int + */ public $lead_time_for_warning; + /** + * @var int + */ public $status; /** @@ -1014,6 +1033,7 @@ class StockTransfer extends CommonObject if (class_exists($classname)) { $obj = new $classname(); + '@phan-var-force ModeleNumRefStockTransfer $obj'; $numref = $obj->getNextValue($this); if ($numref != '' && $numref != '-1') { @@ -1038,10 +1058,10 @@ class StockTransfer extends CommonObject * * @param string $modele Force template to use ('' to not force) * @param Translate $outputlangs object lang a utiliser pour traduction - * @param int $hidedetails Hide details of lines - * @param int $hidedesc Hide description - * @param int $hideref Hide ref - * @param null|array $moreparams Array to provide more information + * @param int<0,1> $hidedetails Hide details of lines + * @param int<0,1> $hidedesc Hide description + * @param int<0,1> $hideref Hide ref + * @param ?array $moreparams Array to provide more information * @return int 0 if KO, 1 if OK */ public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null) diff --git a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php index 6d4ec87f02e..bcaf9d3d6f7 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransferline.class.php @@ -96,17 +96,38 @@ class StockTransferLine extends CommonObjectLine 'pmp' => array('type' => 'double'/*, 'help'=>'THMEstimatedHelp'*/, 'label' => 'PMP', 'enabled' => 1, 'position' => 50, 'notnull' => 0, 'visible' => 1,), 'rang' => array('type' => 'integer', 'label' => 'Qty', 'enabled' => 1, 'position' => 45, 'notnull' => 0, 'visible' => 0, 'default' => '0', 'isameasure' => 1, 'css' => 'maxwidth75imp', 'help' => "Help text for quantity",), ); + /** + * @var int + */ public $rowid; + /** + * @var float + */ public $amount; /** * @var float Quantity */ public $qty; + /** + * @var int + */ public $fk_warehouse_destination; + /** + * @var int + */ public $fk_warehouse_source; + /** + * @var int + */ public $fk_stocktransfer; + /** + * @var int + */ public $fk_product; + /** + * @var string + */ public $batch; /** @@ -919,6 +940,7 @@ class StockTransferLine extends CommonObjectLine if (class_exists($classname)) { $obj = new $classname(); + '@phan-var-force ModeleNumRefStockTransfer $obj'; $numref = $obj->getNextValue($this); if ($numref != '' && $numref != '-1') { @@ -943,10 +965,10 @@ class StockTransferLine extends CommonObjectLine * * @param string $modele Force template to use ('' to not force) * @param Translate $outputlangs object lang a utiliser pour traduction - * @param int $hidedetails Hide details of lines - * @param int $hidedesc Hide description - * @param int $hideref Hide ref - * @param null|array $moreparams Array to provide more information + * @param int<0,1> $hidedetails Hide details of lines + * @param int<0,1> $hidedesc Hide description + * @param int<0,1> $hideref Hide ref + * @param ?array $moreparams Array to provide more information * @return int 0 if KO, 1 if OK */ public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null) diff --git a/htdocs/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php b/htdocs/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php index af8444991ed..3434264cd49 100644 --- a/htdocs/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php +++ b/htdocs/product/stock/stocktransfer/lib/stocktransfer_stocktransfer.lib.php @@ -1,6 +1,7 @@ + * 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 @@ -26,7 +27,7 @@ * Prepare array of tabs for StockTransfer * * @param StockTransfer $object StockTransfer - * @return array Array of tabs + * @return array Array of tabs */ function stocktransferPrepareHead($object) { diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index 94f564465ee..ca0aadaa047 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -153,7 +153,7 @@ if (empty($reshook)) { include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; if ($action == 'set_thirdparty' && $permissiontoadd) { - $object->setValueFrom('fk_soc', GETPOSTINT('fk_soc'), '', '', 'date', '', $user, $triggermodname); + $object->setValueFrom('fk_soc', GETPOSTINT('fk_soc'), '', null, 'date', '', $user, $triggermodname); } if ($action == 'classin' && $permissiontoadd) { $object->setProject(GETPOSTINT('projectid')); @@ -193,7 +193,7 @@ if (empty($reshook)) { } } - if ($prod->status_batch==2 && abs($qty)>1) { + if ($prod->status_batch == 2 && abs($qty) > 1) { $error++; setEventMessages($langs->transnoentities('TooManyQtyForSerialNumber', $prod->ref), null, 'errors'); } @@ -256,7 +256,7 @@ if (empty($reshook)) { } } - if ($prod->status_batch==2 && abs($qty)>1) { + if ($prod->status_batch == 2 && abs($qty) > 1) { $error++; setEventMessages($langs->transnoentities('TooManyQtyForSerialNumber', $prod->ref), null, 'errors'); $action = 'editline'; @@ -547,10 +547,10 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if ($action == 'deleteline') { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1); } + $formquestion = array(); // Clone confirmation if ($action == 'clone') { // Create an array for form - $formquestion = array(); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); } elseif ($action == 'destock') { // Destock confirmation // Create an array for form diff --git a/htdocs/product/stock/tpl/stockcorrection.tpl.php b/htdocs/product/stock/tpl/stockcorrection.tpl.php index 59cb0fa4ad1..c5a592bd2dd 100644 --- a/htdocs/product/stock/tpl/stockcorrection.tpl.php +++ b/htdocs/product/stock/tpl/stockcorrection.tpl.php @@ -1,6 +1,7 @@ * Copyright (C) 2018-2024 Frédéric France + * 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 @@ -25,6 +26,13 @@ if (empty($conf) || !is_object($conf)) { exit(1); } +' +@phan-var-force Entrepot|MouvementStock $object +@phan-var-force FormProduct $formproduct +@phan-var-force FormProjets $formproject +@phan-var-force string $backtopage +'; + ?> @@ -150,14 +158,14 @@ if ($object->element == 'product') { if (empty($ident) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE')) { $ident = getDolGlobalString('MAIN_DEFAULT_WAREHOUSE'); } - print img_picto('', 'stock', 'class="pictofixedwidth"').$formproduct->selectWarehouses($ident, 'id_entrepot', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'minwidth100 maxwidth300 widthcentpercentminusx'); + print img_picto('', 'stock', 'class="pictofixedwidth"').$formproduct->selectWarehouses($ident, 'id_entrepot', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth100 maxwidth300 widthcentpercentminusx'); print ''; } if ($object->element == 'stockmouvement') { print ''.$langs->trans("Product").''; print ''; print img_picto('', 'product'); - $form->select_produits(GETPOSTINT('product_id'), 'product_id', (!getDolGlobalString('STOCK_SUPPORTS_SERVICES') ? '0' : ''), 0, 0, -1, 2, '', 0, null, 0, 1, 0, 'maxwidth500'); + $form->select_produits(GETPOSTINT('product_id'), 'product_id', (!getDolGlobalString('STOCK_SUPPORTS_SERVICES') ? '0' : ''), 0, 0, -1, 2, '', 0, array(), 0, 1, 0, 'maxwidth500'); print ''; } print ''.$langs->trans("NumberOfUnit").''; diff --git a/htdocs/product/stock/tpl/stocktransfer.tpl.php b/htdocs/product/stock/tpl/stocktransfer.tpl.php index c7bac77a67b..e5c9b2333aa 100644 --- a/htdocs/product/stock/tpl/stocktransfer.tpl.php +++ b/htdocs/product/stock/tpl/stocktransfer.tpl.php @@ -1,6 +1,7 @@ * Copyright (C) 2018 Frédéric France + * 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 @@ -25,9 +26,15 @@ if (empty($conf) || !is_object($conf)) { exit(1); } +' +@phan-var-force Entrepot|MouvementStock $object +@phan-var-force FormProduct $formproduct +@phan-var-force string $backtopage +'; + ?> - + element == 'product') { @@ -82,7 +89,7 @@ if ($object->element == 'stockmouvement') { print ''.$langs->trans("Product").''; print ''; print img_picto('', 'product'); - $form->select_produits(GETPOSTINT('product_id'), 'product_id', (!getDolGlobalString('STOCK_SUPPORTS_SERVICES') ? '0' : ''), 0, 0, -1, 2, '', 0, null, 0, 1, 0, 'maxwidth500'); + $form->select_produits(GETPOSTINT('product_id'), 'product_id', (!getDolGlobalString('STOCK_SUPPORTS_SERVICES') ? '0' : ''), 0, 0, -1, 2, '', 0, array(), 0, 1, 0, 'maxwidth500'); print ''; } diff --git a/htdocs/projet/activity/index.php b/htdocs/projet/activity/index.php index 7ac394fd752..a38be8a555b 100644 --- a/htdocs/projet/activity/index.php +++ b/htdocs/projet/activity/index.php @@ -4,6 +4,7 @@ * Copyright (C) 2010 Regis Houssin * Copyright (C) 2019 Nicolas ZABOURI * Copyright (C) 2023 Gauthier VERDOL + * 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 @@ -563,6 +564,8 @@ if (!getDolGlobalString('PROJECT_HIDE_TASKS') && getDolGlobalString('PROJECT_SHO } else { $percentcompletion = intval($obj->duration_effective * 100 / $obj->planned_workload).'%'; } + } else { + $percentcompletion = 0; } print $percentcompletion; print ''; diff --git a/htdocs/projet/admin/project.php b/htdocs/projet/admin/project.php index a1e2c984e58..444599eefba 100644 --- a/htdocs/projet/admin/project.php +++ b/htdocs/projet/admin/project.php @@ -561,6 +561,7 @@ foreach ($dirmodels as $reldir) { require_once $dir.'/'.$file; $module = new $classname($db); + '@phan-var-force ModelePDFProjects $module'; $modulequalified = 1; if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { @@ -575,7 +576,7 @@ foreach ($dirmodels as $reldir) { print(empty($module->name) ? $name : $module->name); print "\n"; if (method_exists($module, 'info')) { - print $module->info($langs); + print $module->info($langs); // @phan-suppress-current-line PhanUndeclaredMethod } else { print $module->description; } @@ -706,6 +707,7 @@ if (!getDolGlobalString('PROJECT_HIDE_TASKS')) { require_once $dir.'/'.$file; $module = new $classname($db); + '@phan-var-force ModelePDFTask $module'; $modulequalified = 1; if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { @@ -720,7 +722,7 @@ if (!getDolGlobalString('PROJECT_HIDE_TASKS')) { print(empty($module->name) ? $name : $module->name); print "\n"; if (method_exists($module, 'info')) { - print $module->info($langs); + print $module->info($langs); // @phan-suppress-current-line PhanUndeclaredMethod } else { print $module->description; } diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 55a9785db38..02b6f669971 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -307,7 +307,7 @@ if (empty($reshook)) { } $db->begin(); - + $old_start_date = null; if (!$error) { $object->oldcopy = clone $object; @@ -622,6 +622,7 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { // Search template files $file = ''; $classname = ''; + $reldir = ''; $filefound = 0; $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); foreach ($dirmodels as $reldir) { @@ -637,7 +638,7 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { $result = dol_include_once($reldir."core/modules/project/".$modele.'.php'); if (class_exists($classname)) { $modProject = new $classname(); - + '@phan-var-force ModeleNumRefProjects $modProject'; $defaultref = $modProject->getNextValue($thirdparty, $object); } } @@ -891,7 +892,7 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { print ''.$langs->trans("Categories").''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_PROJECT, '', 'parent', 64, 0, 3); $arrayselected = GETPOST('categories', 'array'); - print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0); + print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('categories', $cate_arbo, $arrayselected, 0, 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0); print ""; } @@ -981,7 +982,7 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { if ($action == 'delete') { $text = $langs->trans("ConfirmDeleteAProject"); $task = new Task($db); - $taskarray = $task->getTasksArray(0, 0, $object->id, 0, 0); + $taskarray = $task->getTasksArray(null, null, $object->id, 0, 0); $nboftask = count($taskarray); if ($nboftask) { $text .= '
'.img_warning().' '.$langs->trans("ThisWillAlsoRemoveTasks", $nboftask); @@ -993,7 +994,7 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { if ($action == 'clone') { $formquestion = array( 'text' => $langs->trans("ConfirmClone"), - 0 => array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOSTINT('socid') > 0 ? GETPOSTINT('socid') : $object->socid, 'socid', '', "None", 0, 0, null, 0, 'minwidth200 maxwidth250')), + 0 => array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOSTINT('socid') > 0 ? GETPOSTINT('socid') : $object->socid, 'socid', '', "None", 0, 0, array(), 0, 'minwidth200 maxwidth250')), 1 => array('type' => 'checkbox', 'name' => 'clone_contacts', 'label' => $langs->trans("CloneContacts"), 'value' => true), 2 => array('type' => 'checkbox', 'name' => 'clone_tasks', 'label' => $langs->trans("CloneTasks"), 'value' => true), 3 => array('type' => 'checkbox', 'name' => 'move_date', 'label' => $langs->trans("CloneMoveDate"), 'value' => true), diff --git a/htdocs/projet/class/api_projects.class.php b/htdocs/projet/class/api_projects.class.php index 81f4bea7496..979745c3805 100644 --- a/htdocs/projet/class/api_projects.class.php +++ b/htdocs/projet/class/api_projects.class.php @@ -31,7 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; class Projects extends DolibarrApi { /** - * @var array $FIELDS Mandatory fields, checked when create and update object + * @var string[] $FIELDS Mandatory fields, checked when create and update object */ public static $FIELDS = array( 'ref', @@ -197,6 +197,8 @@ class Projects extends DolibarrApi * @param string $properties Restrict the data returned to these properties. Ignored if empty. Comma separated list of properties names * @param bool $pagination_data If this parameter is set to true the response will include pagination data. Default value is false. Page starts from 0* * @return array Array of project objects + * @phan-return array{data:Project[],pagination:array{total:int,page:int,page_count:int,limit:int}} + * @phpstan-return array{data:Project[],pagination:array{total:int,page:int,page_count:int,limit:int}} */ public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $category = 0, $sqlfilters = '', $properties = '', $pagination_data = false) { @@ -302,6 +304,8 @@ class Projects extends DolibarrApi * Create project object * * @param array $request_data Request data + * @phan-param array $request_data + * @phpstan-param array $request_data * @return int ID of project */ public function post($request_data = null) @@ -352,6 +356,7 @@ class Projects extends DolibarrApi $result = dol_include_once($reldir . "core/modules/project/" . $modele . '.php'); if ($result !== false && class_exists($classname)) { $modProject = new $classname(); + '@phan-var-force ModeleNumRefProjects $modProject'; $defaultref = $modProject->getNextValue(null, $this->project); } else { dol_syslog("Failed to include module file or invalid classname: " . $reldir . "core/modules/project/" . $modele . '.php', LOG_ERR); @@ -385,6 +390,8 @@ class Projects extends DolibarrApi * @param int $id Id of project * @param int $includetimespent 0=Return only list of tasks. 1=Include a summary of time spent, 2=Include details of time spent lines * @return array + * @phan-return Object[] + * @phpstan-return Object[] * * @url GET {id}/tasks */ @@ -423,6 +430,8 @@ class Projects extends DolibarrApi * @param int $id Id of project * @param int $userid Id of user (0 = connected user) * @return array + * @phan-return Object[] + * @phpstan-return Object[] * * @url GET {id}/roles */ @@ -465,6 +474,8 @@ class Projects extends DolibarrApi * * @param int $id Id of project to update * @param array $request_data Projectline data + * @phan-param array $request_data + * @phpstan-param array $request_data * * @url POST {id}/tasks * @@ -532,6 +543,8 @@ class Projects extends DolibarrApi * @param int $id Id of project to update * @param int $taskid Id of task to update * @param array $request_data Projectline data + * @phan-param array $request_data + * @phpstan-param array $request_data * * @url PUT {id}/tasks/{taskid} * @@ -596,7 +609,11 @@ class Projects extends DolibarrApi * * @param int $id Id of project to update * @param array $request_data Datas + * @phan-param ?array $request_data + * @phpstan-param ?array $request_data * @return Object Updated object + * @phan-return Object|false + * @phpstan-return Object|false */ public function put($id, $request_data = null) { @@ -644,6 +661,8 @@ class Projects extends DolibarrApi * @param int $id Project ID * * @return array + * @phan-return array{success:array{code:int,message:string}} + * @phpstan-return array{success:array{code:int,message:string}} */ public function delete($id) { @@ -678,10 +697,14 @@ class Projects extends DolibarrApi * * @param int $id Project ID * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @phan-param int<0,1> $notrigger + * @phpstan-param int<0,1> $notrigger * * @url POST {id}/validate * * @return array + * @phan-return array{success:array{code:int,message:string}} + * @phpstan-return array{success:array{code:int,message:string}} * FIXME An error 403 is returned if the request has an empty body. * Error message: "Forbidden: Content type `text/plain` is not supported." * Workaround: send this in the body @@ -775,8 +798,8 @@ class Projects extends DolibarrApi /** * Validate fields before create or update object * - * @param array $data Array with data to verify - * @return array + * @param array $data Array with data to verify + * @return array * @throws RestException */ private function _validate($data) diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 4e76f06bc26..99e27f816ce 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -1930,7 +1930,7 @@ class Project extends CommonObject $tasksarray = $taskstatic->getTasksArray(null, null, $fromid, $socid, 0); $tab_conv_child_parent = array(); - $result_clonse = 0; + $result_clone = 0; // Loop on each task, to clone it foreach ($tasksarray as $tasktoclone) { diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 5a25eee1a7f..738ce921f7e 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -190,6 +190,13 @@ $hookmanager->initHooks(array('projectOverview')); //if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignment. $result = restrictedArea($user, 'projet', $object->id, 'projet&project'); +$total_duration = 0; +$total_ttc_by_line = 0; +$total_ht_by_line = 0; +$expensereport = null; +$othermessage = ''; +$tmpprojtime = array(); +$nbAttendees = 0; /* * Actions @@ -1707,14 +1714,16 @@ function canApplySubtotalOn($tablename) /** * sortElementsByClientName * - * @param array $elementarray Element array - * @return array Element array sorted + * @param int[] $elementarray Element array + * @return int[] Element array sorted */ function sortElementsByClientName($elementarray) { global $db, $classname; + '@phan-var-force string $classname'; $element = new $classname($db); + '@phan-var-force CommonObject $element'; $clientname = array(); foreach ($elementarray as $key => $id) { // id = id of object diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index a917a292a76..f86e08adf6c 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -2184,12 +2184,12 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if (!empty($arrayfields['p.fk_soc']['checked'])) { print ''; if ($task_time->fk_soc > 0) { - if (empty($conf->cache['thridparty'][$task_time->fk_soc])) { + if (empty($conf->cache['thirdparty'][$task_time->fk_soc])) { $tmpsociete = new Societe($db); $tmpsociete->fetch($task_time->fk_soc); - $conf->cache['thridparty'][$task_time->fk_soc] = $tmpsociete; + $conf->cache['thirdparty'][$task_time->fk_soc] = $tmpsociete; } else { - $tmpsociete = $conf->cache['thridparty'][$task_time->fk_soc]; + $tmpsociete = $conf->cache['thirdparty'][$task_time->fk_soc]; } print $tmpsociete->getNomUrl(1, '', 100, 0, 1, empty($arrayfields['s.name_alias']['checked']) ? 0 : 1); } @@ -2202,12 +2202,12 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // Thirdparty alias if (!empty($arrayfields['s.name_alias']['checked'])) { if ($task_time->fk_soc > 0) { - if (empty($conf->cache['thridparty'][$task_time->fk_soc])) { + if (empty($conf->cache['thirdparty'][$task_time->fk_soc])) { $tmpsociete = new Societe($db); $tmpsociete->fetch($task_time->fk_soc); - $conf->cache['thridparty'][$task_time->fk_soc] = $tmpsociete; + $conf->cache['thirdparty'][$task_time->fk_soc] = $tmpsociete; } else { - $tmpsociete = $conf->cache['thridparty'][$task_time->fk_soc]; + $tmpsociete = $conf->cache['thirdparty'][$task_time->fk_soc]; } $valtoshow = $tmpsociete->name_alias; } diff --git a/htdocs/public/cron/cron_run_jobs_by_url.php b/htdocs/public/cron/cron_run_jobs_by_url.php index 86c0cc76299..2ded3bfb832 100644 --- a/htdocs/public/cron/cron_run_jobs_by_url.php +++ b/htdocs/public/cron/cron_run_jobs_by_url.php @@ -3,6 +3,7 @@ * Copyright (C) 2013 Florian Henry * Copyright (C) 2013-2015 Laurent Destailleur * Copyright (C) 2017 Regis Houssin + * 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 @@ -106,7 +107,7 @@ if (empty($userlogin)) { } require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; $user = new User($db); -$result = $user->fetch('', $userlogin); +$result = $user->fetch(0, $userlogin); if ($result < 0) { echo "User Error:".$user->error; dol_syslog("cron_run_jobs.php:: User Error:".$user->error, LOG_ERR); @@ -168,7 +169,7 @@ if (is_array($object->lines) && (count($object->lines) > 0)) { // Force recheck that user is ok for the entity to process and reload permission for entity if ($conf->entity != $user->entity && $user->entity != 0) { - $result = $user->fetch('', $userlogin, '', 0, $conf->entity); + $result = $user->fetch(0, $userlogin, '', 0, $conf->entity); if ($result < 0) { echo "\nUser Error: ".$user->error."\n"; dol_syslog("cron_run_jobs.php:: User Error:".$user->error, LOG_ERR); diff --git a/htdocs/public/project/new.php b/htdocs/public/project/new.php index 4d1c514d3c7..70344778e43 100644 --- a/htdocs/public/project/new.php +++ b/htdocs/public/project/new.php @@ -263,6 +263,7 @@ if (empty($reshook) && $action == 'add') { // Test on permission not required he // Search template files $file = ''; $classname = ''; + $reldir = ''; $filefound = 0; $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); foreach ($dirmodels as $reldir) { @@ -278,6 +279,7 @@ if (empty($reshook) && $action == 'add') { // Test on permission not required he $result = dol_include_once($reldir."core/modules/project/".$modele.'.php'); if (class_exists($classname)) { $modProject = new $classname(); + '@phan-var-force ModeleNumRefProjects $modProject'; $defaultref = $modProject->getNextValue($thirdparty, $object); } diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 7d7b9f47dd7..5ef48d7d397 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -5563,7 +5563,7 @@ class Societe extends CommonObject 'Account' => '/compta/bank/class/account.class.php', 'ConferenceOrBoothAttendee' => '/eventorganization/class/conferenceorboothattendee.class.php', 'Societe' => '/societe/class/societe.class.php', - //'SocieteAccount', 'SocietePrice', 'SocieteRib',... are processed into the replaceThirparty of Societe. + //'SocieteAccount', 'SocietePrice', 'SocieteRib',... are processed into the replaceThirdparty of Societe. ); if ($this->db->DDLListTables($conf->db->name, $this->db->prefix().'delivery')) { $objects['Delivery'] = '/delivery/class/delivery.class.php'; diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 4dbc3a640b4..c31b481b3c8 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -65,7 +65,10 @@ parameters: - '#(?:empty\(\) is always) fals#' - '#(\$force_dolibarr_lib|\$dolibarr_main_db).*in empty\(\) is never defined.#' - '#Sprain\\SwissQrBill\\#' - - '#Constructor of class (?:Dol(?:Editor|iDB(?:Mysqli|Pgsql|Sqlite3))|(?:ModeleBox|box_accountancy_last_manual_entri)es|box_(?:ac(?:countancy_suspense_account|ti(?:ons(?:_future)?|vity))|b(?:irthdays(?:_members)?|o(?:(?:okmark|m)s))|c(?:(?:lient|o(?:m(?:(?:mand|pt)e)|nt(?:r?act)))s|ustomers_outstanding_bill_reached)|dolibarr_state_board|f(?:actures(?:_(?:fourn(?:_imp)?|imp))?|icheinter|ournisseurs|unnel_of_prospection)|g(?:oodcustomers|raph_(?:invoices_(?:per(?:month|year)|supplier_permonth)|n(?:b_ticket(?:_last_x_days|s_type)|ew_vs_close_ticket)|orders_(?:(?:supplier_)?permonth)|pro(?:duct_distribution|pales_permonth)|ticket_by_severity))|last(?:_(?:(?:modified_)?knowledgerecord|(?:modified_)?ticket)|login)|m(?:embers_(?:by_t(?:ags|ype)|last_(?:modified|subscriptions)|subscriptions_by_year)|os)|pro(?:duits(?:_alerte_stock)?|ject(?:_opportunities)?|pales|spect)|s(?:(?:cheduled_job|ervices_contract)s|ervices_expired|(?:hipment|upplier_order)s|upplier_orders_awaiting_reception)|task|validated_projects)).* has an unused parameter #' + - '#(?:Constructor of class (?:(?:ModeleBox|box_accountancy_last_manual_entri)es|box_(?:ac(?:countancy_suspense_account|ti(?:ons(?:_future)?|vity))|b(?:irthdays(?:_members)?|o(?:(?:okmark|m)s))|c(?:(?:lient|o(?:m(?:(?:mand|pt)e)|nt(?:r?act)))s|ustomers_outstanding_bill_reached)|dolibarr_state_board|f(?:actures(?:_(?:fourn(?:_imp)?|imp))?|icheinter|ournisseurs|unnel_of_prospection)|g(?:oodcustomers|raph_(?:invoices_(?:per(?:month|year)|supplier_permonth)|n(?:b_ticket(?:_last_x_days|s_type)|ew_vs_close_ticket)|orders_(?:(?:supplier_)?permonth)|pro(?:duct_distribution|pales_permonth)|ticket_by_severity))|last(?:_(?:(?:modified_)?knowledgerecord|(?:modified_)?ticket)|login)|m(?:embers_(?:by_t(?:ags|ype)|last_(?:modified|subscriptions)|subscriptions_by_year)|os)|pro(?:duits(?:_alerte_stock)?|ject(?:_opportunities)?|pales|spect)|s(?:(?:cheduled_job|ervices_contract)s|ervices_expired|(?:hipment|upplier_order)s|upplier_orders_awaiting_reception)|task|validated_projects))) has an unused parameter \$param\.#' + - '#(?:Constructor of class DoliDB(?:Mysqli|Pgsql|Sqlite3)) has an unused parameter \$type\.#' + - '#(?:Constructor of class DolEditor) has an unused parameter \$toolbarlocation\.#' + - '#Dead catch - Exception is never thrown in the try block#' - '#.*phan-var#' - '#(?:(?:s(?:(?:et_error_handl|pl_autoload_regist)er)|array_filter)) expects \(callable#'