diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index 4a45f724f01f4fc17ddab44f7300e9c94ecad787..de68313e6f87115d161c4e86edea7069587943f6 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -779,8 +779,21 @@ if (empty($reshook)) $desc = dol_concatdesc($desc, $product_desc); + // Add dimensions into product description + /*if (empty($conf->global->MAIN_PRODUCT_DISABLE_AUTOADD_DIM)) + { + $text=''; + if ($prod->weight) $text.=($text?"\n":"").$outputlangs->trans("Weight").': '.$prod->weight.' '.$prod->weight_units; + if ($prod->length) $text.=($text?"\n":"").$outputlangs->trans("Length").': '.$prod->length.' '.$prod->length_units; + if ($prod->surface) $text.=($text?"\n":"").$outputlangs->trans("Surface").': '.$prod->surface.' '.$prod->surface_units; + if ($prod->volume) $text.=($text?"\n":"").$outputlangs->trans("Volume").': '.$prod->volume.' '.$prod->volume_units; + + $desc = dol_concatdesc($desc, $text); + }*/ + // Add custom code and origin country into description - if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) { + if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) + { $tmptxt = '('; if (! empty($prod->customcode)) $tmptxt .= $langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 114648fdf143bc789475b620e55713108484fb6f..36101e4b081aa58ce8d76d1580c1bfe9bfe9d5ec 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2142,7 +2142,7 @@ abstract class CommonObject if ($elementTable == 'user') $fieldstatus="statut"; if ($elementTable == 'expensereport') $fieldstatus="fk_statut"; if ($elementTable == 'commande_fournisseur_dispatch') $fieldstatus="status"; - + $sql = "UPDATE ".MAIN_DB_PREFIX.$elementTable; $sql.= " SET ".$fieldstatus." = ".$status; // If status = 1 = validated, update also fk_user_valid @@ -2804,12 +2804,7 @@ abstract class CommonObject if ($line->fk_product > 0) { $product_static = new Product($this->db); - - $product_static->type=$line->fk_product_type; - $product_static->id=$line->fk_product; - $product_static->ref=$line->ref; - if (! empty($line->entity)) - $product_static->entity=$line->entity; + $product_static->fetch($line->fk_product); $text=$product_static->getNomUrl(1); // Define output language and label @@ -2842,7 +2837,7 @@ abstract class CommonObject } $text.= ' - '.(! empty($line->label)?$line->label:$label); - $description=(! empty($conf->global->PRODUIT_DESC_IN_FORM)?'':dol_htmlentitiesbr($line->description)); + $description.=(! empty($conf->global->PRODUIT_DESC_IN_FORM)?'':dol_htmlentitiesbr($line->description)); // Description is what to show on popup. We shown nothing if already into desc. } // Output template part (modules that overwrite templates must declare this into descriptor) diff --git a/htdocs/core/db/sqlite3.class.php b/htdocs/core/db/sqlite3.class.php index 3c95d9f73f7e05cfc5db435656c033f9c9010f62..50d9e5c9c794663c12d397c54c36529dff42b2dc 100644 --- a/htdocs/core/db/sqlite3.class.php +++ b/htdocs/core/db/sqlite3.class.php @@ -1255,11 +1255,14 @@ class DoliDBSqlite3 extends DoliDB * @param int $arg_count Arg count * @return void */ - private function addCustomFunction($name, $arg_count = -1) { - if ($this->db) { - $localname = __CLASS__ . '::' . 'db' . $name; + private function addCustomFunction($name, $arg_count = -1) + { + if ($this->db) + { + $newname=preg_replace('/_/','',$name); + $localname = __CLASS__ . '::' . 'db' . $newname; $reflectClass = new ReflectionClass(__CLASS__); - $reflectFunction = $reflectClass->getMethod('db' . $name); + $reflectFunction = $reflectClass->getMethod('db' . $newname); if ($arg_count < 0) { $arg_count = $reflectFunction->getNumberOfParameters(); } @@ -1333,7 +1336,7 @@ class DoliDBSqlite3 extends DoliDB * @param string $format la chaine de formatage * @return string La date formatee. */ - public static function dbdate_format($date, $format) + public static function dbdateformat($date, $format) { static $mysql_replacement; if (! isset($mysql_replacement)) { diff --git a/htdocs/product/card.php b/htdocs/product/card.php index cf22670e271ccfa752da8e32debb43fa1d06d214..0a74845a7635bee37bdb8859bb8a812399032232 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -1175,6 +1175,7 @@ else print '</td></tr>'; // Stock + /* if ($object->isproduct() && ! empty($conf->stock->enabled)) { print "<tr>".'<td>'.$langs->trans("StockLimit").'</td><td>'; @@ -1189,7 +1190,7 @@ else { print '<input name="seuil_stock_alerte" type="hidden" value="'.$object->seuil_stock_alerte.'">'; print '<input name="desiredstock" type="hidden" value="'.$object->desiredstock.'">'; - } + }*/ // Nature if($object->type!=1) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 56e721b67ac198700a65320209b7e839cbee70dd..910f5b316cd6512189db1e4c2b07ad2fa5b1c447 100755 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2656,13 +2656,13 @@ class Product extends CommonObject * @param int $level Init level * @return void */ - function fetch_prod_arbo($prod, $compl_path="", $multiply=1, $level=1) + function fetch_prod_arbo($prod, $compl_path="", $multiply=1, $level=1, $id_parent=0) { global $conf,$langs; $product = new Product($this->db); //var_dump($prod); - foreach($prod as $id_product => $desc_pere) // $id_product is 0 (there is no mode sub_product) or an id of a sub_product + foreach($prod as $id_product => $desc_pere) // $id_product is 0 (first call starting with root top) or an id of a sub_product { if (is_array($desc_pere)) // If desc_pere is an array, this means it's a child { @@ -2679,6 +2679,7 @@ class Product extends CommonObject $this->load_stock(); // Load stock $this->res[]= array( 'id'=>$id, // Id product + 'id_parent'=>$id_parent, 'ref'=>$this->ref, // Ref product 'nb'=>$nb, // Nb of units that compose parent product 'nb_total'=>$nb*$multiply, // Nb of units for all nb of product @@ -2696,7 +2697,7 @@ class Product extends CommonObject if (is_array($desc_pere['childs'])) { //print 'YYY We go down for '.$desc_pere[3]." -> \n"; - $this ->fetch_prod_arbo($desc_pere['childs'], $compl_path.$desc_pere[3]." -> ", $desc_pere[1]*$multiply, $level+1); + $this->fetch_prod_arbo($desc_pere['childs'], $compl_path.$desc_pere[3]." -> ", $desc_pere[1]*$multiply, $level+1, $id); } } } @@ -2718,7 +2719,7 @@ class Product extends CommonObject $this->res[]= array($desc_pere[1],$desc_pere[0]); if(count($desc_pere) >1) { - $this ->fetch_prods($desc_pere); + $this->fetch_prods($desc_pere); } } } @@ -2736,7 +2737,7 @@ class Product extends CommonObject { foreach($this->sousprods as $prod_name => $desc_product) { - if (is_array($desc_product)) $this->fetch_prod_arbo($desc_product,"",$multiply); + if (is_array($desc_product)) $this->fetch_prod_arbo($desc_product,"",$multiply,1,$this->id); } } //var_dump($this->res); @@ -2751,13 +2752,11 @@ class Product extends CommonObject function get_each_prod() { $this->res = array(); - if(is_array($this -> sousprods)) + if (is_array($this->sousprods)) { - foreach($this -> sousprods as $nom_pere => $desc_pere) + foreach($this->sousprods as $nom_pere => $desc_pere) { - if(count($desc_pere) >1) - $this ->fetch_prods($desc_pere); - + if (count($desc_pere) >1) $this->fetch_prods($desc_pere); } sort($this->res); } @@ -2769,10 +2768,10 @@ class Product extends CommonObject * Return all Father products fo current product * * @return array prod + * @see getParent */ function getFather() { - $sql = "SELECT p.label as label,p.rowid,pa.fk_product_pere as id,p.fk_product_type"; $sql.= " FROM ".MAIN_DB_PREFIX."product_association as pa,"; $sql.= " ".MAIN_DB_PREFIX."product as p"; @@ -2803,10 +2802,10 @@ class Product extends CommonObject * Return all direct parent products fo current product * * @return array prod + * @see getFather */ function getParent() { - $sql = "SELECT p.label as label,p.rowid,pa.fk_product_pere as id,p.fk_product_type"; $sql.= " FROM ".MAIN_DB_PREFIX."product_association as pa,"; $sql.= " ".MAIN_DB_PREFIX."product as p"; @@ -2833,10 +2832,11 @@ class Product extends CommonObject /** * Return childs of product $id * - * @param int $id Id of product to search childs of - * @return array Prod + * @param int $id Id of product to search childs of + * @param int $firstlevelonly Return only direct child + * @return array Prod */ - function getChildsArbo($id) + function getChildsArbo($id, $firstlevelonly=0) { $sql = "SELECT p.rowid, p.label as label, pa.qty as qty, pa.fk_product_fils as id, p.fk_product_type, pa.incdec"; $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; @@ -2861,10 +2861,13 @@ class Product extends CommonObject ); //$prods[$this->db->escape($rec['label'])]= array(0=>$rec['id'],1=>$rec['qty'],2=>$rec['fk_product_type']); //$prods[$this->db->escape($rec['label'])]= array(0=>$rec['id'],1=>$rec['qty']); - $listofchilds=$this->getChildsArbo($rec['id']); - foreach($listofchilds as $keyChild => $valueChild) + if (empty($firstlevelonly)) { - $prods[$rec['rowid']]['childs'][$keyChild] = $valueChild; + $listofchilds=$this->getChildsArbo($rec['id']); + foreach($listofchilds as $keyChild => $valueChild) + { + $prods[$rec['rowid']]['childs'][$keyChild] = $valueChild; + } } } @@ -2910,6 +2913,7 @@ class Product extends CommonObject function getNomUrl($withpicto=0,$option='',$maxlength=0) { global $conf, $langs; + include_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; $result=''; $newref=$this->ref; @@ -2920,6 +2924,14 @@ class Product extends CommonObject $label .= '<br><b>' . $langs->trans('ProductRef') . ':</b> ' . $this->ref; if (! empty($this->label)) $label .= '<br><b>' . $langs->trans('ProductLabel') . ':</b> ' . $this->label; + + $tmptext=''; + if ($this->weight) $tmptext.="<br>".$langs->trans("Weight").': '.$this->weight.' '.measuring_units_string($this->weight_units,"weight"); + if ($this->length) $tmptext.="<br>".$langs->trans("Length").': '.$this->length.' '.measuring_units_string($this->length_units,'length'); + if ($this->surface) $tmptext.="<br>".$langs->trans("Surface").': '.$this->surface.' '.measuring_units_string($this->surface_units,'surface'); + if ($this->volume) $tmptext.="<br>".$langs->trans("Volume").': '.$this->volume.' '.measuring_units_string($this->volume_units,'volume'); + if ($tmptext) $label .= $tmptext; + if (! empty($this->entity)) $label .= '<br>' . $this->show_photos($conf->product->multidir_output[$this->entity],1,1,0,0,0,80); diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php index af339c8270c36afd171e1410d7b4039309461f94..53f79266c2526ccece61e953bd7e77d88a138482 100644 --- a/htdocs/product/composition/card.php +++ b/htdocs/product/composition/card.php @@ -50,13 +50,13 @@ $fieldvalue = (! empty($id) ? $id : (! empty($ref) ? $ref : '')); $fieldtype = (! empty($ref) ? 'ref' : 'rowid'); $result=restrictedArea($user,'produit|service',$fieldvalue,'product&product','','',$fieldtype); -$product = new Product($db); -$productid=0; +$object = new Product($db); +$objectid=0; if ($id > 0 || ! empty($ref)) { - $result = $product->fetch($id,$ref); - $productid=$product->id; - $id=$product->id; + $result = $object->fetch($id,$ref); + $objectid=$object->id; + $id=$object->id; } @@ -74,7 +74,7 @@ if ($action == 'add_prod' && ($user->rights->produit->creer || $user->rights->se { if ($_POST["prod_qty_".$i] > 0) { - if ($product->add_sousproduit($id, $_POST["prod_id_".$i], $_POST["prod_qty_".$i], $_POST["prod_incdec_".$i]) > 0) + if ($object->add_sousproduit($id, $_POST["prod_id_".$i], $_POST["prod_qty_".$i], $_POST["prod_incdec_".$i]) > 0) { //var_dump($id.' - '.$_POST["prod_id_".$i].' - '.$_POST["prod_qty_".$i]);exit; $action = 'edit'; @@ -83,16 +83,16 @@ if ($action == 'add_prod' && ($user->rights->produit->creer || $user->rights->se { $error++; $action = 're-edit'; - if ($product->error == "isFatherOfThis") { + if ($object->error == "isFatherOfThis") { setEventMessage($langs->trans("ErrorAssociationIsFatherOfThis"), 'errors'); } else { - setEventMessage($product->error, 'errors'); + setEventMessage($object->error, 'errors'); } } } else { - if ($product->del_sousproduit($id, $_POST["prod_id_".$i]) > 0) + if ($object->del_sousproduit($id, $_POST["prod_id_".$i]) > 0) { $action = 'edit'; } @@ -100,13 +100,13 @@ if ($action == 'add_prod' && ($user->rights->produit->creer || $user->rights->se { $error++; $action = 're-edit'; - setEventMessage($product->error, 'errors'); + setEventMessage($object->error, 'errors'); } } } if (! $error) { - header("Location: ".$_SERVER["PHP_SELF"].'?id='.$product->id); + header("Location: ".$_SERVER["PHP_SELF"].'?id='.$object->id); exit; } } @@ -117,7 +117,8 @@ else if($action==='save_composed_product') { foreach ($TProduct as $id_product => $row) { - $product->update_sousproduit($id, $id_product,$row['qty'], isset($row['incdec']) ? 1 : 0 ); + if ($row['qty'] > 0) $object->update_sousproduit($id, $id_product, $row['qty'], isset($row['incdec']) ? 1 : 0 ); + else $object->del_sousproduit($id, $id_product); } } $action=''; @@ -171,11 +172,11 @@ if ($action == 'search') //print $sql; -llxHeader("","",$langs->trans("CardProduct".$product->type)); +llxHeader("","",$langs->trans("CardProduct".$object->type)); -$head=product_prepare_head($product, $user); -$titre=$langs->trans("CardProduct".$product->type); -$picto=($product->type==1?'service':'product'); +$head=product_prepare_head($object, $user); +$titre=$langs->trans("CardProduct".$object->type); +$picto=($object->type==1?'service':'product'); dol_fiche_head($head, 'subproduct', $titre, 0, $picto); @@ -191,20 +192,28 @@ if ($id > 0 || ! empty($ref)) print "<tr>"; $nblignes=6; - if ($product->isproduct() && ! empty($conf->stock->enabled)) $nblignes++; - if ($product->isservice()) $nblignes++; + if ($object->isproduct() && ! empty($conf->stock->enabled)) $nblignes++; + if ($object->isservice()) $nblignes++; // Reference print '<td width="25%">'.$langs->trans("Ref").'</td><td>'; - print $form->showrefnav($product,'ref','',1,'ref'); + print $form->showrefnav($object,'ref','',1,'ref'); print '</td>'; print '</tr>'; // Label - print '<tr><td>'.$langs->trans("Label").'</td><td>'.$product->libelle.'</td>'; + print '<tr><td>'.$langs->trans("Label").'</td><td>'.$object->libelle.'</td>'; print '</tr>'; + // Nature + if($object->type!=1) + { + print '<tr><td>'.$langs->trans("Nature").'</td><td colspan="2">'; + print $object->getLibFinished(); + print '</td></tr>'; + } + if (empty($conf->global->PRODUIT_MULTIPRICES)) { // Price @@ -232,28 +241,57 @@ if ($id > 0 || ! empty($ref)) print '</td></tr>'; } + print '</table>'; + + dol_fiche_end(); + + + $prodsfather = $object->getFather(); // Parent Products + $object->get_sousproduits_arbo(); // Load $object->sousprod + $prods_arbo=$object->get_arbo_each_prod(); + $nbofsubsubproducts=count($prods_arbo); // This include sub sub product into nb + $prodschild = $object->getChildsArbo($id,1); + $nbofsubproducts=count($prodschild); // This include only first level of childs + + + // Number of parent virtual products + print $form->textwithpicto($langs->trans("ParentProductsNumber").': '.count($prodsfather), $langs->trans('IfZeroItIsNotUsedByVirtualProduct')); + + if (count($prodsfather) > 0) + { + print $langs->trans("ProductParentList").'<br>'; + print '<table class="nobordernopadding">'; + foreach($prodsfather as $value) + { + $idprod= $value["id"]; + $productstatic->id=$idprod;// $value["id"]; + $productstatic->type=$value["fk_product_type"]; + $productstatic->ref=$value['label']; + print '<tr>'; + print '<td>'.$productstatic->getNomUrl(1,'composition').'</td>';; + print '</tr>'; + } + print '</table>'; + } + + + print '<br>'."\n"; + + // Number of subproducts - $prodsfather = $product->getFather(); //Parent Products - $product->get_sousproduits_arbo(); // Defined $product->sousprod - $prods_arbo=$product->get_arbo_each_prod(); - $nbofsubproducts=count($prods_arbo); - print '<tr><td>'.$langs->trans("AssociatedProductsNumber").'</td><td>'; - print $form->textwithpicto($nbofsubproducts, $langs->trans('IfZeroItIsNotAVirtualProduct')); - print '</td>'; - print '</tr>'; + print $form->textwithpicto($langs->trans("AssociatedProductsNumber").': '.(empty($conf->global->PRODUCT_SHOW_SUB_SUB_PRODUCTS)?$nbofsubproducts:$nbofsubsubproducts), $langs->trans('IfZeroItIsNotAVirtualProduct')); // List of subproducts if (count($prods_arbo) > 0) { $atleastonenotdefined=0; - print '<tr><td colspan="2">'; print $langs->trans("ProductAssociationList").'<br>'; print '<form name="formComposedProduct" action="'.$_SERVER['PHP_SELF'].'" method="post">'; print '<input type="hidden" name="action" value="save_composed_product" />'; print '<input type="hidden" name="id" value="'.$id.'" />'; - print '<table class="centpercent nobordernopadding">'; + print '<table class="centpercent noborder">'; print '<tr class="liste_titre">'; print '<td>'.$langs->trans('ComposedProduct').'</td>'; @@ -262,7 +300,7 @@ if ($id > 0 || ! empty($ref)) if (! empty($conf->stock->enabled)) print '<td align="right">'.$langs->trans('Stock').'</td>'; print '<td align="center">'.$langs->trans('Qty').'</td>'; print '<td align="center">'.$langs->trans('ComposedProductIncDecStock').'</td>'; - print '</tr>'; + print '</tr>'."\n"; foreach($prods_arbo as $value) { @@ -270,11 +308,11 @@ if ($id > 0 || ! empty($ref)) $productstatic->type=$value['type']; $productstatic->label=$value['label']; - $class=($class=='impair')?'pair':'impair'; - - print '<tr class="'.$class.'">'; if ($value['level'] <= 1) { + $class=($class=='impair')?'pair':'impair'; + print '<tr class="'.$class.'">'; + $notdefined=0; $productstatic->ref=$value['ref']; $nb_of_subproduct = $value['nb']; @@ -312,9 +350,17 @@ if ($id > 0 || ! empty($ref)) print '<td>'.$nb_of_subproduct.'</td>'; print '<td>'.($value['incdec']==1?'x':'' ).'</td>'; } + + print '</tr>'."\n"; } - else + else // By default, we do not show this. It makes screen very difficult to understand { + $hide=''; + if (empty($conf->global->PRODUCT_SHOW_SUB_SUB_PRODUCTS)) $hide=' hideobject'; + + $class=($class=='impair')?'pair':'impair'; + print '<tr class="'.$class.$hide.'" id="sub-'.$value['id_parent'].'">'; + //$productstatic->ref=$value['label']; $productstatic->ref=$value['ref']; print '<td>'; @@ -328,8 +374,9 @@ if ($id > 0 || ! empty($ref)) if (! empty($conf->stock->enabled)) print '<td></td>'; // Real stock print '<td align="center">'.$value['nb'].'</td>'; print '<td> </td>'; + + print '</tr>'."\n"; } - print '</tr>'; } print '<tr class="liste_total">'; print '<td class="liste_total"></td>'; @@ -348,19 +395,13 @@ if ($id > 0 || ! empty($ref)) // Stock if (! empty($conf->stock->enabled)) print '<td class="liste_total" align="right"> </td>'; - print '<td align="center">'; - if ($user->rights->produit->creer || $user->rights->service->creer) - { - print '<input type="submit" class="button" value="'.$langs->trans('Save').'">'; - } - print '</td>'; - print '<td align="center">'; + print '<td align="right" colspan="2">'; if ($user->rights->produit->creer || $user->rights->service->creer) { print '<input type="submit" class="button" value="'.$langs->trans('Save').'">'; } print '</td>'; - print '</tr>'; + print '</tr>'."\n"; print '</table>'; /*if($user->rights->produit->creer || $user->rights->service->creer) { @@ -368,39 +409,8 @@ if ($id > 0 || ! empty($ref)) }*/ print '</form>'; - - print '</td></tr>'; } - // Number of parent virtual products - print '<tr class="pair"><td>'.$langs->trans("ParentProductsNumber").'</td><td>'; - print $form->textwithpicto(count($prodsfather), $langs->trans('IfZeroItIsNotUsedByVirtualProduct')); - print '</td></tr>'; - - if (count($prodsfather) > 0) - { - print '<tr><td colspan="2">'; - print $langs->trans("ProductParentList").'<br>'; - print '<table class="nobordernopadding">'; - foreach($prodsfather as $value) - { - $idprod= $value["id"]; - $productstatic->id=$idprod;// $value["id"]; - $productstatic->type=$value["fk_product_type"]; - $productstatic->ref=$value['label']; - print '<tr>'; - print '<td>'.$productstatic->getNomUrl(1,'composition').'</td>';; - print '</tr>'; - } - print '</table>'; - print '</td></tr>'; - } - - print '</table>'; - - dol_fiche_end(); - - // Form with product to add if ((empty($action) || $action == 'view' || $action == 'edit' || $action == 'search' || $action == 're-edit') && ($user->rights->produit->creer || $user->rights->service->creer)) { @@ -500,11 +510,11 @@ if ($id > 0 || ! empty($ref)) print '<td>'.$labeltoshow.'</td>'; - if($product->is_sousproduit($id, $objp->rowid)) + if($object->is_sousproduit($id, $objp->rowid)) { //$addchecked = ' checked="checked"'; - $qty=$product->is_sousproduit_qty; - $incdec=$product->is_sousproduit_incdec; + $qty=$object->is_sousproduit_qty; + $incdec=$object->is_sousproduit_incdec; } else {