} if (!$error) { if ($id) { $product = new Product($db); $result = $product->fetch($id); $db->begin(); $product->load_stock(); // Load array product->stock_warehouse // Define value of products moved $pricesrc = 0; //if (isset($product->stock_warehouse[GETPOST("id_entrepot_source")]->pmp)) $pricesrc=$product->stock_warehouse[GETPOST("id_entrepot_source")]->pmp; if (isset($product->pmp)) { $pricesrc = $product->pmp; } $pricedest = $pricesrc; if ($product->hasbatch()) { $pdluo = new Productbatch($db); if ($pdluoid > 0) { $result = $pdluo->fetch($pdluoid); if ($result) { $srcwarehouseid = $pdluo->warehouseid; $batch = $pdluo->batch; $eatby = $pdluo->eatby; $sellby = $pdluo->sellby; } else { setEventMessages($pdluo->error, $pdluo->errors, 'errors'); $error++; } } else { $srcwarehouseid = GETPOST('id_entrepot_source', 'int'); $batch = GETPOST('batch_number');
print '<input name="qtydelivered' . $indiceAsked . '" id="qtydelivered' . $indiceAsked . '" type="hidden" value="' . $quantityDelivered . '">'; print '</td>'; $quantityAsked = $line->qty; if ($line->product_type == 1 && empty($conf->global->STOCK_SUPPORTS_SERVICES)) { $quantityToBeDelivered = 0; } else { $quantityToBeDelivered = $quantityAsked - $quantityDelivered; } $warehouse_id = GETPOST('entrepot_id', 'int'); $warehouseObject = null; if ($warehouse_id > 0 || !($line->fk_product > 0)) { //ship from preselected location $stock = +$product->stock_warehouse[$warehouse_id]->real; // Convert to number $deliverableQty = min($quantityToBeDelivered, $stock); if (empty($conf->productbatch->enabled) || !($product->hasbatch() && is_object($product->stock_warehouse[$warehouse_id]))) { // Quantity to send print '<td align="center">'; if ($line->product_type == 0 || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { print '<input name="idl' . $indiceAsked . '" type="hidden" value="' . $line->id . '">'; print '<input name="qtyl' . $indiceAsked . '" id="qtyl' . $indiceAsked . '" type="text" size="4" value="' . $deliverableQty . '">'; } else { print $langs->trans("NA"); } print '</td>'; // Stock if (!empty($conf->stock->enabled)) { print '<td align="left">'; if ($line->product_type == 0 || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { // Show warehouse combo list $ent = "entl" . $indiceAsked;
/** * Add a movement of stock (in one direction only) * * @param User $user User object * @param int $fk_product Id of product * @param int $entrepot_id Id of warehouse * @param int $qty Qty of movement (can be <0 or >0 depending on parameter type) * @param int $type Direction of movement: * 0=input (stock increase after stock transfert), 1=output (stock decrease after stock transfer), * 2=output (stock decrease), 3=input (stock increase) * Note that qty should be > 0 with 0 or 3, < 0 with 1 or 2. * @param int $price Unit price HT of product, used to calculate average weighted price (PMP in french). If 0, average weighted price is not changed. * @param string $label Label of stock movement * @param string $inventorycode Inventory code * @param string $datem Force date of movement * @param date $eatby eat-by date * @param date $sellby sell-by date * @param string $batch batch number * @param boolean $skip_batch If set to true, stock movement is done without impacting batch record * @return int <0 if KO, 0 if fk_product is null, >0 if OK */ function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = 0, $label = '', $inventorycode = '', $datem = '', $eatby = '', $sellby = '', $batch = '', $skip_batch = false) { global $conf, $langs; require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; $error = 0; dol_syslog(get_class($this) . "::_create start userid={$user->id}, fk_product={$fk_product}, warehouse={$entrepot_id}, qty={$qty}, type={$type}, price={$price}, label={$label}, inventorycode={$inventorycode}, datem=" . $datem . ", eatby=" . $eatby . ", sellby=" . $sellby . ", batch=" . $batch . ", skip_batch=" . $skip_batch); // Clean parameters if (empty($price)) { $price = 0; } $now = !empty($datem) ? $datem : dol_now(); // Check parameters if (empty($fk_product)) { return 0; } if ($eatby < 0) { $this->errors[] = 'ErrorBadValueForParameterEatBy'; return -1; } if ($sellby < 0) { $this->errors[] = 'ErrorBadValueForParameterEatBy'; return -1; } // Set properties of movement $this->product_id = $fk_product; $this->entrepot_id = $entrepot_id; $this->qty = $qty; $this->type = $type; $mvid = 0; $product = new Product($this->db); $result = $product->fetch($fk_product); if ($result < 0) { dol_print_error('', "Failed to fetch product"); return -1; } $this->db->begin(); $product->load_stock(); // Test if product require batch data. If yes, and there is not, we throw an error. if (!empty($conf->productbatch->enabled) && $product->hasbatch() && !$skip_batch) { //if (empty($batch) && empty($eatby) && empty($sellby)) if (empty($batch)) { $this->errors[] = $langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $product->name); dol_syslog("Try to make a movement of a product with status_batch on without any batch data"); $this->db->rollback(); return -2; } // If a serial number is provided, we check that sellby and eatby match already existing serial $sql = "SELECT pb.rowid, pb.batch, pb.eatby, pb.sellby FROM " . MAIN_DB_PREFIX . "product_batch as pb, " . MAIN_DB_PREFIX . "product_stock as ps"; $sql .= " WHERE pb.fk_product_stock = ps.rowid AND ps.fk_product = " . $fk_product . " AND pb.batch = '" . $this->db->escape($batch) . "'"; dol_syslog(get_class($this) . "::_create scan serial for this product to check if eatby and sellby match", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); $i = 0; while ($i < $num) { $obj = $this->db->fetch_object($resql); if ($this->db->jdate($obj->eatby) != $eatby) { $this->errors[] = $langs->trans("ThisSerialAlreadyExistWithDifferentDate", $batch, $this->db->jdate($obj->eatby), $eatby); dol_syslog($langs->trans("ThisSerialAlreadyExistWithDifferentDate", $batch, $this->db->jdate($obj->eatby), $eatby)); $this->db->rollback(); return -3; } if ($this->db->jdate($obj->sellby) != $sellby) { $this->errors[] = $langs->trans("ThisSerialAlreadyExistWithDifferentDate", $batch, $this->db->jdate($obj->sellby), $sellby); dol_syslog($langs->trans("ThisSerialAlreadyExistWithDifferentDate", $batch, $this->db->jdate($obj->sellby), $sellby)); $this->db->rollback(); return -3; } $i++; } } else { dol_print_error($this->db); $this->db->rollback(); return -1; } } // TODO Check qty is ok for stock move. if (!empty($conf->productbatch->enabled) && $product->hasbatch() && !$skip_batch) { } else { } // Define if we must make the stock change (If product type is a service or if stock is used also for services) $movestock = 0; if ($product->type != Product::TYPE_SERVICE || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { $movestock = 1; } if ($movestock && $entrepot_id > 0) { if (!empty($this->origin)) { // This is set by caller for tracking reason $origintype = $this->origin->element; $fk_origin = $this->origin->id; } else { $origintype = ''; $fk_origin = 0; } $sql = "INSERT INTO " . MAIN_DB_PREFIX . "stock_mouvement("; $sql .= " datem, fk_product, batch, eatby, sellby,"; $sql .= " fk_entrepot, value, type_mouvement, fk_user_author, label, inventorycode, price, fk_origin, origintype"; $sql .= ")"; $sql .= " VALUES ('" . $this->db->idate($now) . "', " . $this->product_id . ", "; $sql .= " " . ($batch ? "'" . $batch . "'" : "null") . ", "; $sql .= " " . ($eatby ? "'" . $this->db->idate($eatby) . "'" : "null") . ", "; $sql .= " " . ($sellby ? "'" . $this->db->idate($sellby) . "'" : "null") . ", "; $sql .= " " . $this->entrepot_id . ", " . $this->qty . ", " . $this->type . ","; $sql .= " " . $user->id . ","; $sql .= " '" . $this->db->escape($label) . "',"; $sql .= " " . ($inventorycode ? "'" . $this->db->escape($inventorycode) . "'" : "null") . ","; $sql .= " '" . price2num($price) . "',"; $sql .= " '" . $fk_origin . "',"; $sql .= " '" . $origintype . "'"; $sql .= ")"; dol_syslog(get_class($this) . "::_create", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { $mvid = $this->db->last_insert_id(MAIN_DB_PREFIX . "stock_mouvement"); $this->id = $mvid; } else { $this->errors[] = $this->db->lasterror(); $error = -1; } // Define current values for qty and pmp $oldqty = $product->stock_reel; $oldpmp = $product->pmp; $oldqtywarehouse = 0; //$oldpmpwarehouse=0; // Test if there is already a record for couple (warehouse / product) $num = 0; if (!$error) { $sql = "SELECT rowid, reel FROM " . MAIN_DB_PREFIX . "product_stock"; $sql .= " WHERE fk_entrepot = " . $entrepot_id . " AND fk_product = " . $fk_product; // This is a unique key dol_syslog(get_class($this) . "::_create", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { $obj = $this->db->fetch_object($resql); if ($obj) { $num = 1; $oldqtywarehouse = $obj->reel; //$oldpmpwarehouse = $obj->pmp; $fk_product_stock = $obj->rowid; } $this->db->free($resql); } else { $this->errors[] = $this->db->lasterror(); $error = -2; } } // Calculate new PMP. $newpmp = 0; //$newpmpwarehouse=0; if (!$error) { // Note: PMP is calculated on stock input only (type of movement = 0 or 3). If type == 0 or 3, qty should be > 0. // Note: Price should always be >0 or 0. PMP should be always >0 (calculated on input) if (($type == 0 || $type == 3) && $price > 0) { // If we will change PMP for the warehouse we edit and the product, we must first check/clean that PMP is defined // on every stock entry with old value (so global updated value will match recalculated value from product_stock) /* $sql = "UPDATE ".MAIN_DB_PREFIX."product_stock SET pmp = ".($oldpmp?$oldpmp:'0'); $sql.= " WHERE pmp = 0 AND fk_product = ".$fk_product; dol_syslog(get_class($this)."::_create", LOG_DEBUG); $resql=$this->db->query($sql); if (! $resql) { $this->errors[]=$this->db->lasterror(); $error = -4; } */ $oldqtytouse = $oldqty >= 0 ? $oldqty : 0; // We make a test on oldpmp>0 to avoid to use normal rule on old data with no pmp field defined if ($oldpmp > 0) { $newpmp = price2num(($oldqtytouse * $oldpmp + $qty * $price) / ($oldqtytouse + $qty), 'MU'); } else { $newpmp = $price; // For this product, PMP was not yet set. We set it to input price. } /* $oldqtywarehousetouse=$oldqtywarehouse; if ($oldpmpwarehouse > 0) $newpmpwarehouse=price2num((($oldqtywarehousetouse * $oldpmpwarehouse) + ($qty * $price)) / ($oldqtywarehousetouse + $qty), 'MU'); else $newpmpwarehouse=$price; */ //print "oldqtytouse=".$oldqtytouse." oldpmp=".$oldpmp." oldqtywarehousetouse=".$oldqtywarehousetouse." oldpmpwarehouse=".$oldpmpwarehouse." "; //print "qty=".$qty." newpmp=".$newpmp." newpmpwarehouse=".$newpmpwarehouse; //exit; } else { if ($type == 1 || $type == 2) { // After a stock decrease, we don't change value of PMP for product. $newpmp = $oldpmp; } else { $newpmp = $oldpmp; //$newpmpwarehouse = $oldpmpwarehouse; } } } // Update stock quantity if (!$error) { if ($num > 0) { //$sql = "UPDATE ".MAIN_DB_PREFIX."product_stock SET pmp = ".$newpmpwarehouse.", reel = reel + ".$qty; $sql = "UPDATE " . MAIN_DB_PREFIX . "product_stock SET reel = reel + " . $qty; $sql .= " WHERE fk_entrepot = " . $entrepot_id . " AND fk_product = " . $fk_product; } else { $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_stock"; //$sql.= " (pmp, reel, fk_entrepot, fk_product) VALUES "; //$sql.= " (".$newpmpwarehouse.", ".$qty.", ".$entrepot_id.", ".$fk_product.")"; $sql .= " (reel, fk_entrepot, fk_product) VALUES "; $sql .= " (" . $qty . ", " . $entrepot_id . ", " . $fk_product . ")"; } dol_syslog(get_class($this) . "::_create", LOG_DEBUG); $resql = $this->db->query($sql); if (!$resql) { $this->errors[] = $this->db->lasterror(); $error = -3; } else { if (empty($fk_product_stock)) { $fk_product_stock = $this->db->last_insert_id(MAIN_DB_PREFIX . "product_stock"); } } } // Update detail stock for batch product if (!$error && !empty($conf->productbatch->enabled) && $product->hasbatch() && !$skip_batch) { $param_batch = array('fk_product_stock' => $fk_product_stock, 'eatby' => $eatby, 'sellby' => $sellby, 'batchnumber' => $batch); $result = $this->_create_batch($param_batch, $qty); if ($result < 0) { $error++; } } // Update PMP and denormalized value of stock qty at product level if (!$error) { $sql = "UPDATE " . MAIN_DB_PREFIX . "product SET pmp = " . $newpmp . ", stock = " . $this->db->ifsql("stock IS NULL", 0, "stock") . " + " . $qty; $sql .= " WHERE rowid = " . $fk_product; // May be this request is better: // UPDATE llx_product p SET p.stock= (SELECT SUM(ps.reel) FROM llx_product_stock ps WHERE ps.fk_product = p.rowid); dol_syslog(get_class($this) . "::_create", LOG_DEBUG); $resql = $this->db->query($sql); if (!$resql) { $this->errors[] = $this->db->lasterror(); $error = -4; } } } // Add movement for sub products (recursive call) if (!$error && !empty($conf->global->PRODUIT_SOUSPRODUITS) && empty($conf->global->INDEPENDANT_SUBPRODUCT_STOCK)) { $error = $this->_createSubProduct($user, $fk_product, $entrepot_id, $qty, $type, 0, $label, $inventorycode); // we use 0 as price, because pmp is not changed for subproduct } if ($movestock && !$error) { // Call trigger $result = $this->call_trigger('STOCK_MOVEMENT', $user); if ($result < 0) { $error++; } // End call triggers } if (!$error) { $this->db->commit(); return $mvid; } else { $this->db->rollback(); dol_syslog(get_class($this) . "::_create error code=" . $error, LOG_ERR); return -6; } }
} if (!$error) { if ($id) { $object = new Product($db); $result = $object->fetch($id); $db->begin(); $object->load_stock(); // Load array product->stock_warehouse // Define value of products moved $pricesrc = 0; //if (isset($object->stock_warehouse[GETPOST("id_entrepot_source")]->pmp)) $pricesrc=$object->stock_warehouse[GETPOST("id_entrepot_source")]->pmp; if (isset($object->pmp)) { $pricesrc = $object->pmp; } $pricedest = $pricesrc; if ($object->hasbatch()) { $pdluo = new Productbatch($db); if ($pdluoid > 0) { $result = $pdluo->fetch($pdluoid); if ($result) { $srcwarehouseid = $pdluo->warehouseid; $batch = $pdluo->batch; $eatby = $pdluo->eatby; $sellby = $pdluo->sellby; } else { setEventMessages($pdluo->error, $pdluo->errors, 'errors'); $error++; } } else { $srcwarehouseid = GETPOST('id_entrepot_source', 'int'); $batch = GETPOST('batch_number');
/** * Add a movement of stock (in one direction only) * * @param User $user User object * @param int $fk_product Id of product * @param int $entrepot_id Id of warehouse * @param int $qty Qty of movement (can be <0 or >0) * @param int $type Direction of movement: * 0=input (stock increase after stock transfert), 1=output (stock decrease after stock transfer), * 2=output (stock decrease), 3=input (stock increase) * @param int $price Unit price HT of product, used to calculate average weighted price (PMP in french). If 0, average weighted price is not changed. * @param string $label Label of stock movement * @param string $datem Force date of movement * @param date $eatby eat-by date * @param date $sellby sell-by date * @param string $batch batch number * @param boolean $skip_sellby If set to true, stock mouvement is done without impacting batch record * @return int <0 if KO, 0 if fk_product is null, >0 if OK */ function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = 0, $label = '', $datem = '', $eatby = '', $sellby = '', $batch = '', $skip_sellby = false) { global $conf, $langs; require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; $error = 0; dol_syslog(get_class($this) . "::_create start userid={$user->id}, fk_product={$fk_product}, warehouse={$entrepot_id}, qty={$qty}, type={$type}, price={$price} label={$label}"); // Clean parameters if (empty($price)) { $price = 0; } if (empty($fk_product)) { return 0; } $now = !empty($datem) ? $datem : dol_now(); $this->db->begin(); $product = new Product($this->db); $result = $product->fetch_opt($fk_product); if ($result < 0) { dol_print_error('', "Failed to fetch product"); return -1; } $product->load_stock(); // Define if we must make the stock change (If product type is a service or if stock is used also for services) $movestock = 0; if ($product->type != 1 || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { $movestock = 1; } if ($movestock && $entrepot_id > 0) { if (!empty($this->origin)) { $origintype = $this->origin->element; $fk_origin = $this->origin->id; } else { $origintype = ''; $fk_origin = 0; } $sql = "INSERT INTO " . MAIN_DB_PREFIX . "stock_mouvement"; $sql .= " (datem, fk_product, fk_entrepot, value, type_mouvement, fk_user_author, label, price, fk_origin, origintype)"; $sql .= " VALUES ('" . $this->db->idate($now) . "', " . $fk_product . ", " . $entrepot_id . ", " . $qty . ", " . $type . ","; $sql .= " " . $user->id . ","; $sql .= " '" . $this->db->escape($label) . "',"; $sql .= " '" . price2num($price) . "',"; $sql .= " '" . $fk_origin . "',"; $sql .= " '" . $origintype . "'"; $sql .= ")"; dol_syslog(get_class($this) . "::_create sql=" . $sql, LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { $mvid = $this->db->last_insert_id(MAIN_DB_PREFIX . "stock_mouvement"); } else { $this->error = $this->db->lasterror(); dol_syslog(get_class($this) . "::_create " . $this->error, LOG_ERR); $error = -1; } // Define current values for qty and pmp $oldqty = $product->stock_reel; $oldqtywarehouse = 0; $oldpmp = $product->pmp; $oldpmpwarehouse = 0; // Test if there is already a record for couple (warehouse / product) $num = 0; if (!$error) { $sql = "SELECT rowid, reel, pmp FROM " . MAIN_DB_PREFIX . "product_stock"; $sql .= " WHERE fk_entrepot = " . $entrepot_id . " AND fk_product = " . $fk_product; dol_syslog(get_class($this) . "::_create sql=" . $sql); $resql = $this->db->query($sql); if ($resql) { $obj = $this->db->fetch_object($resql); if ($obj) { $num = 1; $oldqtywarehouse = $obj->reel; $oldpmpwarehouse = $obj->pmp; $fk_product_stock = $obj->rowid; } $this->db->free($resql); } else { $this->error = $this->db->lasterror(); dol_syslog(get_class($this) . "::_create echec update " . $this->error, LOG_ERR); $error = -2; } } // Calculate new PMP. if (!$error) { $newpmp = 0; $newpmpwarehouse = 0; // Note: PMP is calculated on stock input only (type = 0 or 3). If type == 0 or 3, qty should be > 0. // Note: Price should always be >0 or 0. PMP should be always >0 (calculated on input) if (($type == 0 || $type == 3) && $price > 0) { $oldqtytouse = $oldqty >= 0 ? $oldqty : 0; // We make a test on oldpmp>0 to avoid to use normal rule on old data with no pmp field defined if ($oldpmp > 0) { $newpmp = price2num(($oldqtytouse * $oldpmp + $qty * $price) / ($oldqtytouse + $qty), 'MU'); } else { $newpmp = $price; } $oldqtywarehousetouse = $oldqtywarehouse >= 0 ? $oldqtywarehouse : 0; if ($oldpmpwarehouse > 0) { $newpmpwarehouse = price2num(($oldqtywarehousetouse * $oldpmpwarehouse + $qty * $price) / ($oldqtywarehousetouse + $qty), 'MU'); } else { $newpmpwarehouse = $price; } //print "oldqtytouse=".$oldqtytouse." oldpmp=".$oldpmp." oldqtywarehousetouse=".$oldqtywarehousetouse." oldpmpwarehouse=".$oldpmpwarehouse." "; //print "qty=".$qty." newpmp=".$newpmp." newpmpwarehouse=".$newpmpwarehouse; //exit; } else { $newpmp = $oldpmp; $newpmpwarehouse = $oldpmpwarehouse; } } // Update denormalized value of stock in product_stock and product if (!$error) { if ($num > 0) { $sql = "UPDATE " . MAIN_DB_PREFIX . "product_stock SET pmp = " . $newpmpwarehouse . ", reel = reel + " . $qty; $sql .= " WHERE fk_entrepot = " . $entrepot_id . " AND fk_product = " . $fk_product; } else { $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_stock"; $sql .= " (pmp, reel, fk_entrepot, fk_product) VALUES "; $sql .= " (" . $newpmpwarehouse . ", " . $qty . ", " . $entrepot_id . ", " . $fk_product . ")"; } dol_syslog(get_class($this) . "::_create sql=" . $sql); $resql = $this->db->query($sql); if (!$resql) { $this->error = $this->db->lasterror(); dol_syslog(get_class($this) . "::_create " . $this->error, LOG_ERR); $error = -3; } else { if (empty($fk_product_stock)) { $fk_product_stock = $this->db->last_insert_id(MAIN_DB_PREFIX . "product_stock"); } } } // Update detail stock for sell-by date if ($product->hasbatch() && !$error && !$skip_sellby) { $param_batch = array('fk_product_stock' => $fk_product_stock, 'eatby' => $eatby, 'sellby' => $sellby, 'batchnumber' => $batch); $result = $this->_create_batch($param_batch, $qty); if ($result < 0) { $error++; } } if (!$error) { $sql = "UPDATE " . MAIN_DB_PREFIX . "product SET pmp = " . $newpmp . ", stock = " . $this->db->ifsql("stock IS NULL", 0, "stock") . " + " . $qty; $sql .= " WHERE rowid = " . $fk_product; // May be this request is better: // UPDATE llx_product p SET p.stock= (SELECT SUM(ps.reel) FROM llx_product_stock ps WHERE ps.fk_product = p.rowid); dol_syslog(get_class($this) . "::_create sql=" . $sql); $resql = $this->db->query($sql); if (!$resql) { $this->error = $this->db->lasterror(); dol_syslog(get_class($this) . "::_create " . $this->error, LOG_ERR); $error = -4; } } } // Add movement for sub products (recursive call) if (!$error && !empty($conf->global->PRODUIT_SOUSPRODUITS)) { $error = $this->_createSubProduct($user, $fk_product, $entrepot_id, $qty, $type, 0, $label); // we use 0 as price, because pmp is not changed for subproduct } if ($movestock && !$error) { // Appel des triggers include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; $interface = new Interfaces($this->db); $this->product_id = $fk_product; $this->entrepot_id = $entrepot_id; $this->qty = $qty; $result = $interface->run_triggers('STOCK_MOVEMENT', $this, $user, $langs, $conf); if ($result < 0) { $error++; $this->errors = $interface->errors; } // Fin appel triggers } if (!$error) { $this->db->commit(); return $mvid; } else { $this->db->rollback(); dol_syslog(get_class($this) . "::_create error code=" . $error, LOG_ERR); return -6; } }
$dlc = -1; // They are loaded later from serial $dluo = -1; // They are loaded later from serial if (!$error && $id_sw != $id_tw && is_numeric($qty) && $id_product) { $result = $product->fetch($id_product); $product->load_stock(); // Load array product->stock_warehouse // Define value of products moved $pricesrc = 0; if (!empty($product->pmp)) { $pricesrc = $product->pmp; } $pricedest = $pricesrc; //print 'price src='.$pricesrc.', price dest='.$pricedest;exit; if (empty($conf->productbatch->enabled) || !$product->hasbatch()) { // Remove stock $result1 = $product->correct_stock($user, $id_sw, $qty, 1, GETPOST("label"), $pricesrc, GETPOST("codemove")); if ($result1 < 0) { $error++; setEventMessage($product->errors, 'errors'); } // Add stock $result2 = $product->correct_stock($user, $id_tw, $qty, 0, GETPOST("label"), $pricedest, GETPOST("codemove")); if ($result2 < 0) { $error++; setEventMessage($product->errors, 'errors'); } } else { $arraybatchinfo = $product->loadBatchInfo($batch); if (count($arraybatchinfo) > 0) {
print '<input name="qtydelivered' . $indiceAsked . '" id="qtydelivered' . $indiceAsked . '" type="hidden" value="' . $quantityDelivered . '">'; print '</td>'; $quantityAsked = $line->qty; $quantityToBeDelivered = $quantityAsked - $quantityDelivered; $defaultqty = 0; if (GETPOST('entrepot_id', 'int') > 0) { //var_dump($product); $stock = $product->stock_warehouse[GETPOST('entrepot_id', 'int')]->real; $stock += 0; // Convertit en numerique $defaultqty = min($quantityToBeDelivered, $stock); if ($line->product_type == 1 && empty($conf->global->STOCK_SUPPORTS_SERVICES) || $defaultqty < 0) { $defaultqty = 0; } } if (empty($conf->productbatch->enabled) || !($product->hasbatch() and is_object($product->stock_warehouse[GETPOST('entrepot_id', 'int')]))) { // Quantity to send print '<td align="center">'; if ($line->product_type == 0 || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { print '<input name="idl' . $indiceAsked . '" type="hidden" value="' . $line->id . '">'; print '<input name="qtyl' . $indiceAsked . '" id="qtyl' . $indiceAsked . '" type="text" size="4" value="' . $defaultqty . '">'; } else { print $langs->trans("NA"); } print '</td>'; // Stock if (!empty($conf->stock->enabled)) { print '<td align="left">'; if ($line->product_type == 0 || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { // Show warehouse combo list $ent = "entl" . $indiceAsked;
$action = 'transfert'; } if (!GETPOST("nbpiece", 'int')) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NumberOfUnit")), null, 'errors'); $error++; $action = 'transfert'; } if ($id == GETPOST("id_entrepot_destination", 'int')) { setEventMessages($langs->trans("ErrorSrcAndTargetWarehouseMustDiffers"), null, 'errors'); $error++; $action = 'transfert'; } if (!empty($conf->productbatch->enabled)) { $product = new Product($db); $result = $product->fetch($product_id); if ($product->hasbatch() && !GETPOST("batch_number")) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("batch_number")), null, 'errors'); $error++; $action = 'transfert'; } } if (!$error) { if ($id) { $object = new Entrepot($db); $result = $object->fetch($id); $db->begin(); $product->load_stock(); // Load array product->stock_warehouse // Define value of products moved $pricesrc = 0; //if (isset($product->stock_warehouse[GETPOST("id_entrepot_source")]->pmp)) $pricesrc=$product->stock_warehouse[GETPOST("id_entrepot_source")]->pmp;
$dluo=-1; // They are loaded later from serial if (! $error && $id_sw <> $id_tw && is_numeric($qty) && $id_product) { $result=$product->fetch($id_product); $product->load_stock(); // Load array product->stock_warehouse // Define value of products moved $pricesrc=0; if (! empty($product->pmp)) $pricesrc=$product->pmp; $pricedest=$pricesrc; //print 'price src='.$pricesrc.', price dest='.$pricedest;exit; if (empty($conf->productbatch->enabled) || ! $product->hasbatch()) // If product does not need lot/serial { // Remove stock $result1=$product->correct_stock( $user, $id_sw, $qty, 1, GETPOST("label"), $pricesrc, GETPOST("codemove") ); if ($result1 < 0) { $error++; setEventMessages($product->errors, $product->errorss, 'errors');