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 dc621e030ce..5e86611507b 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/comm/propal/card.php b/htdocs/comm/propal/card.php
index e717e4b5e08..222f6ab8a87 100644
--- a/htdocs/comm/propal/card.php
+++ b/htdocs/comm/propal/card.php
@@ -1559,8 +1559,6 @@ if ($action == 'create') {
}
}
- $object = new Propal($db);
-
print '