diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index dc297e9df12..29fdfbd3d96 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -3310,8 +3310,7 @@ class Propal extends CommonObject $sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code, pt.localtax1_tx, pt.localtax2_tx,'; $sql.= ' pt.date_start, pt.date_end, pt.product_type, pt.rang, pt.fk_parent_line,'; $sql.= ' pt.fk_unit,'; - $sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid,'; - $sql.= ' p.description as product_desc,'; + $sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.description as product_desc, p.tobatch as product_tobatch,'; $sql.= ' p.entity,'; $sql.= ' pt.fk_multicurrency, pt.multicurrency_code, pt.multicurrency_subprice, pt.multicurrency_total_ht, pt.multicurrency_total_tva, pt.multicurrency_total_ttc'; $sql.= ' FROM '.MAIN_DB_PREFIX.'propaldet as pt'; @@ -3342,6 +3341,7 @@ class Propal extends CommonObject $this->lines[$i]->entity = $obj->entity; // Product entity $this->lines[$i]->product_label = $obj->product_label; $this->lines[$i]->product_desc = $obj->product_desc; + $this->lines[$i]->product_tobatch = $obj->product_tobatch; $this->lines[$i]->fk_product_type = $obj->fk_product_type; // deprecated $this->lines[$i]->product_type = $obj->product_type; $this->lines[$i]->qty = $obj->qty; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 0ae5ab4b217..e6423238168 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -1741,7 +1741,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,'; + $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.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)'; @@ -1801,6 +1801,7 @@ class Commande extends CommonOrder $line->libelle = $objp->product_label; $line->product_label = $objp->product_label; $line->product_desc = $objp->product_desc; + $line->product_tobatch = $objp->product_tobatch; $line->fk_product_type = $objp->fk_product_type; // Produit ou service $line->fk_unit = $objp->fk_unit; @@ -3765,7 +3766,7 @@ class OrderLine extends CommonOrderLine $sql.= ' cd.info_bits, cd.total_ht, cd.total_tva, cd.total_localtax1, cd.total_localtax2, cd.total_ttc, cd.fk_product_fournisseur_price as fk_fournprice, cd.buy_price_ht as pa_ht, cd.rang, cd.special_code,'; $sql.= ' cd.fk_unit,'; $sql.= ' cd.fk_multicurrency, cd.multicurrency_code, cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc,'; - $sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc,'; + $sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc, p.tobatch as product_tobatch,'; $sql.= ' cd.date_start, cd.date_end'; $sql.= ' FROM '.MAIN_DB_PREFIX.'commandedet as cd'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid'; @@ -3810,7 +3811,8 @@ class OrderLine extends CommonOrderLine $this->libelle = $objp->product_libelle; // deprecated $this->product_label = $objp->product_libelle; $this->product_desc = $objp->product_desc; - $this->fk_unit = $objp->fk_unit; + $this->product_tobatch = $objp->product_tobatch; + $this->fk_unit = $objp->fk_unit; $this->date_start = $this->db->jdate($objp->date_start); $this->date_end = $this->db->jdate($objp->date_end); @@ -3828,6 +3830,7 @@ class OrderLine extends CommonOrderLine } else { + $this->error = $this->db->lasterror(); return -1; } } diff --git a/htdocs/core/lib/sendings.lib.php b/htdocs/core/lib/sendings.lib.php index 2a22e3a7383..d81b636633f 100644 --- a/htdocs/core/lib/sendings.lib.php +++ b/htdocs/core/lib/sendings.lib.php @@ -176,7 +176,7 @@ function show_list_sending_receive($origin,$origin_id,$filter='') $sql.= ", ed.qty as qty_shipped, ed.fk_expedition as expedition_id, ed.fk_origin_line, ed.fk_entrepot as warehouse_id"; $sql.= ", e.rowid as sendingid, e.ref as exp_ref, e.date_creation, e.date_delivery, e.date_expedition,"; //if ($conf->livraison_bon->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,'; + $sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, 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"; @@ -270,6 +270,7 @@ function show_list_sending_receive($origin,$origin_id,$filter='') $product_static->type=$objp->fk_product_type; $product_static->id=$objp->fk_product; $product_static->ref=$objp->ref; + $product_static->status_batch=$objp->product_tobatch; $text=$product_static->getNomUrl(1); $text.= ' - '.$label; $description=(! empty($conf->global->PRODUIT_DESC_IN_FORM)?'':dol_htmlentitiesbr($objp->description)); diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index b86d7cd0c0e..799eed27c23 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -42,6 +42,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/modules/expedition/modules_expedition.php' require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; if (! empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; if (! empty($conf->commande->enabled)) require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; @@ -232,30 +233,39 @@ if (empty($reshook)) $batch="batchl".$i."_0"; $stockLocation="ent1".$i."_0"; $qty = "qtyl".$i; - - if (isset($_POST[$batch])) + + if ($objectsrc->lines[$i]->product_tobatch) // If product need a batch number { - //shipment line with batch-enable product - $qty .= '_'.$j; - while (isset($_POST[$batch])) - { - // save line of detail into sub_qty - $sub_qty[$j]['q']=GETPOST($qty,'int'); // the qty we want to move for this stock record - $sub_qty[$j]['id_batch']=GETPOST($batch,'int'); // the id into llx_product_batch of stock record to move - $subtotalqty+=$sub_qty[$j]['q']; - - //var_dump($qty);var_dump($batch);var_dump($sub_qty[$j]['q']);var_dump($sub_qty[$j]['id_batch']); - - $j++; - $batch="batchl".$i."_".$j; - $qty = "qtyl".$i.'_'.$j; - } - - $batch_line[$i]['detail']=$sub_qty; // array of details - $batch_line[$i]['qty']=$subtotalqty; - $batch_line[$i]['ix_l']=GETPOST($idl,'int'); - - $totalqty+=$subtotalqty; + if (isset($_POST[$batch])) + { + //shipment line with batch-enable product + $qty .= '_'.$j; + while (isset($_POST[$batch])) + { + // save line of detail into sub_qty + $sub_qty[$j]['q']=GETPOST($qty,'int'); // the qty we want to move for this stock record + $sub_qty[$j]['id_batch']=GETPOST($batch,'int'); // the id into llx_product_batch of stock record to move + $subtotalqty+=$sub_qty[$j]['q']; + + //var_dump($qty);var_dump($batch);var_dump($sub_qty[$j]['q']);var_dump($sub_qty[$j]['id_batch']); + + $j++; + $batch="batchl".$i."_".$j; + $qty = "qtyl".$i.'_'.$j; + } + + $batch_line[$i]['detail']=$sub_qty; // array of details + $batch_line[$i]['qty']=$subtotalqty; + $batch_line[$i]['ix_l']=GETPOST($idl,'int'); + + $totalqty+=$subtotalqty; + } + else + { + // Case we dont use the list of available qty for each warehouse/lot + // GUI does not allow this yet + setEventMessage('StockRequiredToChooseWhichLotToUse', 'errors'); + } } else if (isset($_POST[$stockLocation])) { @@ -626,8 +636,6 @@ if ($action == 'create') $object = new $classname($db); if ($object->fetch($origin_id)) // This include the fetch_lines { - //var_dump($object); - $soc = new Societe($db); $soc->fetch($object->socid); @@ -652,7 +660,7 @@ if ($action == 'create') print ''; // Ref - print ''; // Tiers - print ''; + print ''; print ''; print ''; @@ -691,7 +699,7 @@ if ($action == 'create') // Note Public print ''; print '"; @@ -700,7 +708,7 @@ if ($action == 'create') { print ''; print '"; } @@ -708,19 +716,18 @@ if ($action == 'create') // Weight print ''; + // Dim + print ''; - print ''; - print ''; + print ''; // Delivery method print ""; @@ -864,6 +871,7 @@ if ($action == 'create') $product_static->type=$line->fk_product_type; $product_static->id=$line->fk_product; $product_static->ref=$line->ref; + $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)); @@ -1136,9 +1144,10 @@ if ($action == 'create') $subj=0; print ''; + $warehouseObject=new Entrepot($db); + $productlotObject=new Productlot($db); foreach ($product->stock_warehouse as $warehouse_id=>$stock_warehouse) { - $warehouseObject=new Entrepot($db); $warehouseObject->fetch($warehouse_id); if (($stock_warehouse->real > 0) && (count($stock_warehouse->detail_batch))) { foreach ($stock_warehouse->detail_batch as $dbatch) @@ -1156,7 +1165,11 @@ if ($action == 'create') print ''; print ''; - print $langs->trans("DetailBatchFormat", $dbatch->batch, dol_print_date($dbatch->eatby,"day"), dol_print_date($dbatch->sellby,"day"), $dbatch->qty); + //print $langs->trans("DetailBatchFormat", $dbatch->batch, dol_print_date($dbatch->eatby,"day"), dol_print_date($dbatch->sellby,"day"), $dbatch->qty); + $productlotObject->fetch(0, $line->fk_product, $dbatch->batch); + print $langs->trans("Batch").': '.$productlotObject->getNomUrl(1); + print ' ('.$dbatch->qty.')'; + //print $langs->trans("DetailBatchFormat", 'ee'.$dbatch->batch, dol_print_date($dbatch->eatby,"day"), dol_print_date($dbatch->sellby,"day"), $dbatch->qty); $quantityToBeDelivered -= $deliverableQty; if ($quantityToBeDelivered < 0) { @@ -1243,6 +1256,7 @@ else if ($id || $ref) /* *************************************************************************** */ { $lines = $object->lines; + $num_prod = count($lines); if ($object->id > 0) @@ -1687,7 +1701,7 @@ else if ($id || $ref) $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->livraison_bon->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,'; + $sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, 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"; @@ -1751,6 +1765,7 @@ else if ($id || $ref) $product_static->type=$lines[$i]->fk_product_type; $product_static->id=$lines[$i]->fk_product; $product_static->ref=$lines[$i]->ref; + $product_static->status_batch=$lines[$i]->product_tobatch; $text=$product_static->getNomUrl(1); $text.= ' - '.$label; $description=(! empty($conf->global->PRODUIT_DESC_IN_FORM)?'':dol_htmlentitiesbr($lines[$i]->description)); diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 9cf00cac1cb..1ae5556a898 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -850,14 +850,14 @@ class Expedition extends CommonObject } /** - * Add a expedition line. + * Add an expedition line. * If STOCK_WAREHOUSE_NOT_REQUIRED_FOR_SHIPMENTS is set, you can add a shipment line, with no stock source defined * If STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT is not set, you can add a shipment line, even if not enough into stock * * @param int $entrepot_id Id of warehouse * @param int $id Id of source line (order line) * @param int $qty Quantity - * @param array $array_options extrafields array + * @param array $array_options extrafields array * @return int <0 if KO, >0 if OK */ function addline($entrepot_id, $id, $qty,$array_options=0) @@ -909,6 +909,13 @@ class Expedition extends CommonObject } } + // If product need a batch number, we should not have called this function but addline_batch instead. + if (! empty($conf->productbatch->enabled) && ! empty($orderline->fk_product) && ! empty($orderline->product_tobatch)) + { + $this->error='ADDLINE_WAS_CALLED_INSTEAD_OF_ADDLINEBATCH'; + return -4; + } + // extrafields if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($array_options) && count($array_options)>0) // For avoid conflicts if trigger used $line->array_options = $array_options; diff --git a/htdocs/expedition/shipment.php b/htdocs/expedition/shipment.php index fdb4bf76359..3fa5de43447 100644 --- a/htdocs/expedition/shipment.php +++ b/htdocs/expedition/shipment.php @@ -42,6 +42,7 @@ $langs->load("bills"); $langs->load('propal'); $langs->load('deliveries'); $langs->load('stocks'); +$langs->load("productbatch"); $id=GETPOST('id','int'); // id of order $ref= GETPOST('ref','alpha'); diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 7cf9079fc0c..4af929b8cba 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -3198,7 +3198,11 @@ class Product extends CommonObject { // } - if (! empty($this->entity)) $label .= '
' . $this->show_photos($conf->product->multidir_output[$this->entity],1,1,0,0,0,80); + if (! empty($this->entity)) + { + $tmpphoto = $this->show_photos($conf->product->multidir_output[$this->entity],1,1,0,0,0,80); + if ($this->nbphoto > 0) $label .= '
' . $tmpphoto; + } $linkclose=''; diff --git a/htdocs/product/stock/class/productlot.class.php b/htdocs/product/stock/class/productlot.class.php index 01da38fae31..6128f8dcf17 100644 --- a/htdocs/product/stock/class/productlot.class.php +++ b/htdocs/product/stock/class/productlot.class.php @@ -547,7 +547,15 @@ class Productlot extends CommonObject $label = '' . $langs->trans("Batch") . ''; $label.= '
'; $label.= '' . $langs->trans('Batch') . ': ' . $this->batch; - + if ($this->eatby) + { + $label.= '
' . $langs->trans('EatByDate') . ': ' . dol_print_date($this->eatby, 'day'); + } + if ($this->sellby) + { + $label.= '
' . $langs->trans('SellByDate') . ': ' . dol_print_date($this->sellby, 'day'); + } + $link = '
'; + print '
'; if ($origin == 'commande' && ! empty($conf->commande->enabled)) { print $langs->trans("RefOrder").''.img_object($langs->trans("ShowOrder"),'order').' '.$object->ref; @@ -675,7 +683,7 @@ if ($action == 'create') print '
'.$langs->trans('Company').'
'.$langs->trans('Company').''.$soc->getNomUrl(1).'
'.$langs->trans("NotePublic").''; - $doleditor = new DolEditor('note_public', $object->note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + $doleditor = new DolEditor('note_public', $object->note_public, '', 60, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); print $doleditor->Create(1); print "
'.$langs->trans("NotePrivate").''; - $doleditor = new DolEditor('note_private', $object->note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + $doleditor = new DolEditor('note_private', $object->note_private, '', 60, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); print $doleditor->Create(1); print "
'; print $langs->trans("Weight"); - print ''; + print ' '; print $formproduct->select_measuring_units("weight_units","weight",GETPOST('weight_units','int')); - print '
'; - print $langs->trans("Width"); - print ' '; + print '
'; + print $langs->trans("Width").' x '.$langs->trans("Height").' x '.$langs->trans("Depth"); + print ' '; + print ' x '; + print ' x '; + print ' '; print $formproduct->select_measuring_units("size_units","size"); - print '
'; - print $langs->trans("Height"); - print '
'; - print $langs->trans("Depth"); - print '
".$langs->trans("DeliveryMethod")."