From a5a4452372dcef95d44010683d6e6238b4bd6103 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sun, 11 Jun 2023 05:00:30 +0200 Subject: [PATCH 01/23] Code part --- htdocs/core/lib/product.lib.php | 2 +- htdocs/product/class/product.class.php | 74 ++++++++++++++----- htdocs/product/list.php | 42 ++++++++++- .../stock/class/mouvementstock.class.php | 12 +-- 4 files changed, 102 insertions(+), 28 deletions(-) diff --git a/htdocs/core/lib/product.lib.php b/htdocs/core/lib/product.lib.php index 48c30219248db..122194aa24916 100644 --- a/htdocs/core/lib/product.lib.php +++ b/htdocs/core/lib/product.lib.php @@ -130,7 +130,7 @@ function product_prepare_head($object) $h++; } - if ($object->isProduct() || ($object->isService() && getDolGlobalString('STOCK_SUPPORTS_SERVICES'))) { // If physical product we can stock (or service with option) + if (($object->isProduct() || ($object->isService() && && getDolGlobalString('STOCK_SUPPORTS_SERVICES'))) && $object->stockable_product == Product::ENABLED_STOCK) { // If physical product we can stock (or service with option) if (isModEnabled('stock') && $user->hasRight('stock', 'lire')) { $head[$h][0] = DOL_URL_ROOT."/product/stock/product.php?id=".$object->id; $head[$h][1] = $langs->trans("Stock"); diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index b526c465d7904..337ff58ad08b8 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -767,6 +767,12 @@ class Product extends CommonObject */ public $mandatory_period; + /** + * 0=This service or product is not managed in stock, 1=This service or product is managed in stock + * + * @var boolean + */ + public $stockable_product = 1; /** * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') @@ -820,6 +826,7 @@ class Product extends CommonObject //'tosell' =>array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'default'=>'0', 'index'=>1, 'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Active', -1=>'Cancel')), //'tobuy' =>array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'default'=>'0', 'index'=>1, 'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Active', -1=>'Cancel')), 'mandatory_period' => array('type' => 'integer', 'label' => 'mandatoryperiod', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'default' => '0', 'index' => 1, 'position' => 1000), + 'stockable_product' =>array('type' => 'integer', 'label' => 'stockable_product', 'enabled' => 1, 'visible' => 1, 'default' => 1, 'notnull' => 1, 'index' => 1, 'position' => 502), ); /** @@ -830,6 +837,21 @@ class Product extends CommonObject * Service */ const TYPE_SERVICE = 1; + /** + * Advanced feature: assembly kit + */ + const TYPE_ASSEMBLYKIT = 2; + /** + * Advanced feature: stock kit + */ + const TYPE_STOCKKIT = 3; + + /** + * Stockable product + */ + const NOT_MANAGED_IN_STOCK = 1; + const DISABLED_STOCK = 1; + const ENABLED_STOCK = 0; /** * Constructor @@ -936,6 +958,9 @@ public function create($user, $notrigger = 0) if (empty($this->status_buy)) { $this->status_buy = 0; } + if (empty($this->stockable_product)) { + $this->stockable_product = 0; + } $price_ht = 0; $price_ttc = 0; @@ -1065,6 +1090,7 @@ public function create($user, $notrigger = 0) $sql .= ", batch_mask"; $sql .= ", fk_unit"; $sql .= ", mandatory_period"; + $sql .= ", stockable_product"; $sql .= ") VALUES ("; $sql .= "'".$this->db->idate($this->date_creation)."'"; $sql .= ", ".(!empty($this->entity) ? (int) $this->entity : (int) $conf->entity); @@ -1096,6 +1122,7 @@ public function create($user, $notrigger = 0) $sql .= ", '".$this->db->escape($this->batch_mask)."'"; $sql .= ", ".($this->fk_unit > 0 ? ((int) $this->fk_unit) : 'NULL'); $sql .= ", '".$this->db->escape($this->mandatory_period)."'"; + $sql .= ", ".((int) $this->stockable_product); $sql .= ")"; dol_syslog(get_class($this)."::Create", LOG_DEBUG); @@ -1377,6 +1404,10 @@ public function update($id, $user, $notrigger = 0, $action = 'update', $updatety $this->state_id = 0; } + if (empty($this->stockable_product)) { + $this->stockable_product = 0; + } + // Barcode value $this->barcode = (empty($this->barcode) ? '' : trim($this->barcode)); @@ -1536,7 +1567,9 @@ public function update($id, $user, $notrigger = 0, $action = 'update', $updatety $sql .= ", price_autogen = ".(!$this->price_autogen ? 0 : 1); $sql .= ", fk_price_expression = ".($this->fk_price_expression != 0 ? (int) $this->fk_price_expression : 'NULL'); $sql .= ", fk_user_modif = ".($user->id > 0 ? $user->id : 'NULL'); - $sql .= ", mandatory_period = ".($this->mandatory_period); + $sql .= ", mandatory_period = ".($this->mandatory_period ); + $sql .= ", stockable_product = ".(int) $this->stockable_product; + // stock field is not here because it is a denormalized value from product_stock. $sql .= " WHERE rowid = ".((int) $id); @@ -2813,8 +2846,8 @@ public function fetch($id = 0, $ref = '', $ref_ext = '', $barcode = '', $ignore_ } else { $sql .= " p.pmp,"; } - $sql .= " p.datec, p.tms, p.import_key, p.entity, p.desiredstock, p.tobatch, p.sell_or_eat_by_mandatory, p.batch_mask, p.fk_unit,"; - $sql .= " p.fk_price_expression, p.price_autogen, p.model_pdf,"; + $sql .= " p.datec, p.tms, p.import_key, p.entity, p.desiredstock, p.tobatch, p.batch_mask, p.fk_unit,"; + $sql .= " p.fk_price_expression, p.price_autogen, p.stockable_product,p.model_pdf,"; $sql .= " p.price_label,"; if ($separatedStock) { $sql .= " SUM(sp.reel) as stock"; @@ -2930,12 +2963,12 @@ public function fetch($id = 0, $ref = '', $ref_ext = '', $barcode = '', $ignore_ $this->height = $obj->height; $this->height_units = $obj->height_units; - $this->surface = $obj->surface; - $this->surface_units = $obj->surface_units; - $this->volume = $obj->volume; - $this->volume_units = $obj->volume_units; - $this->barcode = $obj->barcode; - $this->barcode_type = $obj->fk_barcode_type; + $this->surface = $obj->surface; + $this->surface_units = $obj->surface_units; + $this->volume = $obj->volume; + $this->volume_units = $obj->volume_units; + $this->barcode = $obj->barcode; + $this->barcode_type = $obj->fk_barcode_type; $this->accountancy_code_buy = $obj->accountancy_code_buy; $this->accountancy_code_buy_intra = $obj->accountancy_code_buy_intra; @@ -2944,17 +2977,18 @@ public function fetch($id = 0, $ref = '', $ref_ext = '', $barcode = '', $ignore_ $this->accountancy_code_sell_intra = $obj->accountancy_code_sell_intra; $this->accountancy_code_sell_export = $obj->accountancy_code_sell_export; - $this->fk_default_warehouse = $obj->fk_default_warehouse; - $this->fk_default_workstation = $obj->fk_default_workstation; - $this->seuil_stock_alerte = $obj->seuil_stock_alerte; - $this->desiredstock = $obj->desiredstock; - $this->stock_reel = $obj->stock; - $this->pmp = $obj->pmp; - - $this->date_creation = $obj->datec; - $this->date_modification = $obj->tms; - $this->import_key = $obj->import_key; - $this->entity = $obj->entity; + $this->fk_default_warehouse = $obj->fk_default_warehouse; + $this->fk_default_workstation = $obj->fk_default_workstation; + $this->seuil_stock_alerte = $obj->seuil_stock_alerte; + $this->desiredstock = $obj->desiredstock; + $this->stock_reel = $obj->stock; + $this->stockable_product = $obj->stockable_product; + $this->pmp = $obj->pmp; + + $this->date_creation = $obj->datec; + $this->date_modification = $obj->tms; + $this->import_key = $obj->import_key; + $this->entity = $obj->entity; $this->ref_ext = $obj->ref_ext; $this->fk_price_expression = $obj->fk_price_expression; diff --git a/htdocs/product/list.php b/htdocs/product/list.php index b96d6d578b599..ba795184ef0c9 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -102,6 +102,7 @@ $search_country = GETPOST("search_country", 'aZ09'); $search_state = GETPOST("state_id", 'intcomma'); $search_tobatch = GETPOST("search_tobatch"); +$search_stockable_product = GETPOST('search_stockable_product', 'int'); $search_accountancy_code_sell = GETPOST("search_accountancy_code_sell", 'alpha'); $search_accountancy_code_sell_intra = GETPOST("search_accountancy_code_sell_intra", 'alpha'); $search_accountancy_code_sell_export = GETPOST("search_accountancy_code_sell_export", 'alpha'); @@ -278,6 +279,19 @@ 'p.tobuy' => array('label' => $langs->transnoentitiesnoconv("Status").' ('.$langs->transnoentitiesnoconv("Buy").')', 'checked' => 1, 'position' => 1000), 'p.import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'index' => 0, 'checked' => -1, 'position' => 1100), ); + +if(! empty($conf->stock->enabled)) { + // service + if($type == 1) { + if(! empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + $arrayfields['p.stockable_product'] = array('label' => $langs->trans('StockableProduct'), 'checked' => 0, 'position' => 1001); + } + } + else { + //product + $arrayfields['p.stockable_product'] = array('label' => $langs->trans('StockableProduct'), 'checked' => 0, 'position' => 1001); + } +} /*foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { @@ -373,6 +387,7 @@ $show_childproducts = ''; $search_import_key = ''; + $search_stockable_product = ''; $search_accountancy_code_sell = ''; $search_accountancy_code_sell_intra = ''; $search_accountancy_code_sell_export = ''; @@ -458,7 +473,7 @@ } $sql .= ' p.datec as date_creation, p.tms as date_modification, p.pmp, p.stock, p.cost_price,'; $sql .= ' p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units, p.surface, p.surface_units, p.volume, p.volume_units,'; -$sql .= ' p.fk_country, p.fk_state,'; +$sql .= ' p.fk_country, p.fk_state, p.stockable_product,'; $sql .= ' p.import_key,'; if (getDolGlobalString('PRODUCT_USE_UNITS')) { $sql .= ' p.fk_unit, cu.label as cu_label,'; @@ -565,6 +580,9 @@ if (isset($search_tobuy) && dol_strlen($search_tobuy) > 0 && $search_tobuy != -1) { $sql .= " AND p.tobuy = ".((int) $search_tobuy); } +if (isset($search_stockable_product) && dol_strlen($search_stockable_product) > 0 && $search_stockable_product != -1) { + $sql .= " AND p.stockable_product = '". $search_stockable_product . "'"; +} if (isset($search_tobatch) && dol_strlen($search_tobatch) > 0 && $search_tobatch != -1) { $sql .= " AND p.tobatch = ".((int) $search_tobatch); } @@ -650,7 +668,7 @@ $sql .= " ppe.accountancy_code_sell, ppe.accountancy_code_sell_intra, ppe.accountancy_code_sell_export, ppe.accountancy_code_buy, ppe.accountancy_code_buy_intra, ppe.accountancy_code_buy_export,"; } $sql .= ' p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units, p.surface, p.surface_units, p.volume, p.volume_units,'; -$sql .= ' p.fk_country, p.fk_state,'; +$sql .= ' p.fk_country, p.fk_state, p.stockable_product,'; $sql .= ' p.import_key'; if (getDolGlobalString('PRODUCT_USE_UNITS')) { $sql .= ', p.fk_unit, cu.label'; @@ -838,6 +856,9 @@ if ($search_finished) { $param .= "&search_finished=".urlencode($search_finished); } +if($search_stockable_product != '') { + $param .= "&search_stockable_product=".urlencode($search_stockable_product); +} // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; @@ -1177,6 +1198,11 @@ print ' '; print ''; } +// Managed_in_stock +$array = array('-1'=>' ', '0'=>$langs->trans('No'), '1'=>$langs->trans('Yes')); +if (!empty($arrayfields['p.stockable_product']['checked'])){ + print ''.Form::selectarray('search_stockable_product', $array, $search_stockable_product).''; +} // Desired stock if (!empty($arrayfields['p.desiredstock']['checked'])) { print ''; @@ -1425,6 +1451,9 @@ print_liste_field_titre($arrayfields['p.seuil_stock_alerte']['label'], $_SERVER["PHP_SELF"], "p.seuil_stock_alerte", "", $param, '', $sortfield, $sortorder, 'right '); $totalarray['nbfield']++; } +if (!empty($arrayfields['p.stockable_product']['checked'])) { + print_liste_field_titre($arrayfields['p.stockable_product']['label'], $_SERVER['PHP_SELF'], 'p.stockable_product', '', $param, '', $sortfield, $sortorder, 'center '); +} if (!empty($arrayfields['p.desiredstock']['checked'])) { print_liste_field_titre($arrayfields['p.desiredstock']['label'], $_SERVER["PHP_SELF"], "p.desiredstock", "", $param, '', $sortfield, $sortorder, 'right '); $totalarray['nbfield']++; @@ -1574,6 +1603,7 @@ $product_static->volume_units = $obj->volume_units; $product_static->surface = $obj->surface; $product_static->surface_units = $obj->surface_units; + $product_static->stockable_product = $obj->stockable_product; if (getDolGlobalString('PRODUCT_USE_UNITS')) { $product_static->fk_unit = $obj->fk_unit; } @@ -2081,6 +2111,14 @@ $totalarray['nbfield']++; } } + + // not managed in stock + if(! empty($arrayfields['p.stockable_product']['checked'])) { + print ''; + print ($product_static->stockable_product == '1') ? $langs->trans('Yes') : $langs->trans('No'); + print ''; + } + // Desired stock if (!empty($arrayfields['p.desiredstock']['checked'])) { print ''; diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 716f28af767c1..1289de29d3a69 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -463,7 +463,7 @@ public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = return -8; } } else { - if (isset($product->stock_warehouse[$entrepot_id]) && (empty($product->stock_warehouse[$entrepot_id]->real) || $product->stock_warehouse[$entrepot_id]->real < abs($qty))) { + if (isset($product->stock_warehouse[$entrepot_id]) && (empty($product->stock_warehouse[$entrepot_id]->real) || $product->stock_warehouse[$entrepot_id]->real < abs($qty)) && $product->stockable_product == Product::ENABLED_STOCK) { $langs->load("stocks"); $this->error = $langs->trans('qtyToTranferIsNotEnough').' : '.$product->ref; $this->errors[] = $langs->trans('qtyToTranferIsNotEnough').' : '.$product->ref; @@ -473,7 +473,7 @@ public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = } } - if ($movestock) { // Change stock for current product, change for subproduct is done after + if ($movestock && $product->stockable_product == PRODUCT::ENABLED_STOCK) { // Change stock for current product, change for subproduct is done after // Set $origin_type, origin_id and fk_project $fk_project = $this->fk_project; if (!empty($this->origin_type)) { // This is set by caller for tracking reason @@ -649,9 +649,11 @@ public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = if ($movestock && !$error) { // Call trigger - $result = $this->call_trigger('STOCK_MOVEMENT', $user); - if ($result < 0) { - $error++; + if ($product->stockable_product != Product::NOT_MANAGED_IN_STOCK ) { + $result = $this->call_trigger('STOCK_MOVEMENT', $user); + if ($result < 0) { + $error++; + } } // End call triggers // Check unicity for serial numbered equipment once all movement were done. From ac4fc5fcea3d3ae1890dd6929816c7b33d6f6733 Mon Sep 17 00:00:00 2001 From: tnegre Date: Thu, 12 Oct 2023 14:57:29 +0200 Subject: [PATCH 02/23] Code part 2 --- htdocs/expedition/card.php | 60 ++++++++++++++++---- htdocs/expedition/class/expedition.class.php | 2 +- htdocs/langs/en_US/products.lang | 4 ++ htdocs/product/card.php | 22 +++++++ 4 files changed, 77 insertions(+), 11 deletions(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index ae7dc521d998c..fd2dd1cabd8c1 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -279,6 +279,7 @@ $subtotalqty = 0; $j = 0; + $batch = "batchl".$i."_0"; $stockLocation = "ent1".$i."_0"; $qty = "qtyl".$i; @@ -357,6 +358,31 @@ $qty = "qtyl".$i.'_'.$j; } } else { + $p = new Product($db); + $res = $p->fetch($objectsrc->lines[$i]->fk_product); + if($res > 0) { + if(GETPOST('entrepot_id', 'int') == -1) { + $qty .= '_'.$j; + } + + if($p->stockable_product == Product::DISABLED_STOCK) { + $w = new Entrepot($db); + $Tw = $w->list_array(); + if(count($Tw) > 0) { + $w_Id = array_keys($Tw); + $stockLine[$i][$j]['qty'] = GETPOST($qty, 'int'); + + // lorsque que l'on a le stock dĂ©sactivĂ© sur un produit/service + // on force l'entrepot pour passer le test d'ajout de ligne dans expedition.class.php + // + $stockLine[$i][$j]['warehouse_id'] = $w_Id[0]; + $stockLine[$i][$j]['ix_l'] = GETPOST($idl, 'int'); + } + else { + setEventMessage($langs->trans('NoWarehouseInBase')); + } + } + } //shipment line for product with no batch management and no multiple stock location if (GETPOSTINT($qty) > 0) { $totalqty += price2num(GETPOST($qty, 'alpha'), 'MS'); @@ -1240,7 +1266,7 @@ $text = $product_static->getNomUrl(1); $text .= ' - '.(!empty($line->label) ? $line->label : $line->product_label); $description = ($showdescinproductdesc ? '' : dol_htmlentitiesbr($line->desc)); - + $description .= empty($product->stockable_product) ? $langs->trans('StockDisabled') : $langs->trans('StockEnabled') ; print $form->textwithtooltip($text, $description, 3, '', '', $i); // Show range @@ -1350,8 +1376,11 @@ if (!getDolGlobalInt('STOCK_ALLOW_NEGATIVE_TRANSFER')) { $stockMin = 0; } - print $formproduct->selectWarehouses($tmpentrepot_id, 'entl'.$indiceAsked, '', 1, 0, $line->fk_product, '', 1, 0, array(), 'minwidth200', '', 1, $stockMin, 'stock DESC, e.ref'); - + if ($product->stockable_product == Product::ENABLED_STOCK){ + print $formproduct->selectWarehouses($tmpentrepot_id, 'entl'.$indiceAsked, '', 1, 0, $line->fk_product, '', 1, 0, array(), 'minwidth200', '', 1, $stockMin, 'stock DESC, e.ref'); + } else { + print img_warning().' '.$langs->trans('StockDisabled') ; + } if ($tmpentrepot_id > 0 && $tmpentrepot_id == $warehouse_id) { //print $stock.' '.$quantityToBeDelivered; if ($stock < $quantityToBeDelivered) { @@ -1582,10 +1611,13 @@ if (isModEnabled('stock')) { print ''; if ($line->product_type == Product::TYPE_PRODUCT || getDolGlobalString('STOCK_SUPPORTS_SERVICES')) { - print $tmpwarehouseObject->getNomUrl(0).' '; - - print ''; - print '('.$stock.')'; + if ($product->stockable_product == Product::ENABLED_STOCK){ + print $tmpwarehouseObject->getNomUrl(0).' '; + print ''; + print '('.$stock.')'; + } else { + print img_warning().' '.$langs->trans('StockDisabled') ; + } } else { print '('.$langs->trans("Service").')'; } @@ -1745,6 +1777,10 @@ if ($warehouse_selected_id <= 0) { // We did not force a given warehouse, so we won't have no warehouse to change qty. $disabled = 'disabled="disabled"'; } + // finally we overwrite the input with the product status stockable_product if it's disabled + if ($product->stockable_product == Product::DISABLED_STOCK){ + $disabled = ''; + } print ' '; if (empty($disabled) && getDolGlobalString('STOCK_ALLOW_NEGATIVE_TRANSFER')) { print ''; @@ -1774,8 +1810,11 @@ print img_warning().' '.$langs->trans("NoProductToShipFoundIntoStock", $warehouseObject->label); } else { if ($line->fk_product) { - print img_warning().' '.$langs->trans("StockTooLow"); - } else { + if($product->stockable_product == Product::ENABLED_STOCK) { + print img_warning().' '.$langs->trans('StockTooLow'); + } else { + print img_warning().' '.$langs->trans('StockDisabled'); + } } else { print ''; } } @@ -2382,6 +2421,7 @@ $product_static->surface_units = $lines[$i]->surface_units; $product_static->volume = $lines[$i]->volume; $product_static->volume_units = $lines[$i]->volume_units; + $product_static->stockable_product = $lines[$i]->stockable_product; $text = $product_static->getNomUrl(1); $text .= ' - '.$label; @@ -2552,7 +2592,7 @@ print ''; if ($lines[$i]->product_type == Product::TYPE_SERVICE && getDolGlobalString('SHIPMENT_SUPPORTS_SERVICES')) { print '('.$langs->trans("Service").')'; - } elseif ($lines[$i]->entrepot_id > 0) { + } elseif ($lines[$i]->entrepot_id > 0 && $lines[$i]->product->stockable_product == Product::ENABLED_STOCK) { $entrepot = new Entrepot($db); $entrepot->fetch($lines[$i]->entrepot_id); print $entrepot->getNomUrl(1); diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index d75b4e9796278..91fb5eb502abb 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -961,7 +961,7 @@ public function addline($entrepot_id, $id, $qty, $array_options = []) $isavirtualproduct = ($product->hasFatherOrChild(1) > 0); // The product is qualified for a check of quantity (must be enough in stock to be added into shipment). if (!$isavirtualproduct || !getDolGlobalString('PRODUIT_SOUSPRODUITS') || ($isavirtualproduct && !getDolGlobalString('STOCK_EXCLUDE_VIRTUAL_PRODUCTS'))) { // If STOCK_EXCLUDE_VIRTUAL_PRODUCTS is set, we do not manage stock for kits/virtual products. - if ($product_stock < $qty) { + if ($product_stock < $qty && $product->stockable_product == Product::ENABLED_STOCK) { $langs->load("errors"); $this->error = $langs->trans('ErrorStockIsNotEnoughToAddProductOnShipment', $product->ref); $this->errorhidden = 'ErrorStockIsNotEnoughToAddProductOnShipment'; diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 7181b24d39b76..3a1af1764d98a 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -437,3 +437,7 @@ AllowStockMovementVariantParentHelp=By default, a parent of a variant is a virtu ConfirmSetToDraftInventory=Are you sure you want to go back to Draft status?
The quantities currently set in the inventory will be reset. WarningLineProductNotToSell=Product or service "%s" is not to sell and was cloned PriceLabel=Price label +StockableProduct=Stock management +StockableProductDescription=If this option is enabled, the stock modification for this element is retained. If disabled, the stock modification for this element is not retained. +StockDisabled=Stock disabled +StockEnabled=Stock enabled diff --git a/htdocs/product/card.php b/htdocs/product/card.php index eafcfbd81441f..fcf1c86727f80 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -633,6 +633,9 @@ $object->fk_unit = null; } + // managed_in_stock + $object->stockable_product = ($type == 0 || ($type == 1 && !empty($conf->global->STOCK_SUPPORTS_SERVICES))) ? 1 : 0; + $accountancy_code_sell = GETPOST('accountancy_code_sell', 'alpha'); $accountancy_code_sell_intra = GETPOST('accountancy_code_sell_intra', 'alpha'); $accountancy_code_sell_export = GETPOST('accountancy_code_sell_export', 'alpha'); @@ -812,6 +815,9 @@ } else { $object->fk_default_bom = 0; } + + // managed_in_stock + $object->stockable_product = GETPOSTISSET('stockable_product'); $units = GETPOSTINT('units'); if ($units > 0) { @@ -2206,6 +2212,10 @@ print ''; print ''; */ + + print '' . $langs->trans("StockableProduct") . ''; + $checked = $object->stockable_product == 1 ? "checked" : ""; + print ''; } if ($object->isService() && isModEnabled('workstation')) { @@ -2241,6 +2251,12 @@ print ''; print ''; + + if (!empty($conf->stock->enabled) && !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + print '' . $langs->trans("StockableProduct") . ''; + $checked = $object->stockable_product == 1 ? "checked" : ""; + print ''; + } } else { if (!getDolGlobalString('PRODUCT_DISABLE_NATURE')) { // Nature @@ -2722,6 +2738,12 @@ print ''.$langs->trans("DefaultWorkstation").''; print(!empty($workstation->id) ? $workstation->getNomUrl(1) : ''); print ''; + } + + // View stockable_product + if (($object->isProduct() || ($object->isService() && !empty($conf->global->STOCK_SUPPORTS_SERVICES))) && !empty($conf->stock->enabled)) { + print '' . $form->textwithpicto($langs->trans("StockableProduct"), $langs->trans('StockableProductDescription')) . ''; + print 'stockable_product == 1 ? 'checked' : '').'>'; } // Parent product. From 1fe57974eda390a18fc7ac5b6aaba1126048fd78 Mon Sep 17 00:00:00 2001 From: tnegre Date: Thu, 12 Oct 2023 15:18:59 +0200 Subject: [PATCH 03/23] Fix : invert a const --- htdocs/product/class/product.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 337ff58ad08b8..23e2498f6eff8 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -849,7 +849,7 @@ class Product extends CommonObject /** * Stockable product */ - const NOT_MANAGED_IN_STOCK = 1; + const NOT_MANAGED_IN_STOCK = 0; const DISABLED_STOCK = 1; const ENABLED_STOCK = 0; From 0bf0f34da5da2767aed270a16ebc1aa41059ba65 Mon Sep 17 00:00:00 2001 From: tnegre Date: Tue, 17 Oct 2023 10:45:05 +0200 Subject: [PATCH 04/23] Fix : invert disable/enable stock values --- htdocs/product/class/product.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 23e2498f6eff8..e4a47cf040370 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -850,8 +850,8 @@ class Product extends CommonObject * Stockable product */ const NOT_MANAGED_IN_STOCK = 0; - const DISABLED_STOCK = 1; - const ENABLED_STOCK = 0; + const DISABLED_STOCK = 0; + const ENABLED_STOCK = 1; /** * Constructor From 5b7e4b4bb86412c3617635922e086138742c3cee Mon Sep 17 00:00:00 2001 From: mrozniecki Date: Thu, 15 Feb 2024 15:00:59 +0100 Subject: [PATCH 05/23] Fix --- htdocs/core/lib/product.lib.php | 2 +- htdocs/expedition/class/expedition.class.php | 9 ++++++--- .../expedition/class/expeditionligne.class.php | 7 +++++++ htdocs/expedition/dispatch.php | 17 +++++++++++------ 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/htdocs/core/lib/product.lib.php b/htdocs/core/lib/product.lib.php index 122194aa24916..105612cb5fec5 100644 --- a/htdocs/core/lib/product.lib.php +++ b/htdocs/core/lib/product.lib.php @@ -130,7 +130,7 @@ function product_prepare_head($object) $h++; } - if (($object->isProduct() || ($object->isService() && && getDolGlobalString('STOCK_SUPPORTS_SERVICES'))) && $object->stockable_product == Product::ENABLED_STOCK) { // If physical product we can stock (or service with option) + if (($object->isProduct() || ($object->isService() && getDolGlobalString('STOCK_SUPPORTS_SERVICES'))) && $object->stockable_product == Product::ENABLED_STOCK) { // If physical product we can stock (or service with option) if (isModEnabled('stock') && $user->hasRight('stock', 'lire')) { $head[$h][0] = DOL_URL_ROOT."/product/stock/product.php?id=".$object->id; $head[$h][1] = $langs->trans("Stock"); diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 91fb5eb502abb..3db80d8e384c1 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -1617,7 +1617,9 @@ public function fetch_lines() $sql .= ", cd.fk_multicurrency, cd.multicurrency_code, cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc, cd.rang, cd.date_start, cd.date_end"; $sql .= ", ed.rowid as line_id, ed.qty as qty_shipped, ed.fk_element, ed.fk_elementdet, ed.element_type, ed.fk_entrepot"; $sql .= ", p.ref as product_ref, p.label as product_label, p.fk_product_type, p.barcode as product_barcode"; - $sql .= ", p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units, p.surface, p.surface_units, p.volume, p.volume_units, p.tosell as product_tosell, p.tobuy as product_tobuy, p.tobatch as product_tobatch"; + $sql .= ", p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units"; + $sql .= ", p.surface, p.surface_units, p.volume, p.volume_units, p.tosell as product_tosell, p.tobuy as product_tobuy"; + $sql .= ", p.tobatch as product_tobatch, p.stockable_product"; $sql .= " FROM ".MAIN_DB_PREFIX."expeditiondet as ed, ".MAIN_DB_PREFIX."commandedet as cd"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = cd.fk_product"; $sql .= " WHERE ed.fk_expedition = ".((int) $this->id); @@ -1707,8 +1709,9 @@ public function fetch_lines() $line->surface = $obj->surface; $line->surface_units = $obj->surface_units; $line->volume = $obj->volume; - $line->volume_units = $obj->volume_units; - $line->fk_unit = $obj->fk_unit; + $line->volume_units = $obj->volume_units; + $line->stockable_product = $obj->stockable_product; + $line->fk_unit = $obj->fk_unit; $line->pa_ht = $obj->pa_ht; diff --git a/htdocs/expedition/class/expeditionligne.class.php b/htdocs/expedition/class/expeditionligne.class.php index 5f7aa83c1411a..ed37d785e63ad 100644 --- a/htdocs/expedition/class/expeditionligne.class.php +++ b/htdocs/expedition/class/expeditionligne.class.php @@ -262,6 +262,13 @@ class ExpeditionLigne extends CommonObjectLine */ public $volume_units; + /** + * 0=This service or product is not managed in stock, 1=This service or product is managed in stock + * + * @var boolean + */ + public $stockable_product = true; + /** * @var float|string */ diff --git a/htdocs/expedition/dispatch.php b/htdocs/expedition/dispatch.php index f29fd4d2c8650..d95b78139e535 100644 --- a/htdocs/expedition/dispatch.php +++ b/htdocs/expedition/dispatch.php @@ -901,13 +901,18 @@ // Warehouse print ''; - if (count($listwarehouses) > 1) { - print $formproduct->selectWarehouses(GETPOST("entrepot".$suffix) ? GETPOST("entrepot".$suffix) : $objd->fk_entrepot, "entrepot".$suffix, '', 1, 0, $objp->fk_product, '', 1, 0, null, 'csswarehouse'.$suffix); - } elseif (count($listwarehouses) == 1) { - print $formproduct->selectWarehouses(GETPOST("entrepot".$suffix) ? GETPOST("entrepot".$suffix) : $objd->fk_entrepot, "entrepot".$suffix, '', 0, 0, $objp->fk_product, '', 1, 0, null, 'csswarehouse'.$suffix); + if ($objp->stockable_product == Product::ENABLED_STOCK){ + if (count($listwarehouses) > 1) { + print $formproduct->selectWarehouses(GETPOST("entrepot".$suffix) ? GETPOST("entrepot".$suffix) : $objd->fk_entrepot, "entrepot".$suffix, '', 1, 0, $objp->fk_product, '', 1, 0, null, 'csswarehouse'.$suffix); + } elseif (count($listwarehouses) == 1) { + print $formproduct->selectWarehouses(GETPOST("entrepot".$suffix) ? GETPOST("entrepot".$suffix) : $objd->fk_entrepot, "entrepot".$suffix, '', 0, 0, $objp->fk_product, '', 1, 0, null, 'csswarehouse'.$suffix); + } else { + $langs->load("errors"); + print $langs->trans("ErrorNoWarehouseDefined"); + } } else { - $langs->load("errors"); - print $langs->trans("ErrorNoWarehouseDefined"); + print ''; + print img_warning().' '.$langs->trans('StockDisabled') ; } print "\n"; From f6447b1f5763e88622a05e9a56bcadf646f97398 Mon Sep 17 00:00:00 2001 From: mrozniecki Date: Thu, 15 Feb 2024 16:48:36 +0100 Subject: [PATCH 06/23] Fix missing column from select inside sql request --- htdocs/expedition/dispatch.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/expedition/dispatch.php b/htdocs/expedition/dispatch.php index d95b78139e535..a7e66b630490e 100644 --- a/htdocs/expedition/dispatch.php +++ b/htdocs/expedition/dispatch.php @@ -572,7 +572,7 @@ //$sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref AS sref, SUM(l.qty) as qty,"; $sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, '' AS sref, l.qty as qty,"; - $sql .= " p.ref, p.label, p.tobatch, p.fk_default_warehouse, p.barcode"; + $sql .= " p.ref, p.label, p.tobatch, p.fk_default_warehouse, p.barcode, p.stockable_product"; // Enable hooks to alter the SQL query (SELECT) $parameters = array(); $reshook = $hookmanager->executeHooks( From b19f8af286e65cea08b2bcb2e80729ee7973ec38 Mon Sep 17 00:00:00 2001 From: mrozniecki Date: Thu, 15 Feb 2024 16:59:49 +0100 Subject: [PATCH 07/23] Fix input hidden missing name --- htdocs/expedition/dispatch.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/expedition/dispatch.php b/htdocs/expedition/dispatch.php index a7e66b630490e..0ba03b5733e75 100644 --- a/htdocs/expedition/dispatch.php +++ b/htdocs/expedition/dispatch.php @@ -911,7 +911,7 @@ print $langs->trans("ErrorNoWarehouseDefined"); } } else { - print ''; + print ''; print img_warning().' '.$langs->trans('StockDisabled') ; } print "\n"; From a24edc2fe4485cfaead9e5521eec1c87ff1b0956 Mon Sep 17 00:00:00 2001 From: mrozniecki Date: Fri, 16 Feb 2024 09:34:53 +0100 Subject: [PATCH 08/23] ajout d'un commentaire --- htdocs/expedition/dispatch.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/expedition/dispatch.php b/htdocs/expedition/dispatch.php index 0ba03b5733e75..4ba13978baeb6 100644 --- a/htdocs/expedition/dispatch.php +++ b/htdocs/expedition/dispatch.php @@ -911,6 +911,7 @@ print $langs->trans("ErrorNoWarehouseDefined"); } } else { + // on force l'entrepot pour passer le test d'ajout de ligne dans expedition.class.php print ''; print img_warning().' '.$langs->trans('StockDisabled') ; } From 11c705025fa271e7e8970b05c464d3b2280b3d92 Mon Sep 17 00:00:00 2001 From: Ulysse Valdenaire Date: Wed, 13 Mar 2024 15:42:31 +0100 Subject: [PATCH 09/23] small fixes --- htdocs/expedition/card.php | 2 +- htdocs/expedition/class/expedition.class.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index fd2dd1cabd8c1..ab537795a5c8f 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -2592,7 +2592,7 @@ print ''; if ($lines[$i]->product_type == Product::TYPE_SERVICE && getDolGlobalString('SHIPMENT_SUPPORTS_SERVICES')) { print '('.$langs->trans("Service").')'; - } elseif ($lines[$i]->entrepot_id > 0 && $lines[$i]->product->stockable_product == Product::ENABLED_STOCK) { + } elseif ($lines[$i]->entrepot_id > 0 && $lines[$i]->stockable_product == Product::ENABLED_STOCK) { $entrepot = new Entrepot($db); $entrepot->fetch($lines[$i]->entrepot_id); print $entrepot->getNomUrl(1); diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 3db80d8e384c1..5795e34890769 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -1682,6 +1682,7 @@ public function fetch_lines() $line->fk_expedition = $this->id; // id of parent + $line->stockable_product = $obj->stockable_product; $line->product_type = $obj->product_type; $line->fk_product = $obj->fk_product; $line->fk_product_type = $obj->fk_product_type; From 7a531bbab708973351ec77fdc477c3d27486293d Mon Sep 17 00:00:00 2001 From: tnegre Date: Tue, 16 Apr 2024 14:17:03 +0200 Subject: [PATCH 10/23] remove unrelated lines --- htdocs/product/class/product.class.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index e4a47cf040370..74f1568b53b42 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -837,14 +837,6 @@ class Product extends CommonObject * Service */ const TYPE_SERVICE = 1; - /** - * Advanced feature: assembly kit - */ - const TYPE_ASSEMBLYKIT = 2; - /** - * Advanced feature: stock kit - */ - const TYPE_STOCKKIT = 3; /** * Stockable product From b03bdf17d028e6b1e9b39e6219622db0b9fe43aa Mon Sep 17 00:00:00 2001 From: mrozniecki Date: Thu, 15 Feb 2024 16:34:09 +0100 Subject: [PATCH 11/23] phpcs --- htdocs/expedition/card.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index ab537795a5c8f..e8b2c9f12dde2 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -360,15 +360,15 @@ } else { $p = new Product($db); $res = $p->fetch($objectsrc->lines[$i]->fk_product); - if($res > 0) { - if(GETPOST('entrepot_id', 'int') == -1) { + if ($res > 0) { + if (GETPOST('entrepot_id', 'int') == -1) { $qty .= '_'.$j; } - if($p->stockable_product == Product::DISABLED_STOCK) { + if ($p->stockable_product == Product::DISABLED_STOCK) { $w = new Entrepot($db); $Tw = $w->list_array(); - if(count($Tw) > 0) { + if (count($Tw) > 0) { $w_Id = array_keys($Tw); $stockLine[$i][$j]['qty'] = GETPOST($qty, 'int'); @@ -377,8 +377,7 @@ // $stockLine[$i][$j]['warehouse_id'] = $w_Id[0]; $stockLine[$i][$j]['ix_l'] = GETPOST($idl, 'int'); - } - else { + } else { setEventMessage($langs->trans('NoWarehouseInBase')); } } From d96a1b82fc67a1461344e4383cd2902b9e7bc2d4 Mon Sep 17 00:00:00 2001 From: tnegre Date: Tue, 16 Apr 2024 14:24:48 +0200 Subject: [PATCH 12/23] stickler fix --- htdocs/product/class/product.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 74f1568b53b42..082fd4ac6fb4e 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -772,7 +772,7 @@ class Product extends CommonObject * * @var boolean */ - public $stockable_product = 1; + public $stockable_product = true; /** * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') @@ -951,7 +951,7 @@ public function create($user, $notrigger = 0) $this->status_buy = 0; } if (empty($this->stockable_product)) { - $this->stockable_product = 0; + $this->stockable_product = false; } $price_ht = 0; @@ -1397,7 +1397,7 @@ public function update($id, $user, $notrigger = 0, $action = 'update', $updatety } if (empty($this->stockable_product)) { - $this->stockable_product = 0; + $this->stockable_product = false; } // Barcode value From b5d24779a1ffe896e4a5c46fe50fc3ca68fea44a Mon Sep 17 00:00:00 2001 From: tnegre Date: Fri, 19 Apr 2024 13:37:37 +0200 Subject: [PATCH 13/23] pre-commit fixes --- htdocs/expedition/card.php | 15 ++++++++------- htdocs/product/card.php | 6 +++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index e8b2c9f12dde2..d312aed4c244a 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -1265,7 +1265,7 @@ $text = $product_static->getNomUrl(1); $text .= ' - '.(!empty($line->label) ? $line->label : $line->product_label); $description = ($showdescinproductdesc ? '' : dol_htmlentitiesbr($line->desc)); - $description .= empty($product->stockable_product) ? $langs->trans('StockDisabled') : $langs->trans('StockEnabled') ; + $description .= empty($product->stockable_product) ? $langs->trans('StockDisabled') : $langs->trans('StockEnabled'); print $form->textwithtooltip($text, $description, 3, '', '', $i); // Show range @@ -1375,10 +1375,10 @@ if (!getDolGlobalInt('STOCK_ALLOW_NEGATIVE_TRANSFER')) { $stockMin = 0; } - if ($product->stockable_product == Product::ENABLED_STOCK){ + if ($product->stockable_product == Product::ENABLED_STOCK) { print $formproduct->selectWarehouses($tmpentrepot_id, 'entl'.$indiceAsked, '', 1, 0, $line->fk_product, '', 1, 0, array(), 'minwidth200', '', 1, $stockMin, 'stock DESC, e.ref'); } else { - print img_warning().' '.$langs->trans('StockDisabled') ; + print img_warning().' '.$langs->trans('StockDisabled'); } if ($tmpentrepot_id > 0 && $tmpentrepot_id == $warehouse_id) { //print $stock.' '.$quantityToBeDelivered; @@ -1610,12 +1610,12 @@ if (isModEnabled('stock')) { print ''; if ($line->product_type == Product::TYPE_PRODUCT || getDolGlobalString('STOCK_SUPPORTS_SERVICES')) { - if ($product->stockable_product == Product::ENABLED_STOCK){ + if ($product->stockable_product == Product::ENABLED_STOCK) { print $tmpwarehouseObject->getNomUrl(0).' '; print ''; print '('.$stock.')'; } else { - print img_warning().' '.$langs->trans('StockDisabled') ; + print img_warning().' '.$langs->trans('StockDisabled'); } } else { print '('.$langs->trans("Service").')'; @@ -1777,7 +1777,7 @@ $disabled = 'disabled="disabled"'; } // finally we overwrite the input with the product status stockable_product if it's disabled - if ($product->stockable_product == Product::DISABLED_STOCK){ + if ($product->stockable_product == Product::DISABLED_STOCK) { $disabled = ''; } print ' '; @@ -1813,7 +1813,8 @@ print img_warning().' '.$langs->trans('StockTooLow'); } else { print img_warning().' '.$langs->trans('StockDisabled'); - } } else { + } + } else { print ''; } } diff --git a/htdocs/product/card.php b/htdocs/product/card.php index fcf1c86727f80..aba4ee0d6a749 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -815,7 +815,7 @@ } else { $object->fk_default_bom = 0; } - + // managed_in_stock $object->stockable_product = GETPOSTISSET('stockable_product'); @@ -2251,7 +2251,7 @@ print ''; print ''; - + if (!empty($conf->stock->enabled) && !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { print '' . $langs->trans("StockableProduct") . ''; $checked = $object->stockable_product == 1 ? "checked" : ""; @@ -2738,7 +2738,7 @@ print ''.$langs->trans("DefaultWorkstation").''; print(!empty($workstation->id) ? $workstation->getNomUrl(1) : ''); print ''; - } + } // View stockable_product if (($object->isProduct() || ($object->isService() && !empty($conf->global->STOCK_SUPPORTS_SERVICES))) && !empty($conf->stock->enabled)) { From d43d822c3e65a06990aa60b30398d044d8b7a9c1 Mon Sep 17 00:00:00 2001 From: tnegre Date: Tue, 14 May 2024 13:49:00 +0200 Subject: [PATCH 14/23] pre-commit fixes --- htdocs/expedition/card.php | 2 +- htdocs/expedition/dispatch.php | 60 +++++++++++++++++----------------- htdocs/product/card.php | 6 ++-- htdocs/product/list.php | 12 +++---- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index d312aed4c244a..1be537f11f5ff 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -1809,7 +1809,7 @@ print img_warning().' '.$langs->trans("NoProductToShipFoundIntoStock", $warehouseObject->label); } else { if ($line->fk_product) { - if($product->stockable_product == Product::ENABLED_STOCK) { + if ($product->stockable_product == Product::ENABLED_STOCK) { print img_warning().' '.$langs->trans('StockTooLow'); } else { print img_warning().' '.$langs->trans('StockDisabled'); diff --git a/htdocs/expedition/dispatch.php b/htdocs/expedition/dispatch.php index 4ba13978baeb6..729f5429284d4 100644 --- a/htdocs/expedition/dispatch.php +++ b/htdocs/expedition/dispatch.php @@ -901,7 +901,7 @@ // Warehouse print ''; - if ($objp->stockable_product == Product::ENABLED_STOCK){ + if ($objp->stockable_product == Product::ENABLED_STOCK) { if (count($listwarehouses) > 1) { print $formproduct->selectWarehouses(GETPOST("entrepot".$suffix) ? GETPOST("entrepot".$suffix) : $objd->fk_entrepot, "entrepot".$suffix, '', 1, 0, $objp->fk_product, '', 1, 0, null, 'csswarehouse'.$suffix); } elseif (count($listwarehouses) == 1) { @@ -913,7 +913,7 @@ } else { // on force l'entrepot pour passer le test d'ajout de ligne dans expedition.class.php print ''; - print img_warning().' '.$langs->trans('StockDisabled') ; + print img_warning().' '.$langs->trans('StockDisabled'); } print "\n"; @@ -1166,7 +1166,7 @@ var errortab3 = []; var errortab4 = []; - function barcodescannerjs(){ + function barcodescannerjs() { console.log("We catch inputs in scanner box"); jQuery("#scantoolmessage").text(); @@ -1183,11 +1183,11 @@ function barcodescannerjs(){ errortab3 = []; errortab4 = []; - textarray = textarray.filter(function(value){ + textarray = textarray.filter(function(value) { return value != ""; }); - if(textarray.some((element) => element != "")){ - $(".qtydispatchinput").each(function(){ + if (textarray.some((element) => element != "")) { + $(".qtydispatchinput").each(function() { id = $(this).attr(\'id\'); idarray = id.split(\'_\'); idproduct = idarray[2]; @@ -1198,7 +1198,7 @@ function barcodescannerjs(){ productbarcode = $("#product_"+idproduct).attr(\'data-barcode\'); console.log(productbarcode); productbatchcode = $("#lot_number_"+id).val(); - if(productbatchcode == undefined){ + if (productbatchcode == undefined) { productbatchcode = ""; } console.log(productbatchcode); @@ -1206,25 +1206,25 @@ function barcodescannerjs(){ if (barcodemode != "barcodeforproduct") { tabproduct.forEach(product=>{ console.log("product.Batch="+product.Batch+" productbatchcode="+productbatchcode); - if(product.Batch != "" && product.Batch == productbatchcode){ + if (product.Batch != "" && product.Batch == productbatchcode) { console.log("duplicate batch code found for batch code "+productbatchcode); duplicatedbatchcode.push(productbatchcode); } }) } productinput = $("#qty_"+id).val(); - if(productinput == ""){ + if (productinput == "") { productinput = 0 } tabproduct.push({\'Id\':id,\'Warehouse\':warehouse,\'Barcode\':productbarcode,\'Batch\':productbatchcode,\'Qty\':productinput,\'fetched\':false}); }); console.log("Loop on each record entered in the textarea"); - textarray.forEach(function(element,index){ + textarray.forEach(function(element,index) { console.log("Process record element="+element+" id="+id); var verify_batch = false; var verify_barcode = false; - switch(barcodemode){ + switch(barcodemode) { case "barcodeforautodetect": verify_barcode = barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,warehousetouse,selectaddorreplace,"barcode",true); verify_batch = barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,warehousetouse,selectaddorreplace,"lotserial",true); @@ -1255,12 +1255,12 @@ function barcodescannerjs(){ if (Object.keys(errortab1).length < 1 && Object.keys(errortab2).length < 1 && Object.keys(errortab3).length < 1) { tabproduct.forEach(product => { - if(product.Qty!=0){ - if(product.hasOwnProperty("reelqty")){ + if (product.Qty!=0) { + if (product.hasOwnProperty("reelqty")) { idprod = $("td[data-idproduct=\'"+product.fk_product+"\']").attr("id"); idproduct = idprod.split("_")[1]; console.log("We create a new line for product_"+idproduct); - if(product.Barcode != null){ + if (product.Barcode != null) { modedispatch = "dispatch"; } else { modedispatch = "batch"; @@ -1272,7 +1272,7 @@ function barcodescannerjs(){ $("#qty_"+(nbrTrs-1)+"_"+idproduct).val(product.Qty); $("#entrepot_"+(nbrTrs-1)+"_"+idproduct).val(product.Warehouse); - if(modedispatch == "batch"){ + if (modedispatch == "batch") { $("#lot_number_"+(nbrTrs-1)+"_"+idproduct).val(product.Batch); } @@ -1323,7 +1323,7 @@ function barcodescannerjs(){ } /* This methode is called by parent barcodescannerjs() */ - function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,warehousetouse,selectaddorreplace,mode,autodetect=false){ + function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,warehousetouse,selectaddorreplace,mode,autodetect=false) { BarcodeIsInProduct=0; newproductrow=0 result=false; @@ -1333,13 +1333,13 @@ function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,ware type: \'POST\', async: false, success: function(response) { - if (response.status == "success"){ + if (response.status == "success") { console.log(response.message); - if(!newproductrow){ + if (!newproductrow) { newproductrow = response.object; } }else{ - if (mode!="lotserial" && autodetect==false && !errortab4.includes(element)){ + if (mode!="lotserial" && autodetect==false && !errortab4.includes(element)) { errortab4.push(element); console.error(response.message); } @@ -1350,18 +1350,18 @@ function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,ware }, }); console.log("Product "+(index+=1)+": "+element); - if(mode == "barcode"){ + if (mode == "barcode") { testonproduct = product.Barcode - }else if (mode == "lotserial"){ + }else if (mode == "lotserial") { testonproduct = product.Batch } testonwarehouse = product.Warehouse; - if(testonproduct == element && testonwarehouse == warehousetouse){ - if(selectaddorreplace == "add"){ + if (testonproduct == element && testonwarehouse == warehousetouse) { + if (selectaddorreplace == "add") { productqty = parseInt(product.Qty,10); product.Qty = productqty + parseInt(barcodeproductqty,10); - }else if(selectaddorreplace == "replace"){ - if(product.fetched == false){ + }else if (selectaddorreplace == "replace") { + if (product.fetched == false) { product.Qty = barcodeproductqty product.fetched=true }else{ @@ -1372,11 +1372,11 @@ function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,ware BarcodeIsInProduct+=1; } }) - if(BarcodeIsInProduct==0 && newproductrow!=0){ + if (BarcodeIsInProduct==0 && newproductrow!=0) { tabproduct.push({\'Id\':tabproduct.length-1,\'Warehouse\':newproductrow.fk_warehouse,\'Barcode\':mode=="barcode"?element:null,\'Batch\':mode=="lotserial"?element:null,\'Qty\':barcodeproductqty,\'fetched\':true,\'reelqty\':newproductrow.reelqty,\'fk_product\':newproductrow.fk_product,\'mode\':mode}); result = true; } - if(BarcodeIsInProduct > 0){ + if (BarcodeIsInProduct > 0) { result = true; } return result; @@ -1400,7 +1400,7 @@ function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,ware $("#autoreset").click(function() { console.log("we click on autoreset"); - $(".autoresettr").each(function(){ + $(".autoresettr").each(function() { id = $(this).attr("name"); idtab = id.split("_"); console.log("we process line "+id+" "+idtab); @@ -1423,8 +1423,8 @@ function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,ware return false; }); - $("#resetalltoexpected").click(function(){ - $(".qtydispatchinput").each(function(){ + $("#resetalltoexpected").click(function() { + $(".qtydispatchinput").each(function() { console.log("We reset to expected "+$(this).attr("id")+" qty to dispatch"); $(this).val($(this).data("expected")); }); diff --git a/htdocs/product/card.php b/htdocs/product/card.php index aba4ee0d6a749..1cfd0ed81fe6c 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -815,7 +815,7 @@ } else { $object->fk_default_bom = 0; } - + // managed_in_stock $object->stockable_product = GETPOSTISSET('stockable_product'); @@ -2042,7 +2042,7 @@ $(document).ready(function() { console.log($("#statusBatchWarning")) $("#status_batch").on("change", function() { - if ($("#status_batch")[0].value == 0){ + if ($("#status_batch")[0].value == 0) { $("#statusBatchMouvToGlobal").show() } else { $("#statusBatchMouvToGlobal").hide() @@ -2056,7 +2056,7 @@ $(document).ready(function() { console.log($("#statusBatchWarning")) $("#status_batch").on("change", function() { - if ($("#status_batch")[0].value == 2){ + if ($("#status_batch")[0].value == 2) { $("#statusBatchWarning").show() } else { $("#statusBatchWarning").hide() diff --git a/htdocs/product/list.php b/htdocs/product/list.php index ba795184ef0c9..b50acf416f780 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -280,10 +280,10 @@ 'p.import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'index' => 0, 'checked' => -1, 'position' => 1100), ); -if(! empty($conf->stock->enabled)) { +if (! empty($conf->stock->enabled)) { // service - if($type == 1) { - if(! empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + if ($type == 1) { + if (! empty($conf->global->STOCK_SUPPORTS_SERVICES)) { $arrayfields['p.stockable_product'] = array('label' => $langs->trans('StockableProduct'), 'checked' => 0, 'position' => 1001); } } @@ -856,7 +856,7 @@ if ($search_finished) { $param .= "&search_finished=".urlencode($search_finished); } -if($search_stockable_product != '') { +if ($search_stockable_product != '') { $param .= "&search_stockable_product=".urlencode($search_stockable_product); } // Add $param from extra fields @@ -1200,7 +1200,7 @@ } // Managed_in_stock $array = array('-1'=>' ', '0'=>$langs->trans('No'), '1'=>$langs->trans('Yes')); -if (!empty($arrayfields['p.stockable_product']['checked'])){ +if (!empty($arrayfields['p.stockable_product']['checked'])) { print ''.Form::selectarray('search_stockable_product', $array, $search_stockable_product).''; } // Desired stock @@ -2113,7 +2113,7 @@ } // not managed in stock - if(! empty($arrayfields['p.stockable_product']['checked'])) { + if (! empty($arrayfields['p.stockable_product']['checked'])) { print ''; print ($product_static->stockable_product == '1') ? $langs->trans('Yes') : $langs->trans('No'); print ''; From 42f81afff91788a5cd2102ce332a3334d5d94a7c Mon Sep 17 00:00:00 2001 From: tnegre Date: Tue, 14 May 2024 14:08:44 +0200 Subject: [PATCH 15/23] pre-commit fix --- htdocs/product/list.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index b50acf416f780..b99ef783538f1 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -286,8 +286,7 @@ if (! empty($conf->global->STOCK_SUPPORTS_SERVICES)) { $arrayfields['p.stockable_product'] = array('label' => $langs->trans('StockableProduct'), 'checked' => 0, 'position' => 1001); } - } - else { + } else { //product $arrayfields['p.stockable_product'] = array('label' => $langs->trans('StockableProduct'), 'checked' => 0, 'position' => 1001); } From f2466be7577f16ac258cb54db578b46c125a1ed0 Mon Sep 17 00:00:00 2001 From: tnegre Date: Tue, 28 May 2024 17:07:00 +0200 Subject: [PATCH 16/23] fix missing translation --- htdocs/langs/en_US/sendings.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/sendings.lang b/htdocs/langs/en_US/sendings.lang index 9f648d5f706ff..73502ff2eb745 100644 --- a/htdocs/langs/en_US/sendings.lang +++ b/htdocs/langs/en_US/sendings.lang @@ -66,6 +66,7 @@ NoLineGoOnTabToAddSome=No line, go on tab "%s" to add CreateInvoiceForThisCustomerFromSendings=Create Bills IfValidateInvoiceIsNoSendingStayUnbilled=If invoice validation is 'No', the sending will remain to status 'Unbilled' until the invoice is validated. OptionToSetSendingBilledNotEnabled=Option from module Workflow, to set sending to 'Billed' automatically when invoice is validated, is not enabled, so you will have to set the status of sendings to 'Billed' manually after the invoice has been generated. +NoWarehouseInBase=No warehouse in base # Sending methods # ModelDocument From 06a748c1d5e1e5aed6acff98b45c62a0799a9244 Mon Sep 17 00:00:00 2001 From: tnegre Date: Mon, 10 Jun 2024 14:36:43 +0200 Subject: [PATCH 17/23] Fix phpstan --- htdocs/product/stock/class/mouvementstock.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 1289de29d3a69..7601e35b2025a 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -473,7 +473,7 @@ public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = } } - if ($movestock && $product->stockable_product == PRODUCT::ENABLED_STOCK) { // Change stock for current product, change for subproduct is done after + if ($movestock && $product->stockable_product == Product::ENABLED_STOCK) { // Change stock for current product, change for subproduct is done after // Set $origin_type, origin_id and fk_project $fk_project = $this->fk_project; if (!empty($this->origin_type)) { // This is set by caller for tracking reason From 9b02c454d69484a838f8ba6e3e8f10dbae2dd2b9 Mon Sep 17 00:00:00 2001 From: tnegre Date: Mon, 10 Jun 2024 15:18:16 +0200 Subject: [PATCH 18/23] fix winCI --- htdocs/product/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index b99ef783538f1..ec02917a17cd7 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -580,7 +580,7 @@ $sql .= " AND p.tobuy = ".((int) $search_tobuy); } if (isset($search_stockable_product) && dol_strlen($search_stockable_product) > 0 && $search_stockable_product != -1) { - $sql .= " AND p.stockable_product = '". $search_stockable_product . "'"; + $sql .= " AND p.stockable_product = '". ((int) $search_stockable_product) . "'"; } if (isset($search_tobatch) && dol_strlen($search_tobatch) > 0 && $search_tobatch != -1) { $sql .= " AND p.tobatch = ".((int) $search_tobatch); From b32b54bd9ed9193057385d99812448189a691cb8 Mon Sep 17 00:00:00 2001 From: tnegre Date: Tue, 17 Sep 2024 15:44:17 +0200 Subject: [PATCH 19/23] fix travis --- htdocs/product/class/product.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 082fd4ac6fb4e..e0145dee10684 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2883,7 +2883,7 @@ public function fetch($id = 0, $ref = '', $ref_ext = '', $barcode = '', $ignore_ $sql .= " p.pmp,"; } $sql .= " p.datec, p.tms, p.import_key, p.entity, p.desiredstock, p.tobatch, p.sell_or_eat_by_mandatory, p.batch_mask, p.fk_unit,"; - $sql .= " p.fk_price_expression, p.price_autogen, p.model_pdf"; + $sql .= " p.fk_price_expression, p.price_autogen, p.stockable_product, p.model_pdf"; $sql .= " ,p.price_label"; if (!$separatedStock) { $sql .= ", p.stock"; From a0b8d48687d3ca40e9a57375eb08c03fed114b10 Mon Sep 17 00:00:00 2001 From: tnegre Date: Wed, 18 Sep 2024 12:21:02 +0200 Subject: [PATCH 20/23] fix phpstan --- htdocs/product/class/product.class.php | 5 +++++ htdocs/societe/card.php | 1 + htdocs/societe/class/societe.class.php | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index e0145dee10684..f7401806fc1db 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -767,6 +767,11 @@ class Product extends CommonObject */ public $mandatory_period; + /** + * @var int + */ + public $no_button_copy; + /** * 0=This service or product is not managed in stock, 1=This service or product is managed in stock * diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 33c4c2f6421b9..2796aaa62bdfc 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -97,6 +97,7 @@ $error = 0; $errors = array(); +$refalreadyexists = 0; // Get parameters $action = (GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view'); diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index ccde48cade00a..bd2d74a326a40 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -873,6 +873,11 @@ class Societe extends CommonObject */ public $bank_account; + /** + * @var int + */ + public $no_button_copy; + const STATUS_CEASED = 0; const STATUS_INACTIVITY = 1; From 0113a022dae10cc026ad3193d23b2ad5a57cdd44 Mon Sep 17 00:00:00 2001 From: tnegre Date: Wed, 18 Sep 2024 12:27:46 +0200 Subject: [PATCH 21/23] fix travis (hopefully) --- htdocs/product/class/product.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index f7401806fc1db..9844ebd9de0e6 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2843,8 +2843,8 @@ public function fetch($id = 0, $ref = '', $ref_ext = '', $barcode = '', $ignore_ } else { $sql .= " p.pmp,"; } - $sql .= " p.datec, p.tms, p.import_key, p.entity, p.desiredstock, p.tobatch, p.batch_mask, p.fk_unit,"; - $sql .= " p.fk_price_expression, p.price_autogen, p.stockable_product,p.model_pdf,"; + $sql .= " p.datec, p.tms, p.import_key, p.entity, p.desiredstock, p.tobatch, p.sell_or_eat_by_mandatory, p.batch_mask, p.fk_unit,"; + $sql .= " p.fk_price_expression, p.price_autogen, p.stockable_product, p.model_pdf,"; $sql .= " p.price_label,"; if ($separatedStock) { $sql .= " SUM(sp.reel) as stock"; From 151692f3de12ebc22765a304cca9f8d7f994108a Mon Sep 17 00:00:00 2001 From: tnegre Date: Mon, 23 Sep 2024 11:32:57 +0200 Subject: [PATCH 22/23] remove useless lines --- htdocs/product/class/product.class.php | 5 ----- htdocs/societe/class/societe.class.php | 5 ----- 2 files changed, 10 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 9844ebd9de0e6..8205bd989e739 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -767,11 +767,6 @@ class Product extends CommonObject */ public $mandatory_period; - /** - * @var int - */ - public $no_button_copy; - /** * 0=This service or product is not managed in stock, 1=This service or product is managed in stock * diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index bd2d74a326a40..ccde48cade00a 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -873,11 +873,6 @@ class Societe extends CommonObject */ public $bank_account; - /** - * @var int - */ - public $no_button_copy; - const STATUS_CEASED = 0; const STATUS_INACTIVITY = 1; From 3b5a5f99554427f3e44dfc56c7a6494377cc242e Mon Sep 17 00:00:00 2001 From: tnegre Date: Fri, 4 Oct 2024 12:21:12 +0200 Subject: [PATCH 23/23] relaunch tests