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 require_once DOL_DOCUMENT_ROOT.
'/mrp/lib/mrp.lib.php';
35 $langs->loadLangs(array(
"mrp",
"other"));
40 $action =
GETPOST(
'action',
'aZ09');
41 $confirm =
GETPOST(
'confirm',
'alpha');
42 $cancel =
GETPOST(
'cancel',
'aZ09');
43 $contextpage =
GETPOST(
'contextpage',
'aZ') ?
GETPOST(
'contextpage',
'aZ') :
'bomcard';
44 $backtopage =
GETPOST(
'backtopage',
'alpha');
45 $lineid =
GETPOST(
'lineid',
'int');
48 $hidedetails = (
GETPOST(
'hidedetails',
'int') ?
GETPOST(
'hidedetails',
'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0));
49 $hidedesc = (
GETPOST(
'hidedesc',
'int') ?
GETPOST(
'hidedesc',
'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0));
50 $hideref = (
GETPOST(
'hideref',
'int') ?
GETPOST(
'hideref',
'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0));
53 $object =
new BOM($db);
55 $diroutputmassaction = $conf->bom->dir_output.
'/temp/massgeneration/'.$user->id;
56 $hookmanager->initHooks(array(
'bomcard',
'globalcard'));
58 $extrafields->fetch_name_optionals_label($object->table_element);
59 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element,
'',
'search_');
62 $search_all =
GETPOST(
"search_all",
'alpha');
64 foreach ($object->fields as $key => $val) {
65 if (
GETPOST(
'search_'.$key,
'alpha')) {
66 $search[$key] =
GETPOST(
'search_'.$key,
'alpha');
70 if (empty($action) && empty($id) && empty($ref)) {
75 include DOL_DOCUMENT_ROOT.
'/core/actions_fetchobject.inc.php';
76 if ($object->id > 0) {
77 $object->calculateCosts();
84 $isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
85 $result =
restrictedArea($user,
'bom', $object->id,
'bom_bom',
'',
'',
'rowid', $isdraft);
87 $permissionnote = $user->rights->bom->write;
88 $permissiondellink = $user->rights->bom->write;
89 $permissiontoadd = $user->rights->bom->write;
90 $permissiontodelete = $user->rights->bom->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
91 $upload_dir = $conf->bom->multidir_output[isset($object->entity) ? $object->entity : 1];
98 $parameters = array();
99 $reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
104 if (empty($reshook)) {
107 $backurlforlist = DOL_URL_ROOT.
'/bom/bom_list.php';
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;
114 $backtopage = DOL_URL_ROOT.
'/bom/bom_card.php?id='.($id > 0 ? $id :
'__ID__');
119 $triggermodname =
'BOM_MODIFY';
123 include DOL_DOCUMENT_ROOT.
'/core/actions_addupdatedelete.inc.php';
125 if ($action ==
'confirm_validate' && $object->id > 0) {
126 $object->calculateCosts();
130 include DOL_DOCUMENT_ROOT.
'/core/actions_dellink.inc.php';
133 include DOL_DOCUMENT_ROOT.
'/core/actions_printing.inc.php';
139 include DOL_DOCUMENT_ROOT.
'/core/actions_builddoc.inc.php';
142 $triggersendname =
'BOM_SENTBYMAIL';
143 $autocopy =
'MAIN_MAIL_AUTOCOPY_BOM_TO';
144 $trackid =
'bom'.$object->id;
145 include DOL_DOCUMENT_ROOT.
'/core/actions_sendmails.inc.php';
148 if ($action ==
'addline' && $user->rights->bom->write) {
149 $langs->load(
'errors');
153 $bom_child_id = (int)
GETPOST(
'bom_id',
'int');
154 if ($bom_child_id > 0) {
155 $bom_child =
new BOM($db);
156 $res = $bom_child->fetch($bom_child_id);
158 $idprod = $bom_child->fk_product;
161 $idprod = (int)
GETPOST(
'idprod',
'int');
166 $disable_stock_change =
GETPOST(
'disable_stock_change',
'int');
170 setEventMessages($langs->trans(
'ErrorFieldRequired', $langs->transnoentitiesnoconv(
'Qty')),
null,
'errors');
173 if (!($idprod > 0)) {
174 setEventMessages($langs->trans(
'ErrorFieldRequired', $langs->transnoentitiesnoconv(
'Product')),
null,
'errors');
178 if ($object->fk_product == $idprod) {
179 setEventMessages($langs->trans(
'TheProductXIsAlreadyTheProductToProduce'),
null,
'errors');
185 $object->getParentBomTreeRecursive($TParentBom);
186 if ($bom_child_id > 0 && !empty($TParentBom) && in_array($bom_child_id, $TParentBom)) {
187 $n_child =
new BOM($db);
188 $n_child->fetch($bom_child_id);
189 setEventMessages($langs->transnoentities(
'BomCantAddChildBom', $n_child->getNomUrl(1), $object->getNomUrl(1)),
null,
'errors');
195 $bomline->fk_bom = $id;
196 $bomline->fk_product = $idprod;
197 $bomline->fk_bom_child = $bom_child_id;
198 $bomline->qty = $qty;
199 $bomline->qty_frozen = (int) $qty_frozen;
200 $bomline->disable_stock_change = (int) $disable_stock_change;
201 $bomline->efficiency = $efficiency;
204 $rangmax = $object->line_max(0);
205 $ranktouse = $rangmax + 1;
207 $bomline->position = ($ranktouse + 1);
209 $result = $bomline->create($user);
214 unset($_POST[
'idprod']);
215 unset($_POST[
'qty']);
216 unset($_POST[
'qty_frozen']);
217 unset($_POST[
'disable_stock_change']);
219 $object->fetchLines();
221 $object->calculateCosts();
227 if ($action ==
'updateline' && $user->rights->bom->write) {
228 $langs->load(
'errors');
234 $disable_stock_change =
GETPOST(
'disable_stock_change',
'int');
238 setEventMessages($langs->trans(
'ErrorFieldRequired', $langs->transnoentitiesnoconv(
'Qty')),
null,
'errors');
243 $bomline->fetch($lineid);
244 $bomline->qty = $qty;
245 $bomline->qty_frozen = (int) $qty_frozen;
246 $bomline->disable_stock_change = (int) $disable_stock_change;
247 $bomline->efficiency = $efficiency;
249 $result = $bomline->update($user);
254 unset($_POST[
'idprod']);
255 unset($_POST[
'qty']);
256 unset($_POST[
'qty_frozen']);
257 unset($_POST[
'disable_stock_change']);
259 $object->fetchLines();
261 $object->calculateCosts();
276 $title = $langs->trans(
'BOM');
281 if ($action ==
'create') {
284 print
'<form method="POST" action="'.$_SERVER[
"PHP_SELF"].
'">';
285 print
'<input type="hidden" name="token" value="'.newToken().
'">';
286 print
'<input type="hidden" name="action" value="add">';
287 print
'<input type="hidden" name="backtopage" value="'.$backtopage.
'">';
291 print
'<table class="border centpercent tableforfieldcreate">'.
"\n";
294 include DOL_DOCUMENT_ROOT.
'/core/tpl/commonfields_add.tpl.php';
297 include DOL_DOCUMENT_ROOT.
'/core/tpl/extrafields_add.tpl.php';
299 print
'</table>'.
"\n";
303 print
$form->buttonsSaveCancel(
"Create");
309 if (($id || $ref) && $action ==
'edit') {
312 print
'<form method="POST" action="'.$_SERVER[
"PHP_SELF"].
'">';
313 print
'<input type="hidden" name="token" value="'.newToken().
'">';
314 print
'<input type="hidden" name="action" value="update">';
315 print
'<input type="hidden" name="backtopage" value="'.$backtopage.
'">';
316 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
322 print
'<table class="border centpercent tableforfieldedit">'.
"\n";
325 include DOL_DOCUMENT_ROOT.
'/core/tpl/commonfields_edit.tpl.php';
328 include DOL_DOCUMENT_ROOT.
'/core/tpl/extrafields_edit.tpl.php';
334 print
$form->buttonsSaveCancel(
"Create");
340 if ($object->id > 0 && (empty($action) || ($action !=
'edit' && $action !=
'create'))) {
347 if ($action ==
'delete') {
348 $formconfirm =
$form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.$object->id, $langs->trans(
'DeleteBillOfMaterials'), $langs->trans(
'ConfirmDeleteBillOfMaterials'),
'confirm_delete',
'', 0, 1);
351 if ($action ==
'deleteline') {
352 $formconfirm =
$form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'&lineid='.$lineid, $langs->trans(
'DeleteLine'), $langs->trans(
'ConfirmDeleteLine'),
'confirm_deleteline',
'', 0, 1);
356 if ($action ==
'validate') {
358 $ref = substr($object->ref, 1, 4);
359 if ($ref ==
'PROV') {
360 $object->fetch_product();
361 $numref = $object->getNextNumRef($object->product);
363 $numref = $object->ref;
366 $text = $langs->trans(
'ConfirmValidateBom', $numref);
375 $formquestion = array();
376 if (!empty($conf->bom->enabled)) {
379 if ($conf->browser->name ==
'ie') {
382 $formquestion = array(
389 $formconfirm =
$form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.$object->id, $langs->trans(
'Validate'), $text,
'confirm_validate', $formquestion, 0, 1, 220);
393 if ($action ==
'close') {
394 $text = $langs->trans(
'ConfirmCloseBom', $object->ref);
403 $formquestion = array();
404 if (!empty($conf->bom->enabled)) {
407 if ($conf->browser->name ==
'ie') {
410 $formquestion = array(
417 $formconfirm =
$form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.$object->id, $langs->trans(
'Close'), $text,
'confirm_close', $formquestion, 0, 1, 220);
421 if ($action ==
'reopen') {
422 $text = $langs->trans(
'ConfirmReopenBom', $object->ref);
431 $formquestion = array();
432 if (!empty($conf->bom->enabled)) {
434 require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
436 if ($conf->browser->name ==
'ie') {
439 $formquestion = array(
446 $formconfirm =
$form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.$object->id, $langs->trans(
'ReOpen'), $text,
'confirm_reopen', $formquestion, 0, 1, 220);
450 if ($action ==
'clone') {
452 $formquestion = array();
453 $formconfirm =
$form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.$object->id, $langs->trans(
'ToClone'), $langs->trans(
'ConfirmCloneBillOfMaterials', $object->ref),
'confirm_clone', $formquestion,
'yes', 1);
457 if ($action ==
'setdraft') {
458 $text = $langs->trans(
'ConfirmSetToDraft', $object->ref);
460 $formquestion = array();
461 $formconfirm =
$form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.$object->id, $langs->trans(
'SetToDraft'), $text,
'confirm_setdraft', $formquestion, 0, 1, 220);
465 $parameters = array(
'formConfirm' =>
$formconfirm,
'lineid' => $lineid);
466 $reshook = $hookmanager->executeHooks(
'formConfirm', $parameters, $object, $action);
467 if (empty($reshook)) {
469 } elseif ($reshook > 0) {
479 $linkback =
'<a href="'.DOL_URL_ROOT.
'/bom/bom_list.php?restore_lastsearch_values=1'.(!empty($socid) ?
'&socid='.$socid :
'').
'">'.$langs->trans(
"BackToList").
'</a>';
481 $morehtmlref =
'<div class="refidno">';
519 $morehtmlref .=
'</div>';
522 dol_banner_tab($object,
'ref', $linkback, 1,
'ref',
'ref', $morehtmlref);
525 print
'<div class="fichecenter">';
526 print
'<div class="fichehalfleft">';
527 print
'<div class="underbanner clearboth"></div>';
528 print
'<table class="border centpercent tableforfield">'.
"\n";
531 $keyforbreak =
'duration';
532 include DOL_DOCUMENT_ROOT.
'/core/tpl/commonfields_view.tpl.php';
533 $object->calculateCosts();
534 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"TotalCost"), $langs->trans(
"BOMTotalCost")).
'</td><td><span class="amount">'.
price($object->total_cost).
'</span></td></tr>';
535 print
'<tr><td>'.$langs->trans(
"UnitCost").
'</td><td>'.
price($object->unit_cost).
'</td></tr>';
538 include DOL_DOCUMENT_ROOT.
'/core/tpl/extrafields_view.tpl.php';
544 print
'<div class="clearboth"></div>';
554 if (!empty($object->table_element_line)) {
555 print
' <form name="addproduct" id="addproduct" action="'.$_SERVER[
"PHP_SELF"].
'?id='.$object->id.(($action !=
'editline') ?
'' :
'').
'" method="POST">
556 <input type="hidden" name="token" value="' .
newToken().
'">
557 <input type="hidden" name="action" value="' . (($action !=
'editline') ?
'addline' :
'updateline').
'">
558 <input type="hidden" name="mode" value="">
559 <input type="hidden" name="page_y" value="">
560 <input type="hidden" name="id" value="' . $object->id.
'">
563 if (!empty($conf->use_javascript_ajax) && $object->status == 0) {
564 include DOL_DOCUMENT_ROOT.
'/core/tpl/ajaxrow.tpl.php';
567 print
'<div class="div-table-responsive-no-min">';
568 if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action !=
'selectlines' && $action !=
'editline')) {
569 print
'<table id="tablelines" class="noborder noshadow" width="100%">';
572 if (!empty($object->lines)) {
573 $object->printObjectLines($action, $mysoc,
null,
GETPOST(
'lineid',
'int'), 1,
'/bom/tpl');
577 if ($object->status == 0 && $permissiontoadd && $action !=
'selectlines') {
578 if ($action !=
'editline') {
582 $parameters = array();
583 $reshook = $hookmanager->executeHooks(
'formAddObjectLine', $parameters, $object, $action);
584 if ($reshook < 0)
setEventMessages($hookmanager->error, $hookmanager->errors,
'errors');
586 $object->formAddObjectLine(1, $mysoc,
null,
'/bom/tpl');
590 if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action !=
'selectlines' && $action !=
'editline')) {
603 if ($action !=
'presend' && $action !=
'editline') {
604 print
'<div class="tabsAction">'.
"\n";
605 $parameters = array();
606 $reshook = $hookmanager->executeHooks(
'addMoreActionsButtons', $parameters, $object, $action);
611 if (empty($reshook)) {
618 if ($object->status == $object::STATUS_VALIDATED) {
619 if ($permissiontoadd) {
620 print
'<a class="butAction" href="'.$_SERVER[
'PHP_SELF'].
'?id='.$object->id.
'&action=setdraft&token='.
newToken().
'">'.$langs->trans(
"SetToDraft").
'</a>'.
"\n";
625 if ($object->status == $object::STATUS_DRAFT) {
626 if ($permissiontoadd) {
627 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'&action=edit&token='.
newToken().
'">'.$langs->trans(
"Modify").
'</a>'.
"\n";
629 print
'<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans(
"NotEnoughPermissions")).
'">'.$langs->trans(
'Modify').
'</a>'.
"\n";
634 if ($object->status == $object::STATUS_DRAFT) {
635 if ($permissiontoadd) {
636 if (is_array($object->lines) && count($object->lines) > 0) {
637 print
'<a class="butAction" href="'.$_SERVER[
'PHP_SELF'].
'?id='.$object->id.
'&action=validate&token='.
newToken().
'">'.$langs->trans(
"Validate").
'</a>'.
"\n";
639 $langs->load(
"errors");
640 print
'<a class="butActionRefused" href="" title="'.$langs->trans(
"ErrorAddAtLeastOneLineFirst").
'">'.$langs->trans(
"Validate").
'</a>'.
"\n";
646 if ($permissiontoadd && $object->status == $object::STATUS_CANCELED) {
647 print
'<a class="butAction" href="'.$_SERVER[
'PHP_SELF'].
'?id='.$object->id.
'&action=reopen&token='.
newToken().
'">'.$langs->trans(
"ReOpen").
'</a>'.
"\n";
652 if ($object->status == $object::STATUS_VALIDATED && !empty($user->rights->mrp->write)) {
653 print
'<a class="butAction" href="'.DOL_URL_ROOT.
'/mrp/mo_card.php?action=create&fk_bom='.$object->id.
'&token='.
newToken().
'&backtopageforcancel='.urlencode($_SERVER[
"PHP_SELF"].
'?id='.$object->id).
'">'.$langs->trans(
"CreateMO").
'</a>'.
"\n";
658 if ($permissiontoadd) {
659 print
'<a class="butAction" href="'.$_SERVER[
'PHP_SELF'].
'?id='.$object->id.
'&action=clone&object=bom&token='.
newToken().
'">'.$langs->trans(
"ToClone").
'</a>'.
"\n";
663 if ($permissiontoadd && $object->status == $object::STATUS_VALIDATED) {
664 print
'<a class="butActionDelete" href="'.$_SERVER[
'PHP_SELF'].
'?id='.$object->id.
'&action=close&token='.
newToken().
'">'.$langs->trans(
"Disable").
'</a>'.
"\n";
681 if ($permissiontodelete) {
682 print
'<a class="butActionDelete" href="'.$_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'&action=delete&token='.
newToken().
'">'.$langs->trans(
'Delete').
'</a>'.
"\n";
684 print
'<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans(
"NotEnoughPermissions")).
'">'.$langs->trans(
'Delete').
'</a>'.
"\n";
692 if (
GETPOST(
'modelselected')) {
696 if ($action !=
'presend') {
697 print
'<div class="fichecenter"><div class="fichehalfleft">';
698 print
'<a name="builddoc"></a>';
702 $relativepath = $objref.
'/'.$objref.
'.pdf';
703 $filedir = $conf->bom->dir_output.
'/'.$objref;
704 $urlsource = $_SERVER[
"PHP_SELF"].
"?id=".$object->id;
705 $genallowed = $user->rights->bom->read;
706 $delallowed = $user->rights->bom->write;
707 print $formfile->showdocuments(
'bom', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0,
'',
'',
'', $langs->defaultlang);
710 $linktoelem =
$form->showLinkToObjectBlock($object,
null, array(
'bom'));
711 $somethingshown =
$form->showLinkedObjectBlock($object, $linktoelem);
714 print
'</div><div class="fichehalfright">';
718 $morehtmlcenter =
dolGetButtonTitle($langs->trans(
'SeeAll'),
'',
'fa fa-bars imgforviewmode', DOL_URL_ROOT.
'/bom/bom_agenda.php?id='.$object->id);
721 include_once DOL_DOCUMENT_ROOT.
'/core/class/html.formactions.class.php';
723 $somethingshown =
$formactions->showactions($object, $object->element, 0, 1,
'', $MAXEVENT,
'', $morehtmlcenter);
725 print
'</div></div>';
729 if (
GETPOST(
'modelselected')) {
735 $defaulttopic =
'InformationMessage';
736 $diroutput = $conf->bom->dir_output;
737 $trackid =
'bom'.$object->id;
739 include DOL_DOCUMENT_ROOT.
'/core/tpl/card_presend.tpl.php';