diff --git a/dev/tools/phan/baseline.txt b/dev/tools/phan/baseline.txt index 611fce90ddb..e4d6b885ce3 100644 --- a/dev/tools/phan/baseline.txt +++ b/dev/tools/phan/baseline.txt @@ -9,15 +9,15 @@ */ return [ // # Issue statistics: - // PhanTypeMismatchArgument : 2090+ occurrences - // PhanUndeclaredProperty : 530+ occurrences + // PhanTypeMismatchArgument : 2050+ occurrences + // PhanUndeclaredProperty : 520+ occurrences // PhanTypeMismatchArgumentNullable : 410+ occurrences - // PhanUndeclaredGlobalVariable : 190+ occurrences + // PhanUndeclaredGlobalVariable : 180+ occurrences // PhanPluginUnknownArrayMethodReturnType : 170+ occurrences - // PhanPossiblyUndeclaredGlobalVariable : 140+ occurrences // PhanTypeMismatchProperty : 130+ occurrences - // PhanTypeMismatchArgumentProbablyReal : 120+ occurrences + // PhanPossiblyUndeclaredGlobalVariable : 120+ occurrences // PhanPluginUnknownArrayMethodParamType : 110+ occurrences + // PhanTypeMismatchArgumentProbablyReal : 110+ occurrences // PhanRedefineFunction : 40+ occurrences // PhanTypeExpectedObjectPropAccess : 40+ occurrences // PhanTypeInvalidDimOffset : 25+ occurrences @@ -28,16 +28,16 @@ return [ // PhanUndeclaredMethod : 10+ occurrences // PhanTypeComparisonFromArray : 9 occurrences // PhanPluginSuspiciousParamPosition : 7 occurrences - // PhanPluginUnknownObjectMethodCall : 7 occurrences // PhanPluginDuplicateExpressionBinaryOp : 6 occurrences + // PhanPluginUnknownObjectMethodCall : 6 occurrences // PhanTypeArraySuspiciousNull : 6 occurrences // PhanParamTooMany : 5 occurrences // PhanEmptyForeach : 4 occurrences - // PhanPluginBothLiteralsBinaryOp : 4 occurrences // PhanPluginDuplicateArrayKey : 4 occurrences // PhanPluginEmptyStatementIf : 4 occurrences // PhanEmptyFQSENInClasslike : 3 occurrences // PhanInvalidFQSENInClasslike : 3 occurrences + // PhanPluginBothLiteralsBinaryOp : 3 occurrences // PhanTypeMismatchDimAssignment : 2 occurrences // PhanTypeMismatchDimFetchNullable : 2 occurrences // PhanTypeSuspiciousStringExpression : 2 occurrences @@ -349,7 +349,7 @@ return [ 'htdocs/core/class/hookmanager.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/html.form.class.php' => ['PhanTypeMismatchArgumentNullable'], 'htdocs/core/class/html.formcompany.class.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], - 'htdocs/core/class/html.formfile.class.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], + 'htdocs/core/class/html.formfile.class.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/class/html.formmail.class.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], 'htdocs/core/class/html.formother.class.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/class/html.formprojet.class.php' => ['PhanTypeMismatchArgument'], @@ -598,16 +598,12 @@ return [ 'htdocs/product/inventory/class/inventory.class.php' => ['PhanUndeclaredProperty'], 'htdocs/product/price.php' => ['PhanUndeclaredProperty'], 'htdocs/product/reassort.php' => ['PhanTypeExpectedObjectPropAccessButGotNull'], - 'htdocs/product/stock/card.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchProperty'], 'htdocs/product/stock/class/api_stockmovements.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanTypeMismatchArgument'], 'htdocs/product/stock/class/api_warehouses.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType'], - 'htdocs/product/stock/class/entrepot.class.php' => ['PhanUndeclaredProperty'], - 'htdocs/product/stock/class/mouvementstock.class.php' => ['PhanTypeMismatchArgument'], - 'htdocs/product/stock/info.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanTypeMismatchArgument', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], - 'htdocs/product/stock/list.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], - 'htdocs/product/stock/massstockmove.php' => ['PhanTypeMismatchArgument'], - 'htdocs/product/stock/movement_card.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], - 'htdocs/product/stock/movement_list.php' => ['PhanPluginBothLiteralsBinaryOp', 'PhanPluginUndeclaredVariableIsset', 'PhanTypeMismatchArgument', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], + 'htdocs/product/stock/info.php' => ['PhanUndeclaredProperty'], + 'htdocs/product/stock/list.php' => ['PhanUndeclaredProperty'], + 'htdocs/product/stock/movement_card.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], + 'htdocs/product/stock/movement_list.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/product/stock/product.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], 'htdocs/product/stock/productlot_card.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], 'htdocs/product/stock/productlot_list.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentProbablyReal'], diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 514d9bf10b5..ddc59c1ee53 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2564,7 +2564,7 @@ class Form * * @param string $action Value for $action * @param string $htmlname Field name in form - * @param int $show_empty 0=list without the empty value, 1=add empty value + * @param int<0,1> $show_empty 0=list without the empty value, 1=add empty value * @param int[] $exclude Array list of users id to exclude * @param int<0,1> $disabled If select list must be disabled * @param int[]|string $include Array list of users id to include or 'hierarchy' to have only supervised users @@ -2573,7 +2573,7 @@ class Form * @param int $maxlength Maximum length of string into list (0=no limit) * @param int<-1,1> $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status * @param string $morefilter Add more filters into sql request - * @param int $showproperties Show properties of each attendees + * @param int<0,1> $showproperties Show properties of each attendees * @param array}> $listofresourceid Array with properties of each resource * @return string HTML select string */ @@ -2662,14 +2662,14 @@ class Form * @param int|string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) * @param int $limit Limit on number of returned lines * @param int $price_level Level of price to show - * @param int $status Sell status: -1=No filter on sell status, 0=Products not on sell, 1=Products on sell - * @param int $finished 2=all, 1=finished, 0=raw material + * @param int<-1,1> $status Sell status: -1=No filter on sell status, 0=Products not on sell, 1=Products on sell + * @param int<0,2> $finished 2=all, 1=finished, 0=raw material * @param string $selected_input_value Value of preselected input text (for use with ajax) - * @param int $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after) + * @param int<0,3> $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after) * @param array $ajaxoptions Options for ajax_autocompleter * @param int $socid Thirdparty Id (to get also price dedicated to this customer) - * @param string|int<0,1> $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. - * @param int $forcecombo Force to use combo box. + * @param string|int<0,1> $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. + * @param int<0,1> $forcecombo Force to use combo box. * @param string $morecss Add more css on select * @param int<0,1> $hidepriceinlabel 1=Hide prices in label * @param string $warehouseStatus Warehouse status filter to count the quantity in stock. Following comma separated filter options can be used diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 85cedff7d47..1558bfea3dc 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -396,8 +396,8 @@ class FormFile * @param string $modulesubdir Sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into subdir of module. * @param string $filedir Directory to scan * @param string $urlsource Url of origin page (for return) - * @param int $genallowed Generation is allowed (1/0 or array of formats) - * @param int $delallowed Remove is allowed (1/0) + * @param int<0,1> $genallowed Generation is allowed (1/0 or array of formats) + * @param int<0,1> $delallowed Remove is allowed (1/0) * @param string $modelselected Model to preselect by default * @param integer $allowgenifempty Show warning if no model activated * @param integer $forcenomultilang Do not show language option (even if MAIN_MULTILANGS defined) @@ -427,24 +427,24 @@ class FormFile * @param string $modulesubdir Existing (so sanitized) sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into a subdir of module. * @param string $filedir Directory to scan (must not end with a /). Example: '/mydolibarrdocuments/facture/FAYYMM-1234' * @param string $urlsource Url of origin page (for return) - * @param int|string[] $genallowed Generation is allowed (1/0 or array list of templates) - * @param int $delallowed Remove is allowed (1/0) + * @param int<0,1>|string[] $genallowed Generation is allowed (1/0 or array list of templates) + * @param int<0,1> $delallowed Remove is allowed (1/0) * @param string $modelselected Model to preselect by default - * @param integer $allowgenifempty Allow generation even if list of template ($genallowed) is empty (show however a warning) - * @param integer $forcenomultilang Do not show language option (even if MAIN_MULTILANGS defined) + * @param int<0,1> $allowgenifempty Allow generation even if list of template ($genallowed) is empty (show however a warning) + * @param int<0,1> $forcenomultilang Do not show language option (even if MAIN_MULTILANGS defined) * @param int $iconPDF Deprecated, see getDocumentsLink * @param int $notused Not used - * @param integer $noform Do not output html form tags + * @param int<0,1> $noform Do not output html form tags * @param string $param More param on http links * @param string $title Title to show on top of form. Example: '' (Default to "Documents") or 'none' * @param string $buttonlabel Label on submit button * @param string $codelang Default language code to use on lang combo box if multilang is enabled * @param string $morepicto Add more HTML content into cell with picto * @param Object|null $object Object when method is called from an object card. - * @param int $hideifempty Hide section of generated files if there is no file + * @param int<0,1> $hideifempty Hide section of generated files if there is no file * @param string $removeaction (optional) The action to remove a file * @param string $tooltipontemplatecombo Text to show on a tooltip after the combo list of templates - * @return string|int Output string with HTML array of documents (might be empty string) + * @return string|int<-1,-1> Output string with HTML array of documents (might be empty string) */ public function showdocuments($modulepart, $modulesubdir, $filedir, $urlsource, $genallowed, $delallowed = 0, $modelselected = '', $allowgenifempty = 1, $forcenomultilang = 0, $iconPDF = 0, $notused = 0, $noform = 0, $param = '', $title = '', $buttonlabel = '', $codelang = '', $morepicto = '', $object = null, $hideifempty = 0, $removeaction = 'remove_file', $tooltipontemplatecombo = '') { @@ -947,6 +947,8 @@ class FormFile } } + '@phan-var-force array $file_list'; + require_once DOL_DOCUMENT_ROOT . '/ecm/class/ecmfiles.class.php'; $i = 0; @@ -1145,13 +1147,13 @@ class FormFile * You may want to call this into a div like this: * print '
'.$formfile->getDocumentsLink($element_doc, $filename, $filedir).'
'; * - * @param string $modulepart 'propal', 'facture', 'facture_fourn', ... - * @param string $modulesubdir Sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into subdir of module. - * @param string $filedir Full path to directory to scan - * @param string $filter Filter filenames on this regex string (Example: '\.pdf$') - * @param string $morecss Add more css to the download picto - * @param int $allfiles 0=Only generated docs, 1=All files - * @return string Output string with HTML link of documents (might be empty string). This also fill the array ->infofiles + * @param string $modulepart 'propal', 'facture', 'facture_fourn', ... + * @param string $modulesubdir Sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into subdir of module. + * @param string $filedir Full path to directory to scan + * @param string $filter Filter filenames on this regex string (Example: '\.pdf$') + * @param string $morecss Add more css to the download picto + * @param int<0,1> $allfiles 0=Only generated docs, 1=All files + * @return string Output string with HTML link of documents (might be empty string). This also fill the array ->infofiles */ public function getDocumentsLink($modulepart, $modulesubdir, $filedir, $filter = '', $morecss = 'valignmiddle', $allfiles = 0) { @@ -1373,6 +1375,7 @@ class FormFile if ($permtoeditline < 0) { // Old behaviour for backward compatibility. New feature should call method with value 0 or 1 $permtoeditline = 0; if (in_array($modulepart, array('product', 'produit', 'service'))) { + '@phan-var-force Product $object'; if ($user->hasRight('produit', 'creer') && $object->type == Product::TYPE_PRODUCT) { $permtoeditline = 1; } @@ -2352,9 +2355,9 @@ class FormFile * Show detail icon with link for preview * * @param array{name:string,path:string,level1name:string,relativename:string,fullname:string,date:string,size:int,perm:int,type:string} $file Array with data of file. Example: array('name'=>...) - * @param string $modulepart propal, facture, facture_fourn, ... - * @param string $relativepath Relative path of docs - * @param integer $ruleforpicto Rule for picto: 0=Use the generic preview picto, 1=Use the picto of mime type of file). Use a negative value to show a generic picto even if preview not available. + * @param string $modulepart propal, facture, facture_fourn, ... + * @param string $relativepath Relative path of docs + * @param int $ruleforpicto Rule for picto: 0=Use the generic preview picto, 1=Use the picto of mime type of file). Use a negative value to show a generic picto even if preview not available. * @param string $param More param on http links * @return string $out Output string with HTML */ diff --git a/htdocs/product/stock/card.php b/htdocs/product/stock/card.php index 1914448023d..41bcc14c066 100644 --- a/htdocs/product/stock/card.php +++ b/htdocs/product/stock/card.php @@ -8,7 +8,7 @@ * Copyright (C) 2021-2024 Frédéric France * Copyright (C) 2022-2023 Charlene Benke * Copyright (C) 2023 Christian Foellmann - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -212,14 +212,14 @@ if (empty($reshook)) { if ($object->fetch($id)) { $object->label = GETPOST("libelle"); $object->fk_parent = GETPOST("fk_parent"); - $object->fk_project = GETPOST('projectid'); + $object->fk_project = GETPOSTINT('projectid'); $object->description = GETPOST("desc", 'restricthtml'); $object->statut = GETPOST("statut"); $object->lieu = GETPOST("lieu"); $object->address = GETPOST("address"); $object->zip = GETPOST("zipcode"); $object->town = GETPOST("town"); - $object->country_id = GETPOST("country_id"); + $object->country_id = GETPOSTINT("country_id"); $object->phone = GETPOST("phone"); $object->fax = GETPOST("fax"); @@ -292,6 +292,7 @@ $form = new Form($db); $formproduct = new FormProduct($db); $formcompany = new FormCompany($db); $formfile = new FormFile($db); +$formproject = null; if (isModEnabled('project')) { $formproject = new FormProjets($db); } @@ -330,10 +331,10 @@ if ($action == 'create') { print ''; // Project - if (isModEnabled('project')) { + if (isModEnabled('project') && $formproject !== null) { $langs->load('projects'); print ''.$langs->trans('Project').''; - print img_picto('', 'project').$formproject->select_projects(($socid > 0 ? $socid : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500'); + print img_picto('', 'project').$formproject->select_projects(($socid > 0 ? $socid : -1), (string) $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500'); print ' '; print ''; } @@ -402,7 +403,7 @@ if ($action == 'create') { // Categories print ''.$langs->trans("Categories").''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_WAREHOUSE, '', 'parent', 64, 0, 3); - print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('categories', $cate_arbo, GETPOST('categories', 'array'), '', 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0); + print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('categories', $cate_arbo, GETPOST('categories', 'array'), 0, 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0); print ""; } print ''; @@ -457,7 +458,7 @@ if ($action == 'create') { $morehtmlref .= $langs->trans("LocationSummary").' : '.$object->lieu; // Project - if (isModEnabled('project')) { + if (isModEnabled('project') && $formproject !== null) { $langs->load("projects"); $morehtmlref .= '
'.img_picto('', 'project').' '.$langs->trans('Project').' '; if ($usercancreate) { @@ -469,11 +470,11 @@ if ($action == 'create') { $morehtmlref .= '
'; $morehtmlref .= ''; $morehtmlref .= ''; - $morehtmlref .= $formproject->select_projects(($socid > 0 ? $socid : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500'); + $morehtmlref .= $formproject->select_projects(($socid > 0 ? $socid : -1), (string) $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500'); $morehtmlref .= ''; $morehtmlref .= '
'; } else { - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, ($socid > 0 ? $socid : -1), $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, ($socid > 0 ? $socid : -1), (string) $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); } } else { if (!empty($object->fk_project)) { @@ -555,6 +556,7 @@ if ($action == 'create') { $sql = "SELECT max(m.datem) as datem"; $sql .= " FROM ".MAIN_DB_PREFIX."stock_mouvement as m"; $sql .= " WHERE m.fk_entrepot = ".((int) $object->id); + $lastmovementdate = 0; $resqlbis = $db->query($sql); if ($resqlbis) { $obj = $db->fetch_object($resqlbis); @@ -818,6 +820,7 @@ if ($action == 'create') { print ''.price(price2num($objp->ppmp * $objp->value, 'MT')).''; $totalvalue += price2num($objp->ppmp * $objp->value, 'MT'); + $pricemin = 0; // Price sell min if (!getDolGlobalString('PRODUIT_MULTIPRICES')) { $pricemin = $objp->price; @@ -914,11 +917,11 @@ if ($action == 'create') { print ''; // Project - if (isModEnabled('project')) { + if (isModEnabled('project') && $formproject !== null) { $projectid = $object->fk_project; $langs->load('projects'); print ''.$langs->trans('Project').''; - print img_picto('', 'project').$formproject->select_projects(($socid > 0 ? $socid : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500'); + print img_picto('', 'project').$formproject->select_projects(($socid > 0 ? $socid : -1), (string) $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500'); print ' 0 ? '&socid='.$socid : "")).'">'; print ''; } @@ -993,7 +996,7 @@ if ($action == 'create') { foreach ($cats as $cat) { $arrayselected[] = $cat->id; } - 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 ""; } @@ -1028,7 +1031,7 @@ if ($action != 'create' && $action != 'edit' && $action != 'delete') { $delallowed = $usercancreate; $modulepart = 'stock'; - print $formfile->showdocuments($modulepart, $objectref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 0, 0, 0, 28, 0, '', 0, '', '', '', $object); + print $formfile->showdocuments($modulepart, $objectref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 0, 0, 0, 28, 0, '', '', '', '', '', $object); $somethingshown = $formfile->numoffiles; print '
'; diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index ebe21bdc622..88cdb7a8585 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -1059,7 +1059,8 @@ class Entrepot extends CommonObject if (property_exists($this, 'lieu') && (!empty($this->lieu))) { $return .= '
'.$this->lieu.''; } - if (property_exists($this, 'sellvalue') && $this->sellvalue != 0) { + if (property_exists($this, 'sellvalue') && $this->sellvalue != 0) { // @phan-suppress-current-line PhanUndeclaredProperty + // @phan-suppress-next-line PhanUndeclaredProperty $return .= '
'.price($this->sellvalue).''; } if (method_exists($this, 'getLibStatut')) { diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 1c96b0284e3..7659c066370 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -209,17 +209,17 @@ class MouvementStock extends CommonObject * @param string $label Label of stock movement * @param string $inventorycode Inventory code * @param int|string $datem Force date of movement - * @param int|string $eatby eat-by date. Will be used if lot does not exists yet and will be created. - * @param int|string $sellby sell-by date. Will be used if lot does not exists yet and will be created. + * @param int|'' $eatby eat-by date. Will be used if lot does not exists yet and will be created. + * @param int|'' $sellby sell-by date. Will be used if lot does not exists yet and will be created. * @param string $batch batch number - * @param boolean $skip_batch If set to true, stock movement is done without impacting batch record + * @param bool $skip_batch If set to true, stock movement is done without impacting batch record * @param int $id_product_batch Id product_batch (when skip_batch is false and we already know which record of product_batch to use) * @param int<0,1> $disablestockchangeforsubproduct Disable stock change for sub-products of kit (useful only if product is a subproduct) * @param int<0,1> $donotcleanemptylines Do not clean lines in stock table with qty=0 (because we want to have this done by the caller) * @param bool $force_update_batch Allows to add batch stock movement even if $product doesn't use batch anymore * @return int Return integer <0 if KO, 0 if fk_product is null or product id does not exists, >0 if OK */ - public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = 0, $label = '', $inventorycode = '', $datem = '', $eatby = '', $sellby = '', $batch = '', $skip_batch = false, $id_product_batch = 0, $disablestockchangeforsubproduct = 0, $donotcleanemptylines = 0, $force_update_batch = false) + public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = 0, $label = '', $inventorycode = '', $datem = '', $eatby = 0, $sellby = 0, $batch = '', $skip_batch = false, $id_product_batch = 0, $disablestockchangeforsubproduct = 0, $donotcleanemptylines = 0, $force_update_batch = false) { // phpcs:enable global $conf, $langs; @@ -363,7 +363,7 @@ class MouvementStock extends CommonObject $obj = $this->db->fetch_object($resql); if ($obj->eatby) { if ($eatby) { - $tmparray = dol_getdate($eatby, true); + $tmparray = dol_getdate((int) $eatby, true); $eatbywithouthour = dol_mktime(0, 0, 0, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); if ($this->db->jdate($obj->eatby) != $eatby && $this->db->jdate($obj->eatby) != $eatbywithouthour) { // We test date without hours and with hours for backward compatibility // If found and eatby/sellby defined into table and provided and differs, return error @@ -392,7 +392,7 @@ class MouvementStock extends CommonObject } if ($obj->sellby) { if ($sellby) { - $tmparray = dol_getdate($sellby, true); + $tmparray = dol_getdate((int) $sellby, true); $sellbywithouthour = dol_mktime(0, 0, 0, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); if ($this->db->jdate($obj->sellby) != $sellby && $this->db->jdate($obj->sellby) != $sellbywithouthour) { // We test date without hours and with hours for backward compatibility // If found and eatby/sellby defined into table and provided and differs, return error diff --git a/htdocs/product/stock/info.php b/htdocs/product/stock/info.php index d400873d96b..8487bd92637 100644 --- a/htdocs/product/stock/info.php +++ b/htdocs/product/stock/info.php @@ -1,6 +1,7 @@ * Copyright (C) 2024 Frédéric France + * Copyright (C) 2025 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -87,15 +88,16 @@ if (isModEnabled('project')) { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; } if ($action == 'classify') { + $formproject = new FormProjets($db); $projectid = $object->fk_project; $morehtmlref .= '
'; $morehtmlref .= ''; $morehtmlref .= ''; - $morehtmlref .= $formproject->select_projects(($socid > 0 ? $socid : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500'); + $morehtmlref .= $formproject->select_projects(($socid > 0 ? $socid : -1), (string) $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500'); $morehtmlref .= ''; $morehtmlref .= '
'; } else { - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, (!empty($object->socid) ? $object->socid : 0), $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, (!empty($object->socid) ? $object->socid : 0), (string) $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); } } else { if (!empty($object->fk_project)) { diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index ed830e2cc3e..d00b85f8be8 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -4,7 +4,7 @@ * Copyright (C) 2005-2014 Regis Houssin * Copyright (C) 2015 Juanjo Menent * Copyright (C) 2020 Tobias Sekan - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -121,9 +121,9 @@ foreach ($object->fields as $key => $val) { // Definition of array of fields for columns $arrayfields = array( - 'stockqty' => array('type' => 'float', 'label' => 'PhysicalStock', 'enabled' => 1, 'visible' => -2, 'checked' => 0, 'position' => 170), - 'estimatedvalue' => array('type' => 'float', 'label' => 'EstimatedStockValue', 'enabled' => 1, 'visible' => 1, 'checked' => 1, 'position' => 171), - 'estimatedstockvaluesell' => array('type' => 'float', 'label' => 'EstimatedStockValueSell', 'enabled' => 1, 'checked' => 1, 'visible' => 2, 'position' => 172), + 'stockqty' => array('type' => 'float', 'label' => 'PhysicalStock', 'enabled' => '1', 'visible' => -2, 'checked' => '0', 'position' => 170), + 'estimatedvalue' => array('type' => 'float', 'label' => 'EstimatedStockValue', 'enabled' => '1', 'visible' => 1, 'checked' => '1', 'position' => 171), + 'estimatedstockvaluesell' => array('type' => 'float', 'label' => 'EstimatedStockValueSell', 'enabled' => '1', 'checked' => '1', 'visible' => 2, 'position' => 172), ); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field @@ -131,8 +131,8 @@ foreach ($object->fields as $key => $val) { $visible = (int) dol_eval((string) $val['visible'], 1); $arrayfields['t.'.$key] = array( 'label' => $val['label'], - 'checked' => (($visible < 0) ? 0 : 1), - 'enabled' => (abs($visible) != 3 && (bool) dol_eval($val['enabled'], 1)), + 'checked' => (($visible < 0) ? '0' : '1'), + 'enabled' => (string) (int) (abs($visible) != 3 && (bool) dol_eval($val['enabled'], 1)), 'position' => $val['position'], 'help' => isset($val['help']) ? $val['help'] : '' ); @@ -256,7 +256,7 @@ if ($separatedPMP) { } $sql .= " WHERE t.entity IN (".getEntity('stock').")"; foreach ($search as $key => $val) { - if (array_key_exists($key, $object->fields)||$key == 'status') { + if (array_key_exists($key, $object->fields) || $key == 'status') { $class_key = $key; if ($class_key == 'status') { $class_key = 'statut'; // remove this after refactoring entrepot.class property statut to status @@ -279,10 +279,10 @@ foreach ($search as $key => $val) { $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key); if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) { if (preg_match('/_dtstart$/', $key)) { - $sql .= " AND t.".$db->escape($columnName)." >= '".$db->idate($search[$key])."'"; + $sql .= " AND t.".$db->escape($columnName)." >= '".$db->idate((int) $search[$key])."'"; } if (preg_match('/_dtend$/', $key)) { - $sql .= " AND t.".$db->escape($columnName)." <= '".$db->idate($search[$key])."'"; + $sql .= " AND t.".$db->escape($columnName)." <= '".$db->idate((int) $search[$key])."'"; } } } @@ -581,7 +581,7 @@ foreach ($object->fields as $key => $val) { } elseif ($key == 'lang') { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; $formadmin = new FormAdmin($db); - print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth100imp maxwidth125', 2); + print $formadmin->select_language($search[$key], 'search_lang', 0, array(), 1, 0, 0, 'minwidth100imp maxwidth125', 2); } else { print ''; } @@ -781,7 +781,7 @@ while ($i < $imaxinloop) { if (!empty($arrayfields['t.'.$key]['checked'])) { print '$key)) { - print ' title="'.dol_escape_htmltag($object->$key).'"'; + print ' title="'.dol_escape_htmltag((string) $object->$key).'"'; } print '>'; if ($key == 'statut') { @@ -792,7 +792,7 @@ while ($i < $imaxinloop) { } elseif ($key == 'fax') { print dol_print_phone($object->fax, '', 0, $object->id, 'AC_FAX'); } else { - print $warehouse->showOutputField($val, $key, $object->$key, ''); + print $warehouse->showOutputField($val, $key, (string) $object->$key, ''); } print ''; if (!$i) { diff --git a/htdocs/product/stock/massstockmove.php b/htdocs/product/stock/massstockmove.php index 0290dea17ba..0e55f337b9a 100644 --- a/htdocs/product/stock/massstockmove.php +++ b/htdocs/product/stock/massstockmove.php @@ -228,7 +228,7 @@ if ($action == 'createmovements' && $user->hasRight('stock', 'mouvement', 'creer $result1 = $product->correct_stock( $user, $id_sw, - $qty, + (float) $qty, 1, GETPOST("label"), $pricesrc, @@ -244,7 +244,7 @@ if ($action == 'createmovements' && $user->hasRight('stock', 'mouvement', 'creer $result2 = $product->correct_stock( $user, $id_tw, - $qty, + (float) $qty, 0, GETPOST("label"), $pricedest, @@ -275,7 +275,7 @@ if ($action == 'createmovements' && $user->hasRight('stock', 'mouvement', 'creer $result1 = $product->correct_stock_batch( $user, $id_sw, - $qty, + (float) $qty, 1, GETPOST("label"), $pricesrc, @@ -294,7 +294,7 @@ if ($action == 'createmovements' && $user->hasRight('stock', 'mouvement', 'creer $result2 = $product->correct_stock_batch( $user, $id_tw, - $qty, + (float) $qty, 0, GETPOST("label"), $pricedest, @@ -699,9 +699,9 @@ if (getDolGlobalString('STOCK_SUPPORTS_SERVICES')) { $filtertype = ''; } if (getDolGlobalInt('PRODUIT_LIMIT_SIZE') <= 0) { - $limit = ''; + $limit = 0; } else { - $limit = getDolGlobalString('PRODUIT_LIMIT_SIZE'); + $limit = getDolGlobalInt('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); diff --git a/htdocs/product/stock/movement_card.php b/htdocs/product/stock/movement_card.php index 9c81e707e3d..590420e2028 100644 --- a/htdocs/product/stock/movement_card.php +++ b/htdocs/product/stock/movement_card.php @@ -5,7 +5,7 @@ * Copyright (C) 2015 Juanjo Menent * Copyright (C) 2018 Ferran Marcet * Copyright (C) 2019-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -114,23 +114,23 @@ $extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); $arrayfields = array( - 'm.rowid' => array('label' => $langs->trans("Ref"), 'checked' => 1), - 'm.datem' => array('label' => $langs->trans("Date"), 'checked' => 1), - 'p.ref' => array('label' => $langs->trans("ProductRef"), 'checked' => 1, 'css' => 'maxwidth100'), - 'p.label' => array('label' => $langs->trans("ProductLabel"), 'checked' => 1), - 'm.batch' => array('label' => $langs->trans("BatchNumberShort"), 'checked' => 1, 'enabled' => (isModEnabled('productbatch'))), - 'pl.eatby' => array('label' => $langs->trans("EatByDate"), 'checked' => 0, 'position' => 10, 'enabled' => (isModEnabled('productbatch'))), - 'pl.sellby' => array('label' => $langs->trans("SellByDate"), 'checked' => 0, 'position' => 10, 'enabled' => (isModEnabled('productbatch'))), - 'e.ref' => array('label' => $langs->trans("Warehouse"), 'checked' => 1, 'enabled' => (!($id > 0))), // If we are on specific warehouse, we hide it - 'm.fk_user_author' => array('label' => $langs->trans("Author"), 'checked' => 0), - 'm.inventorycode' => array('label' => $langs->trans("InventoryCodeShort"), 'checked' => 1), - 'm.label' => array('label' => $langs->trans("MovementLabel"), 'checked' => 1), - 'm.type_mouvement' => array('label' => $langs->trans("TypeMovement"), 'checked' => 1), - 'origin' => array('label' => $langs->trans("Origin"), 'checked' => 1), - 'm.value' => array('label' => $langs->trans("Qty"), 'checked' => 1), - 'm.price' => array('label' => $langs->trans("UnitPurchaseValue"), 'checked' => 0), - //'m.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), - //'m.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500) + 'm.rowid' => array('label' => $langs->trans("Ref"), 'checked' => '1'), + 'm.datem' => array('label' => $langs->trans("Date"), 'checked' => '1'), + 'p.ref' => array('label' => $langs->trans("ProductRef"), 'checked' => '1', 'css' => 'maxwidth100'), + 'p.label' => array('label' => $langs->trans("ProductLabel"), 'checked' => '1'), + 'm.batch' => array('label' => $langs->trans("BatchNumberShort"), 'checked' => '1', 'enabled' => (string) (int) (isModEnabled('productbatch'))), + 'pl.eatby' => array('label' => $langs->trans("EatByDate"), 'checked' => '0', 'position' => 10, 'enabled' => (string) (int) (isModEnabled('productbatch'))), + 'pl.sellby' => array('label' => $langs->trans("SellByDate"), 'checked' => '0', 'position' => 10, 'enabled' => (string) (int) (isModEnabled('productbatch'))), + 'e.ref' => array('label' => $langs->trans("Warehouse"), 'checked' => '1', 'enabled' => (string) (int) (!($id > 0))), // If we are on specific warehouse, we hide it + 'm.fk_user_author' => array('label' => $langs->trans("Author"), 'checked' => '0'), + 'm.inventorycode' => array('label' => $langs->trans("InventoryCodeShort"), 'checked' => '1'), + 'm.label' => array('label' => $langs->trans("MovementLabel"), 'checked' => '1'), + 'm.type_mouvement' => array('label' => $langs->trans("TypeMovement"), 'checked' => '1'), + 'origin' => array('label' => $langs->trans("Origin"), 'checked' => '1'), + 'm.value' => array('label' => $langs->trans("Qty"), 'checked' => '1'), + 'm.price' => array('label' => $langs->trans("UnitPurchaseValue"), 'checked' => '0'), + //'m.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked' => '0', 'position'=>500), + //'m.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked' => '0', 'position'=>500) ); $usercanread = (($user->hasRight('stock', 'mouvement', 'lire'))); @@ -218,10 +218,10 @@ if ($action == "correct_stock" && !$cancel && $usercancreate) { $result = $product->correct_stock_batch( $user, $id, - GETPOSTINT("nbpiece"), + GETPOSTFLOAT("nbpiece"), GETPOSTINT("mouvement"), GETPOST("label", 'san_alpha'), - GETPOST('unitprice', 'alpha'), + GETPOSTFLOAT('unitprice'), $eatby, $sellby, $batch, @@ -233,10 +233,10 @@ if ($action == "correct_stock" && !$cancel && $usercancreate) { $result = $product->correct_stock( $user, $id, - GETPOSTINT("nbpiece"), - GETPOST("mouvement", 'alpha'), + GETPOSTFLOAT("nbpiece"), + GETPOSTINT("mouvement"), GETPOST("label", 'san_alpha'), - GETPOST('unitprice', 'alpha'), + GETPOSTFLOAT('unitprice'), GETPOST('inventorycode', 'alpha'), $origin_element, $origin_id @@ -276,7 +276,7 @@ if ($action == "transfert_stock" && !$cancel && $usercancreate) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Product")), null, 'errors'); $action = 'transfert'; } - if (!GETPOSTINT("nbpiece")) { + if (!GETPOSTFLOAT("nbpiece")) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NumberOfUnit")), null, 'errors'); $error++; $action = 'transfert'; @@ -314,14 +314,22 @@ if ($action == "transfert_stock" && !$cancel && $usercancreate) { } $pricedest = $pricesrc; + $result1 = -1; + $result2 = -1; + if ($product->hasbatch()) { $pdluo = new Productbatch($db); + $batch = ''; + $eatby = 0; + $sellby = 0; + $srcwarehouseid = 0; + if ($pdluoid > 0) { $result = $pdluo->fetch($pdluoid); if ($result) { $srcwarehouseid = $pdluo->warehouseid; - $batch = $pdluo->batch; + $batch = (string) $pdluo->batch; $eatby = $pdluo->eatby; $sellby = $pdluo->sellby; } else { @@ -330,7 +338,7 @@ if ($action == "transfert_stock" && !$cancel && $usercancreate) { } } else { $srcwarehouseid = $id; - $batch = GETPOST('batch_number', 'alpha'); + $batch = (string) GETPOST('batch_number', 'alpha'); $eatby = $d_eatby; $sellby = $d_sellby; } @@ -340,7 +348,7 @@ if ($action == "transfert_stock" && !$cancel && $usercancreate) { $result1 = $product->correct_stock_batch( $user, $srcwarehouseid, - GETPOSTINT("nbpiece"), + GETPOSTFLOAT("nbpiece"), 1, GETPOST("label", 'san_alpha'), $pricesrc, @@ -353,7 +361,7 @@ if ($action == "transfert_stock" && !$cancel && $usercancreate) { $result2 = $product->correct_stock_batch( $user, GETPOSTINT("id_entrepot_destination"), - GETPOSTINT("nbpiece"), + GETPOSTFLOAT("nbpiece"), 0, GETPOST("label", 'san_alpha'), $pricedest, @@ -368,7 +376,7 @@ if ($action == "transfert_stock" && !$cancel && $usercancreate) { $result1 = $product->correct_stock( $user, $id, - GETPOSTINT("nbpiece"), + GETPOSTFLOAT("nbpiece"), 1, GETPOST("label", 'alpha'), $pricesrc, @@ -378,8 +386,8 @@ if ($action == "transfert_stock" && !$cancel && $usercancreate) { // Add stock $result2 = $product->correct_stock( $user, - GETPOST("id_entrepot_destination"), - GETPOSTINT("nbpiece"), + GETPOSTINT("id_entrepot_destination"), + GETPOSTFLOAT("nbpiece"), 0, GETPOST("label", 'alpha'), $pricedest, @@ -632,6 +640,7 @@ if ($resql) { $sql = "SELECT MAX(m.datem) as datem"; $sql .= " FROM ".MAIN_DB_PREFIX."stock_mouvement as m"; $sql .= " WHERE m.fk_entrepot = ".(int) $object->id; + $lastmovementdate = 0; $resqlbis = $db->query($sql); if ($resqlbis) { $obj = $db->fetch_object($resqlbis); @@ -1218,7 +1227,7 @@ if ($action != 'create' && $action != 'edit' && $action != 'delete' && $id > 0) $genallowed = $user->hasRight('stock', 'lire'); $delallowed = $user->hasRight('stock', 'creer'); - print $formfile->showdocuments($modulepart, $objectref, $filedir, $urlsource, $genallowed, $delallowed, '', 0, 0, 0, 28, 0, '', 0, '', $object->default_lang, '', $object); + print $formfile->showdocuments($modulepart, $objectref, $filedir, $urlsource, $genallowed, $delallowed, '', 0, 0, 0, 28, 0, '', '', '', $object->default_lang, '', $object); $somethingshown = $formfile->numoffiles; print '
'; diff --git a/htdocs/product/stock/movement_list.php b/htdocs/product/stock/movement_list.php index e5cabbe26d5..a8df7f3435c 100644 --- a/htdocs/product/stock/movement_list.php +++ b/htdocs/product/stock/movement_list.php @@ -5,7 +5,7 @@ * Copyright (C) 2015 Juanjo Menent * Copyright (C) 2018-2022 Ferran Marcet * Copyright (C) 2019-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -73,8 +73,8 @@ $mode = GETPOST('mode', 'aZ'); // The output mode ('list', 'kanban', 'hier $id = GETPOSTINT('id'); $ref = GETPOST('ref', 'alpha'); $msid = GETPOSTINT('msid'); -$idproduct = GETPOST('idproduct', 'intcomma'); -$product_id = GETPOST("product_id", 'intcomma'); +$idproduct = GETPOSTINT('idproduct'); +$product_id = GETPOSTINT('product_id'); $show_files = GETPOSTINT('show_files'); $search_all = trim(GETPOST('search_all', 'alphanohtml')); @@ -136,24 +136,24 @@ $extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); $arrayfields = array( - 'm.rowid' => array('label' => "Ref", 'checked' => 1, 'position' => 1), - 'm.datem' => array('label' => "Date", 'checked' => 1, 'position' => 2), - 'p.ref' => array('label' => "ProductRef", 'checked' => 1, 'css' => 'maxwidth100', 'position' => 3), - 'p.label' => array('label' => "ProductLabel", 'checked' => 0, 'position' => 5), - 'm.batch' => array('label' => "BatchNumberShort", 'checked' => 1, 'position' => 8, 'enabled' => (isModEnabled('productbatch'))), - 'pl.eatby' => array('label' => "EatByDate", 'checked' => 0, 'position' => 9, 'enabled' => (isModEnabled('productbatch'))), - 'pl.sellby' => array('label' => "SellByDate", 'checked' => 0, 'position' => 10, 'enabled' => (isModEnabled('productbatch'))), - 'e.ref' => array('label' => "Warehouse", 'checked' => 1, 'position' => 100, 'enabled' => (!($id > 0))), // If we are on specific warehouse, we hide it - 'm.fk_user_author' => array('label' => "Author", 'checked' => 0, 'position' => 120), - 'm.inventorycode' => array('label' => "InventoryCodeShort", 'checked' => 1, 'position' => 130), - 'm.label' => array('label' => "MovementLabel", 'checked' => 1, 'position' => 140), - 'm.type_mouvement' => array('label' => "TypeMovement", 'checked' => 0, 'position' => 150), - 'origin' => array('label' => "Origin", 'checked' => 1, 'position' => 155), - 'm.fk_projet' => array('label' => 'Project', 'checked' => 0, 'position' => 180), - 'm.value' => array('label' => "Qty", 'checked' => 1, 'position' => 200), - 'm.price' => array('label' => "UnitPurchaseValue", 'checked' => 0, 'position' => 210, 'enabled' => (!getDolGlobalInt('STOCK_MOVEMENT_LIST_HIDE_UNIT_PRICE'))) - //'m.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500), - //'m.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500) + 'm.rowid' => array('label' => "Ref", 'checked' => '1', 'position' => 1), + 'm.datem' => array('label' => "Date", 'checked' => '1', 'position' => 2), + 'p.ref' => array('label' => "ProductRef", 'checked' => '1', 'css' => 'maxwidth100', 'position' => 3), + 'p.label' => array('label' => "ProductLabel", 'checked' => '0', 'position' => 5), + 'm.batch' => array('label' => "BatchNumberShort", 'checked' => '1', 'position' => 8, 'enabled' => (string) (int) (isModEnabled('productbatch'))), + 'pl.eatby' => array('label' => "EatByDate", 'checked' => '0', 'position' => 9, 'enabled' => (string) (int) (isModEnabled('productbatch'))), + 'pl.sellby' => array('label' => "SellByDate", 'checked' => '0', 'position' => 10, 'enabled' => (string) (int) (isModEnabled('productbatch'))), + 'e.ref' => array('label' => "Warehouse", 'checked' => '1', 'position' => 100, 'enabled' => (string) (int) (!($id > 0))), // If we are on specific warehouse, we hide it + 'm.fk_user_author' => array('label' => "Author", 'checked' => '0', 'position' => 120), + 'm.inventorycode' => array('label' => "InventoryCodeShort", 'checked' => '1', 'position' => 130), + 'm.label' => array('label' => "MovementLabel", 'checked' => '1', 'position' => 140), + 'm.type_mouvement' => array('label' => "TypeMovement", 'checked' => '0', 'position' => 150), + 'origin' => array('label' => "Origin", 'checked' => '1', 'position' => 155), + 'm.fk_projet' => array('label' => 'Project', 'checked' => '0', 'position' => 180), + 'm.value' => array('label' => "Qty", 'checked' => '1', 'position' => 200), + 'm.price' => array('label' => "UnitPurchaseValue", 'checked' => '0', 'position' => 210, 'enabled' => (string) (int) (!getDolGlobalInt('STOCK_MOVEMENT_LIST_HIDE_UNIT_PRICE'))) + //'m.datec'=>array('label'=>"DateCreation", 'checked' => '0', 'position'=>500), + //'m.tms'=>array('label'=>"DateModificationShort", 'checked' => '0', 'position'=>500) ); include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; @@ -399,10 +399,10 @@ if ($action == "correct_stock" && $permissiontoadd) { $result = $product->correct_stock_batch( $user, $id, - GETPOSTINT("nbpiece"), + GETPOSTFLOAT("nbpiece"), GETPOSTINT("mouvement"), GETPOST("label", 'alphanohtml'), - price2num(GETPOST('unitprice'), 'MT'), + (float) price2num(GETPOST('unitprice'), 'MT'), $eatby, $sellby, $batch, @@ -416,10 +416,10 @@ if ($action == "correct_stock" && $permissiontoadd) { $result = $product->correct_stock( $user, $id, - GETPOSTINT("nbpiece"), + GETPOSTFLOAT("nbpiece"), GETPOSTINT("mouvement"), GETPOST("label", 'alphanohtml'), - price2num(GETPOST('unitprice'), 'MT'), + (float) price2num(GETPOST('unitprice'), 'MT'), GETPOST('inventorycode', 'alphanohtml'), $origin_element, $origin_id, @@ -461,7 +461,7 @@ if ($action == "transfert_stock" && $permissiontoadd && !$cancel) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Product")), null, 'errors'); $action = 'transfert'; } - if (!GETPOSTINT("nbpiece")) { + if (!GETPOSTFLOAT("nbpiece")) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NumberOfUnit")), null, 'errors'); $error++; $action = 'transfert'; @@ -530,7 +530,7 @@ if ($action == "transfert_stock" && $permissiontoadd && !$cancel) { $result1 = $product->correct_stock_batch( $user, $srcwarehouseid, - GETPOSTINT("nbpiece"), + GETPOSTFLOAT("nbpiece"), 1, GETPOST("label", 'san_alpha'), $pricesrc, @@ -547,7 +547,7 @@ if ($action == "transfert_stock" && $permissiontoadd && !$cancel) { $result2 = $product->correct_stock_batch( $user, GETPOSTINT("id_entrepot_destination"), - GETPOSTINT("nbpiece"), + GETPOSTFLOAT("nbpiece"), 0, GETPOST("label", 'san_alpha'), $pricedest, @@ -566,7 +566,7 @@ if ($action == "transfert_stock" && $permissiontoadd && !$cancel) { $result1 = $product->correct_stock( $user, $id, - GETPOST("nbpiece"), + GETPOSTFLOAT("nbpiece"), 1, GETPOST("label", 'san_alpha'), $pricesrc, @@ -580,8 +580,8 @@ if ($action == "transfert_stock" && $permissiontoadd && !$cancel) { // Add stock $result2 = $product->correct_stock( $user, - GETPOST("id_entrepot_destination"), - GETPOST("nbpiece"), + GETPOSTINT("id_entrepot_destination"), + GETPOSTFLOAT("nbpiece"), 0, GETPOST("label", 'san_alpha'), $pricedest, @@ -755,7 +755,7 @@ if (!empty($search_batch)) { $sql .= natural_search('m.batch', $search_batch); } if (!empty($product_id) && $product_id != '-1') { - $sql .= natural_search('p.rowid', $product_id); + $sql .= natural_search('p.rowid', (string) $product_id); } if (!empty($search_fk_project) && $search_fk_project != '-1') { $sql .= natural_search('m.fk_projet', $search_fk_project); @@ -865,7 +865,7 @@ if ($warehouse->id > 0) { if (isModEnabled('project') && $formproject !== null) { $langs->load("projects"); $morehtmlref .= '
'.img_picto('', 'project').' '.$langs->trans('Project').' '; - if ($usercancreate && 1 == 2) { + if ($usercancreate && 1 == 2) { // @phan-suppress-current-line PhanPluginBothLiteralsBinaryOp if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; } @@ -874,11 +874,11 @@ if ($warehouse->id > 0) { $morehtmlref .= '
'; $morehtmlref .= ''; $morehtmlref .= ''; - $morehtmlref .= $formproject->select_projects(($socid > 0 ? $socid : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500'); + $morehtmlref .= $formproject->select_projects(($socid > 0 ? $socid : -1), (string) $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500'); $morehtmlref .= ''; $morehtmlref .= '
'; } else { - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$warehouse->id, $warehouse->socid, $warehouse->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$warehouse->id, $warehouse->socid, (string) $warehouse->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); } } else { if (!empty($warehouse->fk_project)) { @@ -1688,8 +1688,8 @@ if (count($arrayofuniqueproduct) == 1 && !empty($year) && is_numeric($year)) { $productidselected = $key; $productlabelselected = $val; } - $datebefore = dol_get_first_day($year ? $year : dol_print_date(time(), "%Y"), $month ? $month : 1, true); - $dateafter = dol_get_last_day($year ? $year : dol_print_date(time(), "%Y"), $month ? $month : 12, true); + $datebefore = dol_get_first_day($year ? $year : (int) dol_print_date(time(), "%Y"), $month ? $month : 1, true); + $dateafter = dol_get_last_day($year ? $year : (int) dol_print_date(time(), "%Y"), $month ? $month : 12, true); $balancebefore = $object->calculateBalanceForProductBefore($productidselected, $datebefore); $balanceafter = $object->calculateBalanceForProductBefore($productidselected, $dateafter);