mirror of
https://github.com/Dolibarr/dolibarr.git
synced 2025-02-20 13:46:52 +01:00
Fix debug creation of shipment with virtual product.
This commit is contained in:
parent
548a25b005
commit
6bbeb6d3a0
|
|
@ -2014,7 +2014,7 @@ class Commande extends CommonOrder
|
|||
$sql .= ' l.total_ht, l.total_ttc, l.total_tva, l.total_localtax1, l.total_localtax2, l.date_start, l.date_end,';
|
||||
$sql .= ' l.fk_unit,';
|
||||
$sql .= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
|
||||
$sql .= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label, p.tobatch as product_tobatch,';
|
||||
$sql .= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label, p.tosell as product_tosell, p.tobuy as product_tobuy, p.tobatch as product_tobatch,';
|
||||
$sql .= ' p.weight, p.weight_units, p.volume, p.volume_units';
|
||||
$sql .= ' FROM '.MAIN_DB_PREFIX.'commandedet as l';
|
||||
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON (p.rowid = l.fk_product)';
|
||||
|
|
@ -2077,6 +2077,8 @@ class Commande extends CommonOrder
|
|||
$line->libelle = $objp->product_label;
|
||||
$line->product_label = $objp->product_label;
|
||||
$line->product_desc = $objp->product_desc;
|
||||
$line->product_tosell = $objp->product_tosell;
|
||||
$line->product_tobuy = $objp->product_tobuy;
|
||||
$line->product_tobatch = $objp->product_tobatch;
|
||||
$line->fk_product_type = $objp->fk_product_type; // Produit ou service
|
||||
$line->fk_unit = $objp->fk_unit;
|
||||
|
|
|
|||
|
|
@ -62,6 +62,11 @@ abstract class CommonObject
|
|||
*/
|
||||
public $error;
|
||||
|
||||
/**
|
||||
* @var string Error string that is hidden but can be used to store complementatry technical code.
|
||||
*/
|
||||
public $errorhidden;
|
||||
|
||||
/**
|
||||
* @var string[] Array of error strings
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3190,7 +3190,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
|
|||
'1downarrow', '1uparrow', '1leftarrow', '1rightarrow', '1uparrow_selected', '1downarrow_selected', '1leftarrow_selected', '1rightarrow_selected',
|
||||
'accountancy', 'account', 'accountline', 'action', 'add', 'address', 'bank_account', 'barcode', 'bank', 'bill', 'bookmark', 'bom', 'building',
|
||||
'cash-register', 'category', 'check', 'clock', 'close_title', 'company', 'contact', 'contract', 'cubes',
|
||||
'delete', 'dolly', 'dollyrevert', 'donation', 'edit', 'ellipsis-h', 'email', 'external-link-alt', 'external-link-square-alt',
|
||||
'delete', 'dolly', 'dollyrevert', 'donation', 'edit', 'ellipsis-h', 'email', 'eraser', 'external-link-alt', 'external-link-square-alt',
|
||||
'filter', 'file-code', 'file-export', 'file-import', 'file-upload', 'folder', 'folder-open', 'globe', 'globe-americas', 'grip', 'grip_title', 'group',
|
||||
'help', 'holiday',
|
||||
'intervention', 'label', 'language', 'list', 'listlight', 'lot',
|
||||
|
|
|
|||
|
|
@ -90,16 +90,6 @@ function product_prepare_head($object)
|
|||
$h++;
|
||||
}
|
||||
|
||||
$head[$h][0] = DOL_URL_ROOT."/product/stats/card.php?id=".$object->id;
|
||||
$head[$h][1] = $langs->trans('Statistics');
|
||||
$head[$h][2] = 'stats';
|
||||
$h++;
|
||||
|
||||
$head[$h][0] = DOL_URL_ROOT."/product/stats/facture.php?showmessage=1&id=".$object->id;
|
||||
$head[$h][1] = $langs->trans('Referers');
|
||||
$head[$h][2] = 'referers';
|
||||
$h++;
|
||||
|
||||
if (!empty($conf->variants->enabled) && ($object->isProduct() || $object->isService())) {
|
||||
global $db;
|
||||
|
||||
|
|
@ -149,6 +139,16 @@ function product_prepare_head($object)
|
|||
}
|
||||
}
|
||||
|
||||
$head[$h][0] = DOL_URL_ROOT."/product/stats/facture.php?showmessage=1&id=".$object->id;
|
||||
$head[$h][1] = $langs->trans('Referers');
|
||||
$head[$h][2] = 'referers';
|
||||
$h++;
|
||||
|
||||
$head[$h][0] = DOL_URL_ROOT."/product/stats/card.php?id=".$object->id;
|
||||
$head[$h][1] = $langs->trans('Statistics');
|
||||
$head[$h][2] = 'stats';
|
||||
$h++;
|
||||
|
||||
// Show more tabs from modules
|
||||
// Entries must be declared in modules descriptor with line
|
||||
// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
|
||||
|
|
|
|||
|
|
@ -1047,7 +1047,7 @@ if ($action == 'create')
|
|||
$i++;
|
||||
}
|
||||
print '});
|
||||
jQuery("#autoreset").click(function() {';
|
||||
jQuery("#autoreset").click(function() { console.log("Reset values to 0"); ';
|
||||
$i = 0;
|
||||
while ($i < $numAsked)
|
||||
{
|
||||
|
|
@ -1075,12 +1075,12 @@ if ($action == 'create')
|
|||
print '<td class="center">'.$langs->trans("QtyToShip");
|
||||
if (empty($conf->productbatch->enabled))
|
||||
{
|
||||
print '<br><a href="#" id="autofill">'.$langs->trans("Fill").'</a>';
|
||||
print '<br><a href="#" id="autofill" class="opacitymedium link cursor cursorpointer">'.$langs->trans("Fill").'</a>';
|
||||
print ' / ';
|
||||
} else {
|
||||
print '<br>';
|
||||
}
|
||||
print '<a href="#" id="autoreset">'.$langs->trans("Reset").'</a>';
|
||||
print '<span id="autoreset" class="opacitymedium link cursor cursorpointer">'.img_picto($langs->trans("Reset"), 'eraser').'</span>';
|
||||
print '</td>';
|
||||
if (!empty($conf->stock->enabled))
|
||||
{
|
||||
|
|
@ -1114,7 +1114,7 @@ if ($action == 'create')
|
|||
if (!empty($line->date_start)) $type = 1;
|
||||
if (!empty($line->date_end)) $type = 1;
|
||||
|
||||
print '<!-- line '.$line->rowid.' for product -->'."\n";
|
||||
print '<!-- line '.$line->id.' for product -->'."\n";
|
||||
print '<tr class="oddeven">'."\n";
|
||||
|
||||
// Product label
|
||||
|
|
@ -1125,13 +1125,16 @@ if ($action == 'create')
|
|||
//var_dump($product->stock_warehouse[1]);
|
||||
|
||||
print '<td>';
|
||||
print '<a name="'.$line->rowid.'"></a>'; // ancre pour retourner sur la ligne
|
||||
print '<a name="'.$line->id.'"></a>'; // ancre pour retourner sur la ligne
|
||||
|
||||
// Show product and description
|
||||
$product_static->type = $line->fk_product_type;
|
||||
$product_static->id = $line->fk_product;
|
||||
$product_static->ref = $line->ref;
|
||||
$product_static->status = $line->product_tosell;
|
||||
$product_static->status_buy = $line->product_tobuy;
|
||||
$product_static->status_batch = $line->product_tobatch;
|
||||
|
||||
$text = $product_static->getNomUrl(1);
|
||||
$text .= ' - '.(!empty($line->label) ? $line->label : $line->product_label);
|
||||
$description = ($conf->global->PRODUIT_DESC_IN_FORM ? '' : dol_htmlentitiesbr($line->desc));
|
||||
|
|
@ -2048,7 +2051,7 @@ if ($action == 'create')
|
|||
$sql .= ", ed.rowid as shipmentline_id, ed.qty as qty_shipped, ed.fk_expedition as expedition_id, ed.fk_origin_line, ed.fk_entrepot";
|
||||
$sql .= ", e.rowid as shipment_id, e.ref as shipment_ref, e.date_creation, e.date_valid, e.date_delivery, e.date_expedition";
|
||||
//if ($conf->delivery_note->enabled) $sql .= ", l.rowid as livraison_id, l.ref as livraison_ref, l.date_delivery, ld.qty as qty_received";
|
||||
$sql .= ', p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.tobatch as product_tobatch';
|
||||
$sql .= ', p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.tosell as product_tosell, p.tobuy as product_tobuy, p.tobatch as product_tobatch';
|
||||
$sql .= ', p.description as product_desc';
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."expeditiondet as ed";
|
||||
$sql .= ", ".MAIN_DB_PREFIX."expedition as e";
|
||||
|
|
@ -2075,7 +2078,10 @@ if ($action == 'create')
|
|||
if ($obj)
|
||||
{
|
||||
// $obj->rowid is rowid in $origin."det" table
|
||||
$alreadysent[$obj->rowid][$obj->shipmentline_id] = array('shipment_ref'=>$obj->shipment_ref, 'shipment_id'=>$obj->shipment_id, 'warehouse'=>$obj->fk_entrepot, 'qty_shipped'=>$obj->qty_shipped, 'date_valid'=>$db->jdate($obj->date_valid), 'date_delivery'=>$db->jdate($obj->date_delivery));
|
||||
$alreadysent[$obj->rowid][$obj->shipmentline_id] = array(
|
||||
'shipment_ref'=>$obj->shipment_ref, 'shipment_id'=>$obj->shipment_id, 'warehouse'=>$obj->fk_entrepot, 'qty_shipped'=>$obj->qty_shipped,
|
||||
'product_tosell'=>$obj->product_tosell, 'product_tobuy'=>$obj->product_tobuy, 'product_tobatch'=>$obj->product_tobatch,
|
||||
'date_valid'=>$db->jdate($obj->date_valid), 'date_delivery'=>$db->jdate($obj->date_delivery));
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
|
@ -2084,6 +2090,7 @@ if ($action == 'create')
|
|||
}
|
||||
|
||||
print '<tbody>';
|
||||
|
||||
// Loop on each product to send/sent
|
||||
for ($i = 0; $i < $num_prod; $i++)
|
||||
{
|
||||
|
|
@ -2119,6 +2126,8 @@ if ($action == 'create')
|
|||
$product_static->type = $lines[$i]->fk_product_type;
|
||||
$product_static->id = $lines[$i]->fk_product;
|
||||
$product_static->ref = $lines[$i]->ref;
|
||||
$product_static->status = $lines[$i]->product_tosell;
|
||||
$product_static->status_buy = $lines[$i]->product_tobuy;
|
||||
$product_static->status_batch = $lines[$i]->product_tobatch;
|
||||
|
||||
$product_static->weight = $lines[$i]->weight;
|
||||
|
|
|
|||
|
|
@ -619,10 +619,8 @@ class Expedition extends CommonObject
|
|||
// Tracking url
|
||||
$this->getUrlTrackingStatus($obj->tracking_number);
|
||||
|
||||
/*
|
||||
* Thirdparty
|
||||
*/
|
||||
$result = $this->fetch_thirdparty();
|
||||
// Thirdparty
|
||||
$result = $this->fetch_thirdparty(); // TODO Remove this
|
||||
|
||||
// Retrieve extrafields
|
||||
$this->fetch_optionals();
|
||||
|
|
@ -919,6 +917,7 @@ class Expedition extends CommonObject
|
|||
|
||||
$line->entrepot_id = $entrepot_id;
|
||||
$line->origin_line_id = $id;
|
||||
$line->fk_origin_line = $id;
|
||||
$line->qty = $qty;
|
||||
|
||||
$orderline = new OrderLine($this->db);
|
||||
|
|
@ -931,31 +930,37 @@ class Expedition extends CommonObject
|
|||
{
|
||||
$fk_product = $orderline->fk_product;
|
||||
|
||||
if (!($entrepot_id > 0) && empty($conf->global->STOCK_WAREHOUSE_NOT_REQUIRED_FOR_SHIPMENTS))
|
||||
{
|
||||
if (!($entrepot_id > 0) && empty($conf->global->STOCK_WAREHOUSE_NOT_REQUIRED_FOR_SHIPMENTS)) {
|
||||
$langs->load("errors");
|
||||
$this->error = $langs->trans("ErrorWarehouseRequiredIntoShipmentLine");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ($conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT)
|
||||
{
|
||||
// Check must be done for stock of product into warehouse if $entrepot_id defined
|
||||
if ($conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT) {
|
||||
$product = new Product($this->db);
|
||||
$result = $product->fetch($fk_product);
|
||||
$product->fetch($fk_product);
|
||||
|
||||
// Check must be done for stock of product into warehouse if $entrepot_id defined
|
||||
if ($entrepot_id > 0) {
|
||||
$product->load_stock('warehouseopen');
|
||||
$product_stock = $product->stock_warehouse[$entrepot_id]->real;
|
||||
} else $product_stock = $product->stock_reel;
|
||||
} else {
|
||||
$product_stock = $product->stock_reel;
|
||||
}
|
||||
|
||||
$product_type = $product->type;
|
||||
if ($product_type == 0 && $product_stock < $qty)
|
||||
{
|
||||
$langs->load("errors");
|
||||
$this->error = $langs->trans('ErrorStockIsNotEnoughToAddProductOnShipment', $product->ref);
|
||||
$this->db->rollback();
|
||||
return -3;
|
||||
if ($product_type == 0 || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
|
||||
$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 || empty($conf->global->PRODUIT_SOUSPRODUITS) || ($isavirtualproduct && empty($conf->global->STOCK_EXCLUDE_VIRTUAL_PRODUCTS))) { // If STOCK_EXCLUDE_VIRTUAL_PRODUCTS is set, we do not manage stock for kits/virtual products.
|
||||
if ($product_stock < $qty) {
|
||||
$langs->load("errors");
|
||||
$this->error = $langs->trans('ErrorStockIsNotEnoughToAddProductOnShipment', $product->ref);
|
||||
$this->errorhidden = 'ErrorStockIsNotEnoughToAddProductOnShipment';
|
||||
$this->db->rollback();
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1576,7 +1581,7 @@ class Expedition extends CommonObject
|
|||
$sql .= ", cd.fk_multicurrency, cd.multicurrency_code, cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc, cd.rang";
|
||||
$sql .= ", ed.rowid as line_id, ed.qty as qty_shipped, ed.fk_origin_line, ed.fk_entrepot";
|
||||
$sql .= ", p.ref as product_ref, p.label as product_label, p.fk_product_type";
|
||||
$sql .= ", p.weight, p.weight_units, p.length, p.length_units, p.surface, p.surface_units, p.volume, p.volume_units, p.tobatch as product_tobatch";
|
||||
$sql .= ", p.weight, p.weight_units, p.length, p.length_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 .= " 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 = ".$this->id;
|
||||
|
|
@ -1638,6 +1643,8 @@ class Expedition extends CommonObject
|
|||
$line->product_ref = $obj->product_ref;
|
||||
$line->product_label = $obj->product_label;
|
||||
$line->libelle = $obj->product_label; // TODO deprecated
|
||||
$line->product_tosell = $obj->product_tosell;
|
||||
$line->product_tobuy = $obj->product_tobuy;
|
||||
$line->product_tobatch = $obj->product_tobatch;
|
||||
$line->label = $obj->custom_label;
|
||||
$line->description = $obj->description;
|
||||
|
|
|
|||
|
|
@ -3807,11 +3807,11 @@ class Product extends CommonObject
|
|||
|
||||
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
||||
/**
|
||||
* Verifie si c'est un sous-produit
|
||||
* Check if it is a sub-product into a kit
|
||||
*
|
||||
* @param int $fk_parent Id du produit auquel le produit est lie
|
||||
* @param int $fk_child Id du produit lie
|
||||
* @return int < 0 si erreur, > 0 si ok
|
||||
* @param int $fk_parent Id of parent kit product
|
||||
* @param int $fk_child Id of child product
|
||||
* @return int <0 if KO, >0 if OK
|
||||
*/
|
||||
public function is_sousproduit($fk_parent, $fk_child)
|
||||
{
|
||||
|
|
@ -3827,6 +3827,7 @@ class Product extends CommonObject
|
|||
|
||||
if ($num > 0) {
|
||||
$obj = $this->db->fetch_object($result);
|
||||
|
||||
$this->is_sousproduit_qty = $obj->qty;
|
||||
$this->is_sousproduit_incdec = $obj->incdec;
|
||||
|
||||
|
|
@ -4221,17 +4222,26 @@ class Product extends CommonObject
|
|||
}
|
||||
|
||||
/**
|
||||
* Return all parent products for current product (first level only)
|
||||
* Count all parent and children products for current product (first level only)
|
||||
*
|
||||
* @return int Nb of father + child
|
||||
* @param int $mode 0=Both parent and child, -1=Parents only, 1=Children only
|
||||
* @return int Nb of father + child
|
||||
* @see getFather(), get_sousproduits_arbo()
|
||||
*/
|
||||
public function hasFatherOrChild()
|
||||
public function hasFatherOrChild($mode = 0)
|
||||
{
|
||||
$nb = 0;
|
||||
|
||||
$sql = "SELECT COUNT(pa.rowid) as nb";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."product_association as pa";
|
||||
$sql .= " WHERE pa.fk_product_fils = ".$this->id." OR pa.fk_product_pere = ".$this->id;
|
||||
if ($mode == 0) {
|
||||
$sql .= " WHERE pa.fk_product_fils = ".$this->id." OR pa.fk_product_pere = ".$this->id;
|
||||
} elseif ($mode == -1) {
|
||||
$sql .= " WHERE pa.fk_product_fils = ".$this->id; // We are a child, so we found lines that link to parents (can have several parents)
|
||||
} elseif ($mode == 1) {
|
||||
$sql .= " WHERE pa.fk_product_pere = ".$this->id; // We are a parent, so we found lines that link to children (can have several children)
|
||||
}
|
||||
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
$obj = $this->db->fetch_object($resql);
|
||||
|
|
@ -4297,6 +4307,7 @@ class Product extends CommonObject
|
|||
* Return all parent products for current product (first level only)
|
||||
*
|
||||
* @return array Array of product
|
||||
* @see hasFatherOrChild()
|
||||
*/
|
||||
public function getFather()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ if ($id > 0 || !empty($ref))
|
|||
if (!empty($search_year)) $option .= '&search_year='.urlencode($search_year);
|
||||
|
||||
print '<form method="post" action="'.$_SERVER ['PHP_SELF'].'?id='.$product->id.'" name="search_form">'."\n";
|
||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||
if (!empty($sortfield))
|
||||
print '<input type="hidden" name="sortfield" value="'.$sortfield.'"/>';
|
||||
if (!empty($sortorder))
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user