dolibarr  13.0.2
bom_card.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"));
34 
35 // Get parameters
36 $id = GETPOST('id', 'int');
37 $ref = GETPOST('ref', 'alpha');
38 $action = GETPOST('action', 'aZ09');
39 $confirm = GETPOST('confirm', 'alpha');
40 $cancel = GETPOST('cancel', 'aZ09');
41 $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'bomcard'; // To manage different context of search
42 $backtopage = GETPOST('backtopage', 'alpha');
43 $lineid = GETPOST('lineid', 'int');
44 
45 // PDF
46 $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0));
47 $hidedesc = (GETPOST('hidedesc', 'int') ? GETPOST('hidedesc', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0));
48 $hideref = (GETPOST('hideref', 'int') ? GETPOST('hideref', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0));
49 
50 // Initialize technical objects
51 $object = new BOM($db);
52 $extrafields = new ExtraFields($db);
53 $diroutputmassaction = $conf->bom->dir_output.'/temp/massgeneration/'.$user->id;
54 $hookmanager->initHooks(array('bomcard', 'globalcard')); // Note that conf->hooks_modules contains array
55 // Fetch optionals attributes and labels
56 $extrafields->fetch_name_optionals_label($object->table_element);
57 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
58 
59 // Initialize array of search criterias
60 $search_all = GETPOST("search_all", 'alpha');
61 $search = array();
62 foreach ($object->fields as $key => $val)
63 {
64  if (GETPOST('search_'.$key, 'alpha')) $search[$key] = GETPOST('search_'.$key, 'alpha');
65 }
66 
67 if (empty($action) && empty($id) && empty($ref)) $action = 'view';
68 
69 // Load object
70 include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
71 
72 // Security check - Protection if external user
73 //if ($user->socid > 0) accessforbidden();
74 //if ($user->socid > 0) $socid = $user->socid;
75 //$isdraft = (($object->statut == $object::STATUS_DRAFT) ? 1 : 0);
76 //$result = restrictedArea($user, 'bom', $object->id, '', '', 'fk_soc', 'rowid', $isdraft);
77 
78 $permissionnote = $user->rights->bom->write; // Used by the include of actions_setnotes.inc.php
79 $permissiondellink = $user->rights->bom->write; // Used by the include of actions_dellink.inc.php
80 $permissiontoadd = $user->rights->bom->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
81 $permissiontodelete = $user->rights->bom->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
82 $upload_dir = $conf->bom->multidir_output[isset($object->entity) ? $object->entity : 1];
83 
84 
85 /*
86  * Actions
87  */
88 
89 $parameters = array();
90 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
91 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
92 
93 if (empty($reshook))
94 {
95  $error = 0;
96 
97  $backurlforlist = DOL_URL_ROOT.'/bom/bom_list.php';
98 
99  if (empty($backtopage) || ($cancel && empty($id))) {
100  if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
101  if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) $backtopage = $backurlforlist;
102  else $backtopage = dol_buildpath('/bom/bom_card.php', 1).'?id='.($id > 0 ? $id : '__ID__');
103  }
104  }
105 
106  $triggermodname = 'BOM_MODIFY'; // Name of trigger action code to execute when we modify record
107 
108  // Actions cancel, add, update, delete or clone
109  include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
110 
111  // Actions when linking object each other
112  include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';
113 
114  // Actions when printing a doc from card
115  include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
116 
117  // Action to move up and down lines of object
118  //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php';
119 
120  // Action to build doc
121  include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
122 
123  // Actions to send emails
124  $triggersendname = 'BOM_SENTBYMAIL';
125  $autocopy = 'MAIN_MAIL_AUTOCOPY_BOM_TO';
126  $trackid = 'bom'.$object->id;
127  include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
128 
129  // Add line
130  if ($action == 'addline' && $user->rights->bom->write)
131  {
132  $langs->load('errors');
133  $error = 0;
134 
135  // Set if we used free entry or predefined product
136  $idprod = (int) GETPOST('idprod', 'int');
137  $qty = price2num(GETPOST('qty', 'alpha'), 'MS');
138  $qty_frozen = price2num(GETPOST('qty_frozen', 'alpha'), 'MS');
139  $disable_stock_change = GETPOST('disable_stock_change', 'int');
140  $efficiency = price2num(GETPOST('efficiency', 'alpha'));
141 
142  if ($qty == '') {
143  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
144  $error++;
145  }
146  if (!($idprod > 0)) {
147  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Product')), null, 'errors');
148  $error++;
149  }
150 
151  if ($object->fk_product == $idprod) {
152  setEventMessages($langs->trans('TheProductXIsAlreadyTheProductToProduce'), null, 'errors');
153  $error++;
154  }
155 
156  if (!$error)
157  {
158  $bomline = new BOMLine($db);
159  $bomline->fk_bom = $id;
160  $bomline->fk_product = $idprod;
161  $bomline->qty = $qty;
162  $bomline->qty_frozen = (int) $qty_frozen;
163  $bomline->disable_stock_change = (int) $disable_stock_change;
164  $bomline->efficiency = $efficiency;
165 
166  // Rang to use
167  $rangmax = $object->line_max(0);
168  $ranktouse = $rangmax + 1;
169 
170  $bomline->position = ($ranktouse + 1);
171 
172  $result = $bomline->create($user);
173  if ($result <= 0) {
174  setEventMessages($bomline->error, $bomline->errors, 'errors');
175  $action = '';
176  } else {
177  unset($_POST['idprod']);
178  unset($_POST['qty']);
179  unset($_POST['qty_frozen']);
180  unset($_POST['disable_stock_change']);
181 
182  $object->fetchLines();
183 
184  $object->calculateCosts();
185  }
186  }
187  }
188 
189  // Add line
190  if ($action == 'updateline' && $user->rights->bom->write)
191  {
192  $langs->load('errors');
193  $error = 0;
194 
195  // Set if we used free entry or predefined product
196  $qty = price2num(GETPOST('qty', 'alpha'), 'MS');
197  $qty_frozen = price2num(GETPOST('qty_frozen', 'alpha'), 'MS');
198  $disable_stock_change = GETPOST('disable_stock_change', 'int');
199  $efficiency = price2num(GETPOST('efficiency', 'alpha'));
200 
201  if ($qty == '') {
202  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
203  $error++;
204  }
205 
206  $bomline = new BOMLine($db);
207  $bomline->fetch($lineid);
208  $bomline->qty = $qty;
209  $bomline->qty_frozen = (int) $qty_frozen;
210  $bomline->disable_stock_change = (int) $disable_stock_change;
211  $bomline->efficiency = $efficiency;
212 
213  $result = $bomline->update($user);
214  if ($result <= 0)
215  {
216  setEventMessages($bomline->error, $bomline->errors, 'errors');
217  $action = '';
218  } else {
219  unset($_POST['idprod']);
220  unset($_POST['qty']);
221  unset($_POST['qty_frozen']);
222  unset($_POST['disable_stock_change']);
223 
224  $object->fetchLines();
225 
226  $object->calculateCosts();
227  }
228  }
229 }
230 
231 
232 /*
233  * View
234  */
235 
236 $form = new Form($db);
237 $formfile = new FormFile($db);
238 
239 llxHeader('', $langs->trans("BOM"), '');
240 
241 // Example : Adding jquery code
242 print '<script type="text/javascript" language="javascript">
243 jQuery(document).ready(function() {
244  function init_myfunc()
245  {
246  jQuery("#myid").removeAttr(\'disabled\');
247  jQuery("#myid").attr(\'disabled\',\'disabled\');
248  }
249  init_myfunc();
250  jQuery("#mybutton").click(function() {
251  init_myfunc();
252  });
253 });
254 </script>';
255 
256 
257 // Part to create
258 if ($action == 'create')
259 {
260  print load_fiche_titre($langs->trans("NewBOM"), '', 'bom');
261 
262  print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
263  print '<input type="hidden" name="token" value="'.newToken().'">';
264  print '<input type="hidden" name="action" value="add">';
265  print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
266 
267  print dol_get_fiche_head(array(), '');
268 
269  print '<table class="border centpercent tableforfieldcreate">'."\n";
270 
271  // Common attributes
272  include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php';
273 
274  // Other attributes
275  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
276 
277  print '</table>'."\n";
278 
279  print dol_get_fiche_end();
280 
281  print '<div class="center">';
282  print '<input type="submit" class="button" name="add" value="'.dol_escape_htmltag($langs->trans("Create")).'">';
283  print '&nbsp; ';
284  print '<input type="'.($backtopage ? "submit" : "button").'" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'"'.($backtopage ? '' : ' onclick="javascript:history.go(-1)"').'>'; // Cancel for create does not post form if we don't know the backtopage
285  print '</div>';
286 
287  print '</form>';
288 }
289 
290 // Part to edit record
291 if (($id || $ref) && $action == 'edit')
292 {
293  print load_fiche_titre($langs->trans("BillOfMaterials"), '', 'cubes');
294 
295  print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
296  print '<input type="hidden" name="token" value="'.newToken().'">';
297  print '<input type="hidden" name="action" value="update">';
298  print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
299  print '<input type="hidden" name="id" value="'.$object->id.'">';
300 
301  print dol_get_fiche_head();
302 
303  //$object->fields['keyfield']['disabled'] = 1;
304 
305  print '<table class="border centpercent tableforfieldedit">'."\n";
306 
307  // Common attributes
308  include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_edit.tpl.php';
309 
310  // Other attributes
311  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php';
312 
313  print '</table>';
314 
315  print dol_get_fiche_end();
316 
317  print '<div class="center"><input type="submit" class="button button-save" name="save" value="'.$langs->trans("Save").'">';
318  print ' &nbsp; <input type="submit" class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
319  print '</div>';
320 
321  print '</form>';
322 }
323 
324 // Part to show record
325 if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create')))
326 {
327  $res = $object->fetch_optionals();
328 
329  $head = bomPrepareHead($object);
330  print dol_get_fiche_head($head, 'card', $langs->trans("BillOfMaterials"), -1, 'bom');
331 
332  $formconfirm = '';
333 
334  // Confirmation to delete
335  if ($action == 'delete')
336  {
337  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteBillOfMaterials'), $langs->trans('ConfirmDeleteBillOfMaterials'), 'confirm_delete', '', 0, 1);
338  }
339  // Confirmation to delete line
340  if ($action == 'deleteline')
341  {
342  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
343  }
344 
345  // Confirmation of validation
346  if ($action == 'validate')
347  {
348  // We check that object has a temporary ref
349  $ref = substr($object->ref, 1, 4);
350  if ($ref == 'PROV') {
351  $object->fetch_product();
352  $numref = $object->getNextNumRef($object->product);
353  } else {
354  $numref = $object->ref;
355  }
356 
357  $text = $langs->trans('ConfirmValidateBom', $numref);
358  /*if (! empty($conf->notification->enabled))
359  {
360  require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php';
361  $notify = new Notify($db);
362  $text .= '<br>';
363  $text .= $notify->confirmMessage('BOM_VALIDATE', $object->socid, $object);
364  }*/
365 
366  $formquestion = array();
367  if (!empty($conf->bom->enabled))
368  {
369  $langs->load("mrp");
370  require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
371  $formproduct = new FormProduct($db);
372  $forcecombo = 0;
373  if ($conf->browser->name == 'ie') $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
374  $formquestion = array(
375  // 'text' => $langs->trans("ConfirmClone"),
376  // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
377  // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
378  );
379  }
380 
381  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Validate'), $text, 'confirm_validate', $formquestion, 0, 1, 220);
382  }
383 
384  // Confirmation of closing
385  if ($action == 'close')
386  {
387  $text = $langs->trans('ConfirmCloseBom', $object->ref);
388  /*if (! empty($conf->notification->enabled))
389  {
390  require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php';
391  $notify = new Notify($db);
392  $text .= '<br>';
393  $text .= $notify->confirmMessage('BOM_CLOSE', $object->socid, $object);
394  }*/
395 
396  $formquestion = array();
397  if (!empty($conf->bom->enabled))
398  {
399  $langs->load("mrp");
400  require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
401  $formproduct = new FormProduct($db);
402  $forcecombo = 0;
403  if ($conf->browser->name == 'ie') $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
404  $formquestion = array(
405  // 'text' => $langs->trans("ConfirmClone"),
406  // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
407  // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
408  );
409  }
410 
411  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Close'), $text, 'confirm_close', $formquestion, 0, 1, 220);
412  }
413 
414  // Confirmation of reopen
415  if ($action == 'reopen')
416  {
417  $text = $langs->trans('ConfirmReopenBom', $object->ref);
418  /*if (! empty($conf->notification->enabled))
419  {
420  require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php';
421  $notify = new Notify($db);
422  $text .= '<br>';
423  $text .= $notify->confirmMessage('BOM_CLOSE', $object->socid, $object);
424  }*/
425 
426  $formquestion = array();
427  if (!empty($conf->bom->enabled))
428  {
429  $langs->load("mrp");
430  require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
431  $formproduct = new FormProduct($db);
432  $forcecombo = 0;
433  if ($conf->browser->name == 'ie') $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
434  $formquestion = array(
435  // 'text' => $langs->trans("ConfirmClone"),
436  // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
437  // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
438  );
439  }
440 
441  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ReOpen'), $text, 'confirm_reopen', $formquestion, 0, 1, 220);
442  }
443 
444  // Clone confirmation
445  if ($action == 'clone') {
446  // Create an array for form
447  $formquestion = array();
448  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneBillOfMaterials', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
449  }
450 
451  // Confirmation of action xxxx
452  if ($action == 'setdraft')
453  {
454  $text = $langs->trans('ConfirmSetToDraft', $object->ref);
455 
456  $formquestion = array();
457  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('SetToDraft'), $text, 'confirm_setdraft', $formquestion, 0, 1, 220);
458  }
459 
460  // Call Hook formConfirm
461  $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
462  $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
463  if (empty($reshook)) $formconfirm .= $hookmanager->resPrint;
464  elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint;
465 
466  // Print form confirm
467  print $formconfirm;
468 
469 
470  // Object card
471  // ------------------------------------------------------------
472  $linkback = '<a href="'.dol_buildpath('/bom/bom_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
473 
474  $morehtmlref = '<div class="refidno">';
475  /*
476  // Ref bis
477  $morehtmlref.=$form->editfieldkey("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->bom->creer, 'string', '', 0, 1);
478  $morehtmlref.=$form->editfieldval("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->bom->creer, 'string', '', null, null, '', 1);
479  // Thirdparty
480  $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $soc->getNomUrl(1);
481  // Project
482  if (! empty($conf->projet->enabled))
483  {
484  $langs->load("projects");
485  $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
486  if ($permissiontoadd)
487  {
488  if ($action != 'classify')
489  $morehtmlref.='<a class="editfielda" href="' . $_SERVER['PHP_SELF'] . '?action=classify&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
490  if ($action == 'classify') {
491  //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
492  $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
493  $morehtmlref.='<input type="hidden" name="action" value="classin">';
494  $morehtmlref.='<input type="hidden" name="token" value="'.newToken().'">';
495  $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', 0, 0, 1, 0, 1, 0, 0, '', 1);
496  $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
497  $morehtmlref.='</form>';
498  } else {
499  $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
500  }
501  } else {
502  if (! empty($object->fk_project)) {
503  $proj = new Project($db);
504  $proj->fetch($object->fk_project);
505  $morehtmlref.=$proj->getNomUrl();
506  } else {
507  $morehtmlref.='';
508  }
509  }
510  }
511  */
512  $morehtmlref .= '</div>';
513 
514 
515  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
516 
517 
518  print '<div class="fichecenter">';
519  print '<div class="fichehalfleft">';
520  print '<div class="underbanner clearboth"></div>';
521  print '<table class="border centpercent tableforfield">'."\n";
522 
523  // Common attributes
524  $keyforbreak = 'duration';
525  include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
526 
527  print '<tr><td>'.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).'</td><td>'.price($object->total_cost).'</td></tr>';
528  print '<tr><td>'.$langs->trans("UnitCost").'</td><td>'.price($object->unit_cost).'</td></tr>';
529 
530  // Other attributes
531  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
532 
533  print '</table>';
534  print '</div>';
535  print '</div>';
536 
537  print '<div class="clearboth"></div>';
538 
539  print dol_get_fiche_end();
540 
541 
542 
543  /*
544  * Lines
545  */
546 
547  if (!empty($object->table_element_line))
548  {
549  print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '#addline' : '').'" method="POST">
550  <input type="hidden" name="token" value="' . newToken().'">
551  <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
552  <input type="hidden" name="mode" value="">
553  <input type="hidden" name="id" value="' . $object->id.'">
554  ';
555 
556  if (!empty($conf->use_javascript_ajax) && $object->status == 0) {
557  include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
558  }
559 
560  print '<div class="div-table-responsive-no-min">';
561  if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline'))
562  {
563  print '<table id="tablelines" class="noborder noshadow" width="100%">';
564  }
565 
566  if (!empty($object->lines))
567  {
568  $object->printObjectLines($action, $mysoc, null, GETPOST('lineid', 'int'), 1, '/bom/tpl');
569  }
570 
571  // Form to add new line
572  if ($object->status == 0 && $permissiontoadd && $action != 'selectlines')
573  {
574  if ($action != 'editline')
575  {
576  // Add products/services form
577  $object->formAddObjectLine(1, $mysoc, null, '/bom/tpl');
578 
579  $parameters = array();
580  $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
581  }
582  }
583 
584  if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline'))
585  {
586  print '</table>';
587  }
588  print '</div>';
589 
590  print "</form>\n";
591  }
592 
593 
594  // Buttons for actions
595 
596  if ($action != 'presend' && $action != 'editline') {
597  print '<div class="tabsAction">'."\n";
598  $parameters = array();
599  $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
600  if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
601 
602  if (empty($reshook))
603  {
604  // Send
605  //if (empty($user->socid)) {
606  // print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=presend&mode=init#formmailbeforetitle">' . $langs->trans('SendMail') . '</a>'."\n";
607  //}
608 
609  // Back to draft
610  if ($object->status == $object::STATUS_VALIDATED)
611  {
612  if ($permissiontoadd)
613  {
614  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=setdraft&token='.newToken().'">'.$langs->trans("SetToDraft").'</a>';
615  }
616  }
617 
618  // Modify
619  if ($object->status == $object::STATUS_DRAFT)
620  {
621  if ($permissiontoadd)
622  {
623  print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=edit&amp;token='.newToken().'">'.$langs->trans("Modify").'</a>'."\n";
624  } else {
625  print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans('Modify').'</a>'."\n";
626  }
627  }
628 
629  // Validate
630  if ($object->status == $object::STATUS_DRAFT)
631  {
632  if ($permissiontoadd)
633  {
634  if (is_array($object->lines) && count($object->lines) > 0)
635  {
636  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;action=validate&amp;token='.newToken().'">'.$langs->trans("Validate").'</a>';
637  } else {
638  $langs->load("errors");
639  print '<a class="butActionRefused" href="" title="'.$langs->trans("ErrorAddAtLeastOneLineFirst").'">'.$langs->trans("Validate").'</a>';
640  }
641  }
642  }
643 
644  // Re-open
645  if ($permissiontoadd && $object->status == $object::STATUS_CANCELED)
646  {
647  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=reopen">'.$langs->trans("ReOpen").'</a>';
648  }
649 
650  // Create MO
651  if ($conf->mrp->enabled)
652  {
653  if ($object->status == $object::STATUS_VALIDATED && !empty($user->rights->mrp->write))
654  {
655  print '<a class="butAction" href="'.DOL_URL_ROOT.'/mrp/mo_card.php?action=create&fk_bom='.$object->id.'&backtopageforcancel='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id).'">'.$langs->trans("CreateMO").'</a>';
656  }
657  }
658 
659  // Clone
660  if ($permissiontoadd)
661  {
662  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=clone&object=bom">'.$langs->trans("ToClone").'</a>';
663  }
664 
665  // Close / Cancel
666  if ($permissiontoadd && $object->status == $object::STATUS_VALIDATED)
667  {
668  print '<a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=close">'.$langs->trans("Disable").'</a>';
669  }
670 
671  /*
672  if ($user->rights->bom->write)
673  {
674  if ($object->status == 1)
675  {
676  print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=disable">'.$langs->trans("Disable").'</a>'."\n";
677  }
678  else
679  {
680  print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=enable">'.$langs->trans("Enable").'</a>'."\n";
681  }
682  }
683  */
684 
685  if ($permissiontodelete)
686  {
687  print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delete&amp;token='.newToken().'">'.$langs->trans('Delete').'</a>'."\n";
688  } else {
689  print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans('Delete').'</a>'."\n";
690  }
691  }
692  print '</div>'."\n";
693  }
694 
695 
696  // Select mail models is same action as presend
697  if (GETPOST('modelselected')) {
698  $action = 'presend';
699  }
700 
701  if ($action != 'presend')
702  {
703  print '<div class="fichecenter"><div class="fichehalfleft">';
704  print '<a name="builddoc"></a>'; // ancre
705 
706  // Documents
707  $objref = dol_sanitizeFileName($object->ref);
708  $relativepath = $objref.'/'.$objref.'.pdf';
709  $filedir = $conf->bom->dir_output.'/'.$objref;
710  $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
711  $genallowed = $user->rights->bom->read; // If you can read, you can build the PDF to read content
712  $delallowed = $user->rights->bom->write; // If you can create/edit, you can remove a file on card
713  print $formfile->showdocuments('bom', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang);
714 
715  // Show links to link elements
716  $linktoelem = $form->showLinkToObjectBlock($object, null, array('bom'));
717  $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
718 
719 
720  print '</div><div class="fichehalfright"><div class="ficheaddleft">';
721 
722  $MAXEVENT = 10;
723 
724  $morehtmlright = '<a href="'.dol_buildpath('/bom/bom_agenda.php', 1).'?id='.$object->id.'">';
725  $morehtmlright .= $langs->trans("SeeAll");
726  $morehtmlright .= '</a>';
727 
728  // List of actions on element
729  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
730  $formactions = new FormActions($db);
731  $somethingshown = $formactions->showactions($object, 'bom', $socid, 1, '', $MAXEVENT, '', $morehtmlright);
732 
733  print '</div></div></div>';
734  }
735 
736  //Select mail models is same action as presend
737  if (GETPOST('modelselected')) $action = 'presend';
738 
739  // Presend form
740  $modelmail = 'bom';
741  $defaulttopic = 'InformationMessage';
742  $diroutput = $conf->bom->dir_output;
743  $trackid = 'bom'.$object->id;
744 
745  include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
746 }
747 
748 // End of page
749 llxFooter();
750 $db->close();
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
if(preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) if(preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) if($action== 'set') elseif($action== 'specimen') elseif($action== 'setmodel') elseif($action== 'del') elseif($action== 'setdoc') $formactions
View.
Class to manage building of HTML components.
Class for BOM.
Definition: bom.class.php:32
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
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...
Class with static methods for building HTML components related to products Only components common to ...
llxHeader()
Empty header.
Definition: wrapper.php:45
Class to manage standard extra fields.
setEventMessages($mesg, $mesgs, $style= 'mesgs', $messagekey= '')
Set event messages in dol_events session object.
Class to manage generation of HTML components Only common components must be here.
bomPrepareHead($object)
Prepare array of tabs for BillOfMaterials.
Definition: bom.lib.php:77
Class for BOMLine.
Definition: bom.class.php:1075
load_fiche_titre($titre, $morehtmlright= '', $picto= 'generic', $pictoisfullpath=0, $id= '', $morecssontable= '', $morehtmlcenter= '')
Load a title with picto.
price2num($amount, $rounding= '', $option=0)
Function that return a number with universal decimal format (decimal separator is &#39;...
dol_sanitizeFileName($str, $newstr= '_', $unaccent=1)
Clean a string to use it as a file name.
Class to offer components to list and upload files.
print $_SERVER["PHP_SELF"]
Edit parameters.
dol_get_fiche_head($links=array(), $active= '', $title= '', $notab=0, $picto= '', $pictoisfullpath=0, $morehtmlright= '', $morecss= '', $limittoshow=0, $moretabssuffix= '')
Show tabs of a record.
print
Draft customers invoices.
Definition: index.php:89
newToken()
Return the value of token currently saved into session with name &#39;newtoken&#39;.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
print $_SERVER["PHP_SELF"] n
Edit parameters.
Definition: categories.php:101
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.
llxFooter()
Empty footer.
Definition: wrapper.php:59
if(!defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN'
Draft customers invoices.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $keepmoretags= '', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...