dolibarr  18.0.0
bom_net_needs.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2017-2020 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2019 Frédéric France <frederic.france@netlogic.fr>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
25 // Load Dolibarr environment
26 require '../main.inc.php';
27 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
28 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
29 require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
30 require_once DOL_DOCUMENT_ROOT.'/bom/lib/bom.lib.php';
31 
32 // Load translation files required by the page
33 $langs->loadLangs(array("mrp", "other", "stocks"));
34 
35 // Get parameters
36 $id = GETPOST('id', 'int');
37 $lineid = GETPOST('lineid', 'int');
38 $ref = GETPOST('ref', 'alpha');
39 $action = GETPOST('action', 'aZ09');
40 $confirm = GETPOST('confirm', 'alpha');
41 $cancel = GETPOST('cancel', 'aZ09');
42 $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'bomnet_needs'; // To manage different context of search
43 $backtopage = GETPOST('backtopage', 'alpha');
44 
45 
46 // Initialize technical objects
47 $object = new BOM($db);
48 $extrafields = new ExtraFields($db);
49 
50 // Initialize technical objects for hooks
51 $hookmanager->initHooks(array('bomnetneeds')); // Note that conf->hooks_modules contains array
52 
53 // Massaction
54 $diroutputmassaction = $conf->bom->dir_output.'/temp/massgeneration/'.$user->id;
55 
56 // Fetch optionals attributes and labels
57 $extrafields->fetch_name_optionals_label($object->table_element);
58 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
59 
60 // Initialize array of search criterias
61 $search_all = GETPOST("search_all", 'alpha');
62 $search = array();
63 foreach ($object->fields as $key => $val) {
64  if (GETPOST('search_'.$key, 'alpha')) {
65  $search[$key] = GETPOST('search_'.$key, 'alpha');
66  }
67 }
68 
69 if (empty($action) && empty($id) && empty($ref)) {
70  $action = 'view';
71 }
72 
73 // Load object
74 include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
75 if ($object->id > 0) {
76  $object->calculateCosts();
77 }
78 
79 
80 // Security check - Protection if external user
81 //if ($user->socid > 0) accessforbidden();
82 //if ($user->socid > 0) $socid = $user->socid;
83 $isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
84 $result = restrictedArea($user, 'bom', $object->id, $object->table_element, '', '', 'rowid', $isdraft);
85 
86 // Permissions
87 $permissionnote = $user->hasRight('bom', 'write'); // Used by the include of actions_setnotes.inc.php
88 $permissiondellink = $user->hasRight('bom', 'write'); // Used by the include of actions_dellink.inc.php
89 $permissiontoadd = $user->hasRight('bom', 'write'); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
90 $permissiontodelete = $user->hasRight('bom', 'delete') || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
91 $upload_dir = $conf->bom->multidir_output[isset($object->entity) ? $object->entity : 1];
92 
93 
94 /*
95  * Actions
96  */
97 
98 $parameters = array();
99 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
100 if ($reshook < 0) {
101  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
102 }
103 
104 if (empty($reshook)) {
105  $error = 0;
106 
107  $backurlforlist = DOL_URL_ROOT.'/bom/bom_list.php';
108 
109  if (empty($backtopage) || ($cancel && empty($id))) {
110  if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
111  if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
112  $backtopage = $backurlforlist;
113  } else {
114  $backtopage = DOL_URL_ROOT.'/bom/bom_net_needs.php?id='.($id > 0 ? $id : '__ID__');
115  }
116  }
117  }
118  if ($action == 'treeview') $object->getNetNeedsTree($TChildBom, 1);
119  else $object->getNetNeeds($TChildBom, 1);
120 }
121 
122 
123 /*
124  * View
125  */
126 
127 $form = new Form($db);
128 $formfile = new FormFile($db);
129 
130 $title = $langs->trans('BOM');
131 $help_url ='EN:Module_BOM';
132 llxHeader('', $title, $help_url);
133 
134 
135 // Part to show record
136 if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
137  $head = bomPrepareHead($object);
138  print dol_get_fiche_head($head, 'net_needs', $langs->trans("BillOfMaterials"), -1, 'bom');
139 
140  $formconfirm = '';
141 
142  // Call Hook formConfirm
143  $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
144  $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
145  if (empty($reshook)) {
146  $formconfirm .= $hookmanager->resPrint;
147  } elseif ($reshook > 0) {
148  $formconfirm = $hookmanager->resPrint;
149  }
150 
151  // Print form confirm
152  print $formconfirm;
153 
154 
155  // Object card
156  // ------------------------------------------------------------
157  $linkback = '<a href="'.DOL_URL_ROOT.'/bom/bom_list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
158 
159  $morehtmlref = '<div class="refidno">';
160 
161  $morehtmlref .= '</div>';
162 
163 
164  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
165 
166 
167  print '<div class="fichecenter">';
168  print '<div class="fichehalfleft">';
169  print '<div class="underbanner clearboth"></div>';
170  print '<table class="border centpercent tableforfield">'."\n";
171 
172  // Common attributes
173  $keyforbreak = 'duration';
174  include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
175 
176  print '<tr><td>'.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).'</td><td><span class="amount">'.price($object->total_cost).'</span></td></tr>';
177  print '<tr><td>'.$langs->trans("UnitCost").'</td><td>'.price($object->unit_cost).'</td></tr>';
178 
179  // Other attributes
180  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
181 
182  print '</table>';
183  print '</div>';
184  print '</div>';
185 
186  print '<div class="clearboth"></div>';
187 
188  print dol_get_fiche_end();
189 
190  $viewlink = dolGetButtonTitle($langs->trans('GroupByX', $langs->transnoentitiesnoconv("Products")), '', 'fa fa-bars imgforviewmode', $_SERVER['PHP_SELF'].'?id='.$object->id.'&token='.newToken(), '', 1, array('morecss' => 'reposition '.($action !== 'treeview' ? 'btnTitleSelected':'')));
191  $viewlink .= dolGetButtonTitle($langs->trans('TreeView'), '', 'fa fa-stream imgforviewmode', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=treeview&token='.newToken(), '', 1, array('morecss' => 'reposition marginleftonly '.($action == 'treeview' ? 'btnTitleSelected':'')));
192 
193  print load_fiche_titre($langs->trans("BOMNetNeeds"), $viewlink, 'product');
194 
195  /*
196  * Lines
197  */
198  $text_stock_options = $langs->trans("RealStockDesc").'<br>';
199  $text_stock_options .= $langs->trans("RealStockWillAutomaticallyWhen").'<br>';
200  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || !empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE) ? '- '.$langs->trans("DeStockOnShipment").'<br>' : '');
201  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) ? '- '.$langs->trans("DeStockOnValidateOrder").'<br>' : '');
202  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_BILL) ? '- '.$langs->trans("DeStockOnBill").'<br>' : '');
203  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL) ? '- '.$langs->trans("ReStockOnBill").'<br>' : '');
204  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER) ? '- '.$langs->trans("ReStockOnValidateOrder").'<br>' : '');
205  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) ? '- '.$langs->trans("ReStockOnDispatchOrder").'<br>' : '');
206  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE) ? '- '.$langs->trans("StockOnReception").'<br>' : '');
207 
208  print '<table id="tablelines" class="noborder noshadow" width="100%">';
209  print "<thead>\n";
210  print '<tr class="liste_titre nodrag nodrop">';
211  print '<td class="linecoldescription">'.$langs->trans('Product');
212  if (!empty($conf->global->BOM_SUB_BOM) && $action == 'treeview') {
213  print ' &nbsp; <a id="show_all" href="#">'.img_picto('', 'folder-open', 'class="paddingright"').$langs->trans("ExpandAll").'</a>&nbsp;&nbsp;';
214  print '<a id="hide_all" href="#">'.img_picto('', 'folder', 'class="paddingright"').$langs->trans("UndoExpandAll").'</a>&nbsp;';
215  }
216  print '</td>';
217  if ($action == 'treeview') print '<td class="left">'.$langs->trans('ProducedBy').'</td>';
218  print '<td class="linecolqty right">'.$langs->trans('Quantity').'</td>';
219  print '<td class="linecolstock right">'.$form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1).'</td>';
220  print '<td class="linecoltheoricalstock right">'.$form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc")).'</td>';
221  print '</tr>';
222 
223  print '</thead>';
224  print '<tbody>';
225  if (!empty($TChildBom)) {
226  if ($action == 'treeview') {
227  foreach ($TChildBom as $fk_bom => $TProduct) {
228  $repeatChar = '&emsp;';
229  if (!empty($TProduct['bom'])) {
230  $prod = new Product($db);
231  $prod->fetch($TProduct['bom']->fk_product);
232  if ($TProduct['parentid'] != $object->id) print '<tr class="sub_bom_lines oddeven" parentid="'.$TProduct['parentid'].'">';
233  else print '<tr class="oddeven">';
234  if ($action == 'treeview') print '<td class="linecoldescription">'.str_repeat($repeatChar, $TProduct['level']).$prod->getNomUrl(1);
235  else print '<td class="linecoldescription">'.str_repeat($repeatChar, $TProduct['level']).$TProduct['bom']->getNomUrl(1);
236  print ' <a class="collapse_bom" id="collapse-'.$fk_bom.'" href="#">';
237  print img_picto('', 'folder-open');
238  print '</a>';
239  print '</td>';
240  if ($action == 'treeview') print '<td class="left">'.$TProduct['bom']->getNomUrl(1).'</td>';
241  print '<td class="linecolqty right">'.$TProduct['qty'].'</td>';
242  print '<td class="linecolstock right"></td>';
243  print '<td class="linecoltheoricalstock right"></td>';
244  print '</tr>';
245  }
246  if (!empty($TProduct['product'])) {
247  foreach ($TProduct['product'] as $fk_product => $TInfos) {
248  $prod = new Product($db);
249  $prod->fetch($fk_product);
250  $prod->load_virtual_stock();
251  if (empty($prod->stock_reel)) $prod->stock_reel = 0;
252  if ($fk_bom != $object->id) print '<tr class="sub_bom_lines oddeven" parentid="'.$fk_bom.'">';
253  else print '<tr class="oddeven">';
254  print '<td class="linecoldescription">'.str_repeat($repeatChar, $TInfos['level']).$prod->getNomUrl(1).'</td>';
255  if ($action == 'treeview') print '<td></td>';
256  print '<td class="linecolqty right">'.$TInfos['qty'].'</td>';
257  print '<td class="linecolstock right">'.price2num($prod->stock_reel, 'MS').'</td>';
258  print '<td class="linecoltheoricalstock right">'.$prod->stock_theorique.'</td>';
259  print '</tr>';
260  }
261  }
262  }
263  } else {
264  foreach ($TChildBom as $fk_product => $qty) {
265  $prod = new Product($db);
266  $prod->fetch($fk_product);
267  $prod->load_virtual_stock();
268  if (empty($prod->stock_reel)) $prod->stock_reel = 0;
269  print '<tr class="oddeven">';
270  print '<td class="linecoldescription">'.$prod->getNomUrl(1).'</td>';
271  print '<td class="linecolqty right">'.$qty.'</td>';
272  print '<td class="linecolstock right">'.price2num($prod->stock_reel, 'MS').'</td>';
273  print '<td class="linecoltheoricalstock right">'.$prod->stock_theorique.'</td>';
274  print '</tr>';
275  }
276  }
277  }
278  print '</tbody>';
279  print '</table>';
280 
281 
282 
283  /*
284  * ButAction
285  */
286  print '<div class="tabsAction">'."\n";
287  $parameters = array();
288  $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
289  if ($reshook < 0) {
290  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
291  }
292  print '</div>';
293 
294 
295  ?>
296 
297  <script type="text/javascript" language="javascript">
298  $(document).ready(function() {
299 
300  function folderManage(element) {
301  var id_bom_line = element.attr('id').replace('collapse-', '');
302  let TSubLines = $('[parentid="'+ id_bom_line +'"]');
303 
304  if(element.html().indexOf('folder-open') <= 0) {
305  $('[parentid="'+ id_bom_line +'"]').show();
306  element.html('<?php echo dol_escape_js(img_picto('', 'folder-open')); ?>');
307  }
308  else {
309  for (let i = 0; i < TSubLines.length; i++) {
310  let subBomFolder = $(TSubLines[i]).children('.linecoldescription').children('.collapse_bom');
311  if (subBomFolder.length > 0) {
312  folderManage(subBomFolder);
313  }
314  }
315  TSubLines.hide();
316  element.html('<?php echo dol_escape_js(img_picto('', 'folder')); ?>');
317  }
318  }
319 
320  // When clicking on collapse
321  $(".collapse_bom").click(function() {
322  folderManage($(this));
323  return false;
324  });
325 
326  // To Show all the sub bom lines
327  $("#show_all").click(function() {
328  console.log("We click on show all");
329  $("[class^=sub_bom_lines]").show();
330  $("[class^=collapse_bom]").html('<?php echo dol_escape_js(img_picto('', 'folder-open')); ?>');
331  return false;
332  });
333 
334  // To Hide all the sub bom lines
335  $("#hide_all").click(function() {
336  console.log("We click on hide all");
337  $("[class^=sub_bom_lines]").hide();
338  $("[class^=collapse_bom]").html('<?php echo dol_escape_js(img_picto('', 'folder')); ?>');
339  return false;
340  });
341 
342  });
343  </script>
344 
345  <?php
346 }
347 
348 // End of page
349 llxFooter();
350 $db->close();
llxFooter
llxFooter()
Empty footer.
Definition: wrapper.php:70
load_fiche_titre
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
Definition: functions.lib.php:5477
GETPOST
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Definition: functions.lib.php:609
$form
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
BOM
Class for BOM.
Definition: bom.class.php:38
dol_banner_tab
dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='rowid', $fieldref='ref', $morehtmlref='', $moreparam='', $nodbprefix=0, $morehtmlleft='', $morehtmlstatus='', $onlybanner=0, $morehtmlright='')
Show tab footer of a card.
Definition: functions.lib.php:2205
$help_url
if(GETPOST('button_removefilter_x', 'alpha')||GETPOST('button_removefilter.x', 'alpha')||GETPOST('button_removefilter', 'alpha')) if(GETPOST('button_search_x', 'alpha')||GETPOST('button_search.x', 'alpha')||GETPOST('button_search', 'alpha')) if($action=="save" &&empty($cancel)) $help_url
View.
Definition: agenda.php:118
img_picto
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
Definition: functions.lib.php:4135
llxHeader
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:56
$formconfirm
$formconfirm
if ($action == 'delbookkeepingyear') {
Definition: listbyaccount.php:634
FormFile
Class to offer components to list and upload files.
Definition: html.formfile.class.php:36
dolGetButtonTitle
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
Definition: functions.lib.php:11263
bomPrepareHead
bomPrepareHead($object)
Prepare array of tabs for BillOfMaterials.
Definition: bom.lib.php:78
setEventMessages
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
Definition: functions.lib.php:8673
restrictedArea
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
Definition: security.lib.php:353
newToken
newToken()
Return the value of token currently saved into session with name 'newtoken'.
Definition: functions.lib.php:11654
dol_get_fiche_end
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Definition: functions.lib.php:2177
dol_get_fiche_head
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
Definition: functions.lib.php:1979
ExtraFields
Class to manage standard extra fields.
Definition: extrafields.class.php:39
Product
Class to manage products or services.
Definition: product.class.php:46
Form
Class to manage generation of HTML components Only common components must be here.
Definition: html.form.class.php:53
price
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
Definition: functions.lib.php:5829
type
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:120