Merge pull request #18503 from atm-adrien/NEW_develop_sub_BOM
NEW : Sub bill of materials
This commit is contained in:
commit
7f19682724
28
htdocs/bom/ajax/interface.php
Normal file
28
htdocs/bom/ajax/interface.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
require '../../main.inc.php';
|
||||
|
||||
$action = GETPOST('action', 'alphanohtml');
|
||||
$select_product_val = GETPOST('select_product_val', 'int');
|
||||
$current_bom_id = GETPOST('current_bom_id', 'int');
|
||||
|
||||
global $db;
|
||||
|
||||
switch ($action) {
|
||||
case 'select_BOM':
|
||||
//Selection of nomenclatures corresponding to the selected product
|
||||
$sql = 'SELECT b.rowid, b.ref, b.label, b.fk_product, p.label AS product_label FROM '.MAIN_DB_PREFIX.'bom_bom AS b ';
|
||||
$sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'product AS p ON b.fk_product=p.rowid';
|
||||
$sql.= ' WHERE fk_product='.(int) $select_product_val.' AND b.rowid<>'. (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;
|
||||
}
|
||||
@ -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 '</table>';
|
||||
}
|
||||
?>
|
||||
<script>
|
||||
let select_product_val;
|
||||
let current_bom_id = <?php echo $object->id?>;
|
||||
//On change on the bom select
|
||||
$('#idprod').on('change', function () {
|
||||
select_product_val = $('#idprod').select2().val();
|
||||
|
||||
//Ajax to set all options without reloading the page
|
||||
$.ajax({
|
||||
url: 'script/interface.php'
|
||||
, method: 'POST'
|
||||
, dataType: 'text'
|
||||
, data: {
|
||||
action: 'select_BOM'
|
||||
, select_product_val: select_product_val
|
||||
, current_bom_id: current_bom_id
|
||||
}
|
||||
}).done(function (data) {
|
||||
//To remove all options of the bom select on change
|
||||
$('#bom_select').get(0).length = 0;
|
||||
|
||||
//To set options for the bom select on change
|
||||
let options = JSON.parse(data)
|
||||
for (let key in options) {
|
||||
let opt = new Option(options[key], key);
|
||||
$('#bom_select').append(opt)
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<?php
|
||||
print '</div>';
|
||||
|
||||
print "</form>\n";
|
||||
?>
|
||||
|
||||
<script type="text/javascript" language="javascript">
|
||||
$(document).ready(function() {
|
||||
|
||||
$(".collapse_bom").click(function() {
|
||||
|
||||
var id_bom_line = $(this).attr('id').replace('collapse-', '');
|
||||
if($(this).text().indexOf('+') > 0) {
|
||||
$('[parentid="'+ id_bom_line +'"]').show();
|
||||
$(this).html('(-) ');
|
||||
}
|
||||
else {
|
||||
$('[parentid="'+ id_bom_line +'"]').hide();
|
||||
$(this).html('(+) ');
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
//To Show all the sub bom lines
|
||||
$("#show_all").click(function() {
|
||||
$("[class^=sub_bom_lines]").show();
|
||||
$("[class^=collapse_bom]").html('(-) ');
|
||||
return false;
|
||||
});
|
||||
//To Hide all the sub bom lines
|
||||
$("#hide_all").click(function() {
|
||||
$("[class^=sub_bom_lines]").hide();
|
||||
$("[class^=collapse_bom]").html('(+) ');
|
||||
return false;
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1139,6 +1139,7 @@ class BOMLine extends CommonObjectLine
|
||||
'rowid' => 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
|
||||
*/
|
||||
|
||||
@ -61,6 +61,8 @@ if ($nolinesbefore) {
|
||||
print '<td class="linecoldescription minwidth500imp">';
|
||||
print '<div id="add"></div><span class="hideonsmartphone">'.$langs->trans('AddNewLine').'</span>';
|
||||
print '</td>';
|
||||
// Linked BOM
|
||||
print '<td class="linecolBOM">'.$langs->trans('BOM').'</td>';
|
||||
print '<td class="linecolqty right">'.$langs->trans('Qty').'</td>';
|
||||
if (!empty($conf->global->PRODUCT_USE_UNITS)) {
|
||||
print '<td class="linecoluseunit left">';
|
||||
@ -107,6 +109,10 @@ if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) {
|
||||
|
||||
echo '</span>';
|
||||
}
|
||||
$coldisplay++;
|
||||
print '<td class="bordertop nobottom linecolbom">';
|
||||
print '<select id="bom_select" name="bom_select"><options value="-1"></options></select>';
|
||||
print '</td>';
|
||||
|
||||
$coldisplay++;
|
||||
print '<td class="bordertop nobottom linecolqty right"><input type="text" size="2" name="qty" id="qty" class="flat right" value="'.(GETPOSTISSET("qty") ? GETPOST("qty", 'alpha', 2) : 1).'">';
|
||||
|
||||
@ -97,6 +97,8 @@ print '</td>';
|
||||
*/
|
||||
|
||||
$coldisplay++;
|
||||
// For BOM
|
||||
print '<td></td>';
|
||||
|
||||
print '<td class="nobottom linecolqty right">';
|
||||
if (($line->info_bits & 2) != 2) {
|
||||
|
||||
@ -43,6 +43,8 @@ print "<!-- BEGIN PHP TEMPLATE objectline_title.tpl.php -->\n";
|
||||
print "<thead>\n";
|
||||
|
||||
print '<tr class="liste_titre nodrag nodrop">';
|
||||
print '<a id="show_all" href="#">'.img_picto('', 'folder-open', 'class="paddingright"').$langs->trans("ExpandAll").'</a> ';
|
||||
print '<a id="hide_all" href="#">'.img_picto('', 'folder', 'class="paddingright"').$langs->trans("UndoExpandAll").'</a> ';
|
||||
|
||||
// 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 '<td class="linecoldescription">'.$langs->trans('Description').'</td>';
|
||||
|
||||
// Linked BOM
|
||||
print '<td class="linecolBOM">'.$langs->trans('BOM').'</td>';
|
||||
|
||||
// Qty
|
||||
print '<td class="linecolqty right">'.$form->textwithpicto($langs->trans('Qty'), $langs->trans("QtyRequiredIfNoLoss")).'</td>';
|
||||
|
||||
|
||||
@ -80,9 +80,22 @@ print '<div id="line_'.$line->id.'"></div>';
|
||||
$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 '<a class="collapse_bom" id="collapse-'.$line->id.'" href="#">' . (empty($conf->global->BOM_SHOW_ALL_BOM_BY_DEFAULT) ? '(+)' : '(-)') . ' </a>';
|
||||
}
|
||||
print $tmpproduct->getNomUrl(1);
|
||||
print ' - '.$tmpproduct->label;
|
||||
print '</td>';
|
||||
|
||||
// To show BOM links in the list
|
||||
if ($res > 0) {
|
||||
print '<td id="bom_id">'.$tmpbom->getNomUrl(1).'</td>';
|
||||
} else {
|
||||
print '<td id="bom_id"> </td>';
|
||||
}
|
||||
|
||||
print '<td class="linecolqty nowrap right">';
|
||||
$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 '</td>';
|
||||
|
||||
print '<td class="linecolcost nowrap right">';
|
||||
$total_cost = 0;
|
||||
print '<td id="costline_'.$line->id.'" class="linecolcost nowrap right">';
|
||||
$coldisplay++;
|
||||
echo price($line->total_cost);
|
||||
print '</td>';
|
||||
@ -166,6 +180,93 @@ if ($action == 'selectlines') {
|
||||
|
||||
print '</tr>';
|
||||
|
||||
// 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 '<tr style="display:none" class="sub_bom_lines" parentid="'.$line->id.'">';
|
||||
} else {
|
||||
print '<tr class="sub_bom_lines" parentid="'.$line->id.'">';
|
||||
}
|
||||
|
||||
// Product
|
||||
print '<td style="padding-left: 5%" id="sub_bom_product_'.$sub_bom_line->id.'">'.$sub_bom_product->getNomUrl(1).'</td>';
|
||||
|
||||
// Sub-BOM
|
||||
if ($sub_bom_line->fk_bom_child > 0) {
|
||||
print '<td id="sub_bom_bom_'.$sub_bom_line->id.'">'.$sub_bom->getNomUrl(1).'</td>';
|
||||
} else {
|
||||
print '<td id="sub_bom_bom_'.$sub_bom_line->id.'"> </td>';
|
||||
}
|
||||
|
||||
// Qty
|
||||
print '<td class="linecolqty nowrap right" id="sub_bom_qty_'.$sub_bom_line->id.'">'.price($sub_bom_line->qty * $line->qty, 0, '', 0, 0).'</td>';
|
||||
if ($sub_bom_line->qty_frozen > 0) {
|
||||
print '<td class="linecolqtyfrozen nowrap right" id="sub_bom_qty_frozen_'.$sub_bom_line->id.'">'.$sub_bom_line->qty_frozen.'</td>';
|
||||
} else {
|
||||
print '<td class="linecolqtyfrozen nowrap right" id="sub_bom_qty_frozen_'.$sub_bom_line->id.'"> </td>';
|
||||
}
|
||||
|
||||
// Disable stock change
|
||||
if ($sub_bom_line->disable_stock_change > 0) {
|
||||
print '<td class="linecoldisablestockchange nowrap right" id="sub_bom_stock_change_'.$sub_bom_line->id.'">'.$sub_bom_line->disable_stock_change.'</td>';
|
||||
} else {
|
||||
print '<td class="linecoldisablestockchange nowrap right" id="sub_bom_stock_change_'.$sub_bom_line->id.'"> </td>';
|
||||
}
|
||||
|
||||
// Efficiency
|
||||
print '<td class="linecolefficiency nowrap right" id="sub_bom_efficiency_'.$sub_bom_line->id.'">'.$sub_bom_line->efficiency.'</td>';
|
||||
|
||||
// Cost price if it's defined
|
||||
if ($sub_bom_product->cost_price > 0) {
|
||||
print '<td class="linecolcost nowrap right" id="sub_bom_cost_'.$sub_bom_line->id.'">'.price($sub_bom_product->cost_price * $line->qty).'</td>';
|
||||
$total_cost.= $sub_bom_product->cost_price * $line->qty;
|
||||
} elseif ($sub_bom_product->pmp > 0) { // PMP if cost price isn't defined
|
||||
print '<td class="linecolcost nowrap right" id="sub_bom_cost_'.$sub_bom_line->id.'">'.price($sub_bom_product->pmp * $line->qty).'</td>';
|
||||
$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 '<td class="linecolcost nowrap right" id="sub_bom_cost_'.$sub_bom_line->id.'">'.price($obj->min_price * $line->qty).'</td>';
|
||||
$total_cost+= $obj->min_price * $line->qty;
|
||||
}
|
||||
}
|
||||
|
||||
print '<td></td>';
|
||||
print '<td></td>';
|
||||
print '<td></td>';
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
?>
|
||||
<script>
|
||||
$('#costline_<?php echo $line->id?>').html("<?php echo "".price($total_cost)?>");
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
//Line extrafield
|
||||
if (!empty($extrafields)) {
|
||||
print $line->showOptionals($extrafields, 'view', array('style'=>'class="drag drop oddeven"', 'colspan'=>$coldisplay), '', '', 1, 'line');
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user