diff --git a/htdocs/bom/ajax/interface.php b/htdocs/bom/ajax/interface.php new file mode 100644 index 00000000000..23b208e25ba --- /dev/null +++ b/htdocs/bom/ajax/interface.php @@ -0,0 +1,28 @@ +'. (int) $current_bom_id; + $resql = $db->query($sql); + if ($resql && $db->num_rows($resql) > 0) { + $options = array(); + $cpt=0; + while ($obj = $db->fetch_object($resql)) { + $options[$obj->rowid] = $obj->ref.' - '.$obj->label; + $cpt++; + } + print json_encode($options); + } + + break; +} diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index c649b207ef5..435c3b5bb6f 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -149,6 +149,7 @@ if (empty($reshook)) { // Set if we used free entry or predefined product $idprod = (int) GETPOST('idprod', 'int'); + $bom_child = (int) GETPOST('bom_select', 'int'); $qty = price2num(GETPOST('qty', 'alpha'), 'MS'); $qty_frozen = price2num(GETPOST('qty_frozen', 'alpha'), 'MS'); $disable_stock_change = GETPOST('disable_stock_change', 'int'); @@ -172,6 +173,7 @@ if (empty($reshook)) { $bomline = new BOMLine($db); $bomline->fk_bom = $id; $bomline->fk_product = $idprod; + $bomline->fk_bom_child = $bom_child; $bomline->qty = $qty; $bomline->qty_frozen = (int) $qty_frozen; $bomline->disable_stock_change = (int) $disable_stock_change; @@ -571,9 +573,78 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) { print ''; } + ?> + + '; print "\n"; + ?> + + + + array('type'=>'integer', 'label'=>'LineID', 'enabled'=>1, 'visible'=>-1, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",), 'fk_bom' => array('type'=>'integer:BillOfMaterials:societe/class/bom.class.php', 'label'=>'BillOfMaterials', 'enabled'=>1, 'visible'=>1, 'position'=>10, 'notnull'=>1, 'index'=>1,), 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php', 'label'=>'Product', 'enabled'=>1, 'visible'=>1, 'position'=>20, 'notnull'=>1, 'index'=>1,), + 'fk_bom_child' => array('type'=>'integer:BOM:bom/class/bom.class.php', 'label'=>'BillOfMaterials', 'enabled'=>1, 'visible'=>-1, 'position'=>40, 'notnull'=>-1,), 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'notnull'=>-1,), 'qty' => array('type'=>'double(24,8)', 'label'=>'Quantity', 'enabled'=>1, 'visible'=>1, 'position'=>100, 'notnull'=>1, 'isameasure'=>'1',), 'qty_frozen' => array('type'=>'smallint', 'label'=>'QuantityFrozen', 'enabled'=>1, 'visible'=>1, 'default'=>0, 'position'=>105, 'css'=>'maxwidth50imp', 'help'=>'QuantityConsumedInvariable'), @@ -1163,6 +1164,11 @@ class BOMLine extends CommonObjectLine */ public $fk_product; + /** + * @var int Id of parent bom + */ + public $fk_bom_child; + /** * @var string description */ diff --git a/htdocs/bom/tpl/objectline_create.tpl.php b/htdocs/bom/tpl/objectline_create.tpl.php index 210ab695ec8..d96f8da2791 100644 --- a/htdocs/bom/tpl/objectline_create.tpl.php +++ b/htdocs/bom/tpl/objectline_create.tpl.php @@ -61,6 +61,8 @@ if ($nolinesbefore) { print ''; print '
'.$langs->trans('AddNewLine').''; print ''; + // Linked BOM + print ''.$langs->trans('BOM').''; print ''.$langs->trans('Qty').''; if (!empty($conf->global->PRODUCT_USE_UNITS)) { print ''; @@ -107,6 +109,10 @@ if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) { echo ''; } +$coldisplay++; +print ''; +print ''; +print ''; $coldisplay++; print ''; diff --git a/htdocs/bom/tpl/objectline_edit.tpl.php b/htdocs/bom/tpl/objectline_edit.tpl.php index 46b57e89243..54e145ad2ee 100644 --- a/htdocs/bom/tpl/objectline_edit.tpl.php +++ b/htdocs/bom/tpl/objectline_edit.tpl.php @@ -97,6 +97,8 @@ print ''; */ $coldisplay++; +// For BOM +print ''; print ''; if (($line->info_bits & 2) != 2) { diff --git a/htdocs/bom/tpl/objectline_title.tpl.php b/htdocs/bom/tpl/objectline_title.tpl.php index d1b29ee03b0..0656f23aed9 100644 --- a/htdocs/bom/tpl/objectline_title.tpl.php +++ b/htdocs/bom/tpl/objectline_title.tpl.php @@ -43,6 +43,8 @@ print "\n"; print "\n"; print ''; +print ''.img_picto('', 'folder-open', 'class="paddingright"').$langs->trans("ExpandAll").'  '; +print ''.img_picto('', 'folder', 'class="paddingright"').$langs->trans("UndoExpandAll").' '; // Adds a line numbering column if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { @@ -52,6 +54,9 @@ if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { // Description print ''.$langs->trans('Description').''; +// Linked BOM +print ''.$langs->trans('BOM').''; + // Qty print ''.$form->textwithpicto($langs->trans('Qty'), $langs->trans("QtyRequiredIfNoLoss")).''; diff --git a/htdocs/bom/tpl/objectline_view.tpl.php b/htdocs/bom/tpl/objectline_view.tpl.php index 9ef77fb0d98..8256019bd98 100644 --- a/htdocs/bom/tpl/objectline_view.tpl.php +++ b/htdocs/bom/tpl/objectline_view.tpl.php @@ -80,9 +80,22 @@ print '
'; $coldisplay++; $tmpproduct = new Product($object->db); $tmpproduct->fetch($line->fk_product); +$tmpbom = new BOM($object->db); +$res = $tmpbom->fetch($line->fk_bom_child); +if (!empty($tmpbom->id)) { + print '' . (empty($conf->global->BOM_SHOW_ALL_BOM_BY_DEFAULT) ? '(+)' : '(-)') . ' '; +} print $tmpproduct->getNomUrl(1); print ' - '.$tmpproduct->label; print ''; + +// To show BOM links in the list +if ($res > 0) { + print ''.$tmpbom->getNomUrl(1).''; +} else { + print ' '; +} + print ''; $coldisplay++; echo price($line->qty, 0, '', 0, 0); // Yes, it is a quantity, not a price, but we just want the formating role of function price @@ -111,7 +124,8 @@ $coldisplay++; echo $line->efficiency; print ''; -print ''; +$total_cost = 0; +print ''; $coldisplay++; echo price($line->total_cost); print ''; @@ -166,6 +180,93 @@ if ($action == 'selectlines') { print ''; +// Select of all the sub-BOM lines +$sql = 'SELECT rowid, fk_bom_child, fk_product FROM '.MAIN_DB_PREFIX.'bom_bomline AS bl'; +$sql.= ' WHERE fk_bom ='. (int) $tmpbom->id; +$resql = $object->db->query($sql); + +if ($resql) { + // Loop on all the sub-BOM lines if they exist + while ($obj = $object->db->fetch_object($resql)) { + $sub_bom_product = new Product($object->db); + $sub_bom_product->fetch($obj->fk_product); + + $sub_bom = new BOM($object->db); + $sub_bom->fetch($obj->fk_bom_child); + + $sub_bom_line = new BOMLine($object->db); + $sub_bom_line->fetch($obj->rowid); + + //If hidden conf is set, we show directly all the sub-BOM lines + if (empty($conf->global->BOM_SHOW_ALL_BOM_BY_DEFAULT)) { + print ''; + } else { + print ''; + } + + // Product + print ''.$sub_bom_product->getNomUrl(1).''; + + // Sub-BOM + if ($sub_bom_line->fk_bom_child > 0) { + print ''.$sub_bom->getNomUrl(1).''; + } else { + print ' '; + } + + // Qty + print ''.price($sub_bom_line->qty * $line->qty, 0, '', 0, 0).''; + if ($sub_bom_line->qty_frozen > 0) { + print ''.$sub_bom_line->qty_frozen.''; + } else { + print ' '; + } + + // Disable stock change + if ($sub_bom_line->disable_stock_change > 0) { + print ''.$sub_bom_line->disable_stock_change.''; + } else { + print ' '; + } + + // Efficiency + print ''.$sub_bom_line->efficiency.''; + + // Cost price if it's defined + if ($sub_bom_product->cost_price > 0) { + print ''.price($sub_bom_product->cost_price * $line->qty).''; + $total_cost.= $sub_bom_product->cost_price * $line->qty; + } elseif ($sub_bom_product->pmp > 0) { // PMP if cost price isn't defined + print ''.price($sub_bom_product->pmp * $line->qty).''; + $total_cost.= $sub_bom_product->pmp * $line->qty; + } else { // Minimum purchase price if cost price and PMP aren't defined + $sql_supplier_price = 'SELECT MIN(price) AS min_price FROM '.MAIN_DB_PREFIX.'product_fournisseur_price'; + $sql_supplier_price.= ' WHERE fk_product = '. (int) $sub_bom_product->id; + $resql_supplier_price = $object->db->query($sql_supplier_price); + if ($resql_supplier_price) { + $obj = $object->db->fetch_object($resql_supplier_price); + print ''.price($obj->min_price * $line->qty).''; + $total_cost+= $obj->min_price * $line->qty; + } + } + + print ''; + print ''; + print ''; + } +} + +// Replace of the total_cost value by the sum of all sub-BOM lines total_cost +if ($total_cost > 0) { + $line->total_cost = price($total_cost); + ?> + + showOptionals($extrafields, 'view', array('style'=>'class="drag drop oddeven"', 'colspan'=>$coldisplay), '', '', 1, 'line'); diff --git a/htdocs/langs/en_US/mrp.lang b/htdocs/langs/en_US/mrp.lang index 10e81316ee4..3f1aac53340 100644 --- a/htdocs/langs/en_US/mrp.lang +++ b/htdocs/langs/en_US/mrp.lang @@ -104,4 +104,6 @@ HumanMachine=Human / Machine WorkstationArea=Workstation area Machines=Machines THMEstimatedHelp=This rate makes it possible to define a forecast cost of the item +BOM=Bill Of Materials +CollapseBOMHelp=You can define the default display of the details of the nomenclature in the configuration of the BOM module MOAndLines=Manufacturing Orders and lines diff --git a/htdocs/langs/fr_FR/mrp.lang b/htdocs/langs/fr_FR/mrp.lang index 4aaeb4f9366..5a89a594cc3 100644 --- a/htdocs/langs/fr_FR/mrp.lang +++ b/htdocs/langs/fr_FR/mrp.lang @@ -32,7 +32,7 @@ ValueOfMeansLossForProductProduced=Une valeur de 0,95 signifie une moyenne de 5% DeleteBillOfMaterials=Supprimer la nomenclature DeleteMo=Supprimer l'ordre de fabrication ConfirmDeleteBillOfMaterials=Êtes-vous sûr de vouloir supprimer cette nomenclature? -ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? +ConfirmDeleteMo=Êtes-vous sûr de vouloir supprimer cette nomenclature? MenuMRP=Ordres de fabrication NewMO=Nouvel Ordre de fabrication QtyToProduce=Quantité à produire @@ -74,7 +74,7 @@ NoStockChangeOnServices=Aucune variation de stock sur les services ProductQtyToConsumeByMO=Quantité de produit restant à consommer par OF ouvert ProductQtyToProduceByMO=Quantités restant à produire avec les OF ouverts AddNewConsumeLines=Ajouter une nouvelle ligne à consommer -AddNewProduceLines=Add new line to produce +AddNewProduceLines=Ajouter une nouvelle ligne à produire ProductsToConsume=Produits à consommer ProductsToProduce=Produits à produire UnitCost=Coût unitaire @@ -105,3 +105,5 @@ WorkstationArea=Espace Poste de travail Machines=Machines THMEstimatedHelp=Ce taux permet de définir un coût prévisionnel de l'article MOAndLines=Ordres de fabrication et lignes +BOM=Nomenclature +CollapseBOMHelp=Vous pouvez définir l'affichage par défaut du détail des nomenclature dans la configuration du module "Nomenclature Produits"