dolibarr 19.0.3
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
26require '../main.inc.php';
27require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
28require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
29require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
30require_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();
63foreach ($object->fields as $key => $val) {
64 if (GETPOST('search_'.$key, 'alpha')) {
65 $search[$key] = GETPOST('search_'.$key, 'alpha');
66 }
67}
68
69if (empty($action) && empty($id) && empty($ref)) {
70 $action = 'view';
71}
72
73// Load object
74include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
75if ($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
100if ($reshook < 0) {
101 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
102}
103
104if (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') {
119 $object->getNetNeedsTree($TChildBom, 1);
120 } else {
121 $object->getNetNeeds($TChildBom, 1);
122 }
123}
124
125
126/*
127 * View
128 */
129
130$form = new Form($db);
131$formfile = new FormFile($db);
132
133$title = $langs->trans('BOM');
134$help_url ='EN:Module_BOM';
135llxHeader('', $title, $help_url);
136
137
138// Part to show record
139if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
140 $head = bomPrepareHead($object);
141 print dol_get_fiche_head($head, 'net_needs', $langs->trans("BillOfMaterials"), -1, 'bom');
142
143 $formconfirm = '';
144
145 // Call Hook formConfirm
146 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
147 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
148 if (empty($reshook)) {
149 $formconfirm .= $hookmanager->resPrint;
150 } elseif ($reshook > 0) {
151 $formconfirm = $hookmanager->resPrint;
152 }
153
154 // Print form confirm
155 print $formconfirm;
156
157
158 // Object card
159 // ------------------------------------------------------------
160 $linkback = '<a href="'.DOL_URL_ROOT.'/bom/bom_list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
161
162 $morehtmlref = '<div class="refidno">';
163
164 $morehtmlref .= '</div>';
165
166
167 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
168
169
170 print '<div class="fichecenter">';
171 print '<div class="fichehalfleft">';
172 print '<div class="underbanner clearboth"></div>';
173 print '<table class="border centpercent tableforfield">'."\n";
174
175 // Common attributes
176 $keyforbreak = 'duration';
177 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
178
179 print '<tr><td>'.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).'</td><td><span class="amount">'.price($object->total_cost).'</span></td></tr>';
180 print '<tr><td>'.$langs->trans("UnitCost").'</td><td>'.price($object->unit_cost).'</td></tr>';
181
182 // Other attributes
183 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
184
185 print '</table>';
186 print '</div>';
187 print '</div>';
188
189 print '<div class="clearboth"></div>';
190
191 print dol_get_fiche_end();
192
193 $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' : '')));
194 $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' : '')));
195
196 print load_fiche_titre($langs->trans("BOMNetNeeds"), $viewlink, 'product');
197
198 /*
199 * Lines
200 */
201 $text_stock_options = $langs->trans("RealStockDesc").'<br>';
202 $text_stock_options .= $langs->trans("RealStockWillAutomaticallyWhen").'<br>';
203 $text_stock_options .= (getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT') || getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT_CLOSE') ? '- '.$langs->trans("DeStockOnShipment").'<br>' : '');
204 $text_stock_options .= (getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') ? '- '.$langs->trans("DeStockOnValidateOrder").'<br>' : '');
205 $text_stock_options .= (getDolGlobalString('STOCK_CALCULATE_ON_BILL') ? '- '.$langs->trans("DeStockOnBill").'<br>' : '');
206 $text_stock_options .= (getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') ? '- '.$langs->trans("ReStockOnBill").'<br>' : '');
207 $text_stock_options .= (getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER') ? '- '.$langs->trans("ReStockOnValidateOrder").'<br>' : '');
208 $text_stock_options .= (getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER') ? '- '.$langs->trans("ReStockOnDispatchOrder").'<br>' : '');
209 $text_stock_options .= (getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION') || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE') ? '- '.$langs->trans("StockOnReception").'<br>' : '');
210
211 print '<table id="tablelines" class="noborder noshadow" width="100%">';
212 print "<thead>\n";
213 print '<tr class="liste_titre nodrag nodrop">';
214 print '<td class="linecoldescription">'.$langs->trans('Product');
215 if (getDolGlobalString('BOM_SUB_BOM') && $action == 'treeview') {
216 print ' &nbsp; <a id="show_all" href="#">'.img_picto('', 'folder-open', 'class="paddingright"').$langs->trans("ExpandAll").'</a>&nbsp;&nbsp;';
217 print '<a id="hide_all" href="#">'.img_picto('', 'folder', 'class="paddingright"').$langs->trans("UndoExpandAll").'</a>&nbsp;';
218 }
219 print '</td>';
220 if ($action == 'treeview') {
221 print '<td class="left">'.$langs->trans('ProducedBy').'</td>';
222 }
223 print '<td class="linecolqty right">'.$langs->trans('Quantity').'</td>';
224 print '<td class="linecolstock right">'.$form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1).'</td>';
225 print '<td class="linecoltheoricalstock right">'.$form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc")).'</td>';
226 print '</tr>';
227
228 print '</thead>';
229 print '<tbody>';
230 if (!empty($TChildBom)) {
231 if ($action == 'treeview') {
232 foreach ($TChildBom as $fk_bom => $TProduct) {
233 $repeatChar = '&emsp;';
234 if (!empty($TProduct['bom'])) {
235 $prod = new Product($db);
236 $prod->fetch($TProduct['bom']->fk_product);
237 if ($TProduct['parentid'] != $object->id) {
238 print '<tr class="sub_bom_lines oddeven" parentid="'.$TProduct['parentid'].'">';
239 } else {
240 print '<tr class="oddeven">';
241 }
242 if ($action == 'treeview') {
243 print '<td class="linecoldescription">'.str_repeat($repeatChar, $TProduct['level']).$prod->getNomUrl(1);
244 } else {
245 print '<td class="linecoldescription">'.str_repeat($repeatChar, $TProduct['level']).$TProduct['bom']->getNomUrl(1);
246 }
247 print ' <a class="collapse_bom" id="collapse-'.$fk_bom.'" href="#">';
248 print img_picto('', 'folder-open');
249 print '</a>';
250 print '</td>';
251 if ($action == 'treeview') {
252 print '<td class="left">'.$TProduct['bom']->getNomUrl(1).'</td>';
253 }
254 print '<td class="linecolqty right">'.$TProduct['qty'].'</td>';
255 print '<td class="linecolstock right"></td>';
256 print '<td class="linecoltheoricalstock right"></td>';
257 print '</tr>';
258 }
259 if (!empty($TProduct['product'])) {
260 foreach ($TProduct['product'] as $fk_product => $TInfos) {
261 $prod = new Product($db);
262 $prod->fetch($fk_product);
263 $prod->load_virtual_stock();
264 if (empty($prod->stock_reel)) {
265 $prod->stock_reel = 0;
266 }
267 if ($fk_bom != $object->id) {
268 print '<tr class="sub_bom_lines oddeven" parentid="'.$fk_bom.'">';
269 } else {
270 print '<tr class="oddeven">';
271 }
272 print '<td class="linecoldescription">'.str_repeat($repeatChar, $TInfos['level']).$prod->getNomUrl(1).'</td>';
273 if ($action == 'treeview') {
274 print '<td></td>';
275 }
276 print '<td class="linecolqty right">'.$TInfos['qty'].'</td>';
277 print '<td class="linecolstock right">'.price2num($prod->stock_reel, 'MS').'</td>';
278 print '<td class="linecoltheoricalstock right">'.$prod->stock_theorique.'</td>';
279 print '</tr>';
280 }
281 }
282 }
283 } else {
284 foreach ($TChildBom as $fk_product => $qty) {
285 $prod = new Product($db);
286 $prod->fetch($fk_product);
287 $prod->load_virtual_stock();
288 if (empty($prod->stock_reel)) {
289 $prod->stock_reel = 0;
290 }
291 print '<tr class="oddeven">';
292 print '<td class="linecoldescription">'.$prod->getNomUrl(1).'</td>';
293 print '<td class="linecolqty right">'.$qty.'</td>';
294 print '<td class="linecolstock right">'.price2num($prod->stock_reel, 'MS').'</td>';
295 print '<td class="linecoltheoricalstock right">'.$prod->stock_theorique.'</td>';
296 print '</tr>';
297 }
298 }
299 }
300 print '</tbody>';
301 print '</table>';
302
303
304
305 /*
306 * ButAction
307 */
308 print '<div class="tabsAction">'."\n";
309 $parameters = array();
310 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
311 if ($reshook < 0) {
312 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
313 }
314 print '</div>'; ?>
315
316 <script type="text/javascript" language="javascript">
317 $(document).ready(function() {
318
319 function folderManage(element) {
320 var id_bom_line = element.attr('id').replace('collapse-', '');
321 let TSubLines = $('[parentid="'+ id_bom_line +'"]');
322
323 if(element.html().indexOf('folder-open') <= 0) {
324 $('[parentid="'+ id_bom_line +'"]').show();
325 element.html('<?php echo dol_escape_js(img_picto('', 'folder-open')); ?>');
326 }
327 else {
328 for (let i = 0; i < TSubLines.length; i++) {
329 let subBomFolder = $(TSubLines[i]).children('.linecoldescription').children('.collapse_bom');
330 if (subBomFolder.length > 0) {
331 folderManage(subBomFolder);
332 }
333 }
334 TSubLines.hide();
335 element.html('<?php echo dol_escape_js(img_picto('', 'folder')); ?>');
336 }
337 }
338
339 // When clicking on collapse
340 $(".collapse_bom").click(function() {
341 folderManage($(this));
342 return false;
343 });
344
345 // To Show all the sub bom lines
346 $("#show_all").click(function() {
347 console.log("We click on show all");
348 $("[class^=sub_bom_lines]").show();
349 $("[class^=collapse_bom]").html('<?php echo dol_escape_js(img_picto('', 'folder-open')); ?>');
350 return false;
351 });
352
353 // To Hide all the sub bom lines
354 $("#hide_all").click(function() {
355 console.log("We click on hide all");
356 $("[class^=sub_bom_lines]").hide();
357 $("[class^=collapse_bom]").html('<?php echo dol_escape_js(img_picto('', 'folder')); ?>');
358 return false;
359 });
360
361 });
362 </script>
363
364 <?php
365}
366
367// End of page
368llxFooter();
369$db->close();
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Definition wrapper.php:55
llxFooter()
Empty footer.
Definition wrapper.php:69
bomPrepareHead($object)
Prepare array of tabs for BillOfMaterials.
Definition bom.lib.php:78
Class for BOM.
Definition bom.class.php:43
Class to manage standard extra fields.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class to manage products or services.
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.
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
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.
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.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
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.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:121
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.