dolibarr 21.0.0-beta
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-2024 Frédéric France <frederic.france@free.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
40// Load translation files required by the page
41$langs->loadLangs(array("mrp", "other", "stocks"));
42
43// Get parameters
44$id = GETPOSTINT('id');
45$lineid = GETPOSTINT('lineid');
46$ref = GETPOST('ref', 'alpha');
47$action = GETPOST('action', 'aZ09');
48$confirm = GETPOST('confirm', 'alpha');
49$cancel = GETPOST('cancel', 'aZ09');
50$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'bomnet_needs'; // To manage different context of search
51$backtopage = GETPOST('backtopage', 'alpha');
52
53
54// Initialize a technical objects
55$object = new BOM($db);
56$extrafields = new ExtraFields($db);
57
58// Initialize a technical objects for hooks
59$hookmanager->initHooks(array('bomnetneeds')); // Note that conf->hooks_modules contains array
60
61// Massaction
62$diroutputmassaction = $conf->bom->dir_output.'/temp/massgeneration/'.$user->id;
63
64// Fetch optionals attributes and labels
65$extrafields->fetch_name_optionals_label($object->table_element);
66$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
67
68// Initialize array of search criteria
69$search_all = GETPOST("search_all", 'alpha');
70$search = array();
71foreach ($object->fields as $key => $val) {
72 if (GETPOST('search_'.$key, 'alpha')) {
73 $search[$key] = GETPOST('search_'.$key, 'alpha');
74 }
75}
76
77if (empty($action) && empty($id) && empty($ref)) {
78 $action = 'view';
79}
80
81// Load object
82include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'.
83if ($object->id > 0) {
84 $object->calculateCosts();
85}
86
87
88// Security check - Protection if external user
89//if ($user->socid > 0) accessforbidden();
90//if ($user->socid > 0) $socid = $user->socid;
91$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
92$result = restrictedArea($user, 'bom', $object->id, $object->table_element, '', '', 'rowid', $isdraft);
93
94// Permissions
95$permissionnote = $user->hasRight('bom', 'write'); // Used by the include of actions_setnotes.inc.php
96$permissiondellink = $user->hasRight('bom', 'write'); // Used by the include of actions_dellink.inc.php
97$permissiontoadd = $user->hasRight('bom', 'write'); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
98$permissiontodelete = $user->hasRight('bom', 'delete') || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
99$upload_dir = $conf->bom->multidir_output[isset($object->entity) ? $object->entity : 1];
100
101
102/*
103 * Actions
104 */
105
106$parameters = array();
107$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
108if ($reshook < 0) {
109 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
110}
111
112if (empty($reshook)) {
113 $error = 0;
114
115 $backurlforlist = DOL_URL_ROOT.'/bom/bom_list.php';
116
117 if (empty($backtopage) || ($cancel && empty($id))) {
118 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
119 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
120 $backtopage = $backurlforlist;
121 } else {
122 $backtopage = DOL_URL_ROOT.'/bom/bom_net_needs.php?id='.($id > 0 ? $id : '__ID__');
123 }
124 }
125 }
126}
127
128
129/*
130 * View
131 */
132
133$form = new Form($db);
134$formfile = new FormFile($db);
135
136$title = $langs->trans('BOM');
137$help_url ='EN:Module_BOM';
138
139llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-bom page-net_needs');
140
141
142$TChildBom = array();
143if ($action == 'treeview') {
144 $object->getNetNeedsTree($TChildBom, 1);
145} else {
146 $object->getNetNeeds($TChildBom, 1);
147}
148
149
150// Part to show record
151if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
152 $head = bomPrepareHead($object);
153 print dol_get_fiche_head($head, 'net_needs', $langs->trans("BillOfMaterials"), -1, 'bom');
154
155 $formconfirm = '';
156
157 // Call Hook formConfirm
158 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
159 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
160 if (empty($reshook)) {
161 $formconfirm .= $hookmanager->resPrint;
162 } elseif ($reshook > 0) {
163 $formconfirm = $hookmanager->resPrint;
164 }
165
166 // Print form confirm
167 print $formconfirm;
168
169
170 // Object card
171 // ------------------------------------------------------------
172 $linkback = '<a href="'.DOL_URL_ROOT.'/bom/bom_list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
173
174 $morehtmlref = '<div class="refidno">';
175
176 $morehtmlref .= '</div>';
177
178
179 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
180
181
182 print '<div class="fichecenter">';
183 print '<div class="fichehalfleft">';
184 print '<div class="underbanner clearboth"></div>';
185 print '<table class="border centpercent tableforfield">'."\n";
186
187 // Common attributes
188 $keyforbreak = 'duration';
189 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
190
191 print '<tr><td>'.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).'</td><td><span class="amount">'.price($object->total_cost).'</span></td></tr>';
192 print '<tr><td>'.$langs->trans("UnitCost").'</td><td>'.price($object->unit_cost).'</td></tr>';
193
194 // Other attributes
195 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
196
197 print '</table>';
198 print '</div>';
199 print '</div>';
200
201 print '<div class="clearboth"></div>';
202
203 print dol_get_fiche_end();
204
205 $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' : '')));
206 $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' : '')));
207
208 print load_fiche_titre($langs->trans("BOMNetNeeds"), $viewlink, 'product');
209
210 /*
211 * Lines
212 */
213 $text_stock_options = $langs->trans("RealStockDesc").'<br>';
214 $text_stock_options .= $langs->trans("RealStockWillAutomaticallyWhen").'<br>';
215 $text_stock_options .= (getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT') || getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT_CLOSE') ? '- '.$langs->trans("DeStockOnShipment").'<br>' : '');
216 $text_stock_options .= (getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') ? '- '.$langs->trans("DeStockOnValidateOrder").'<br>' : '');
217 $text_stock_options .= (getDolGlobalString('STOCK_CALCULATE_ON_BILL') ? '- '.$langs->trans("DeStockOnBill").'<br>' : '');
218 $text_stock_options .= (getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') ? '- '.$langs->trans("ReStockOnBill").'<br>' : '');
219 $text_stock_options .= (getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER') ? '- '.$langs->trans("ReStockOnValidateOrder").'<br>' : '');
220 $text_stock_options .= (getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER') ? '- '.$langs->trans("ReStockOnDispatchOrder").'<br>' : '');
221 $text_stock_options .= (getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION') || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE') ? '- '.$langs->trans("StockOnReception").'<br>' : '');
222
223 print '<table id="tablelines" class="noborder noshadow" width="100%">';
224 print "<thead>\n";
225 print '<tr class="liste_titre nodrag nodrop">';
226 print '<td class="linecoldescription">'.$langs->trans('Product');
227 if (getDolGlobalString('BOM_SUB_BOM') && $action == 'treeview') {
228 print ' &nbsp; <a id="show_all" href="#">'.img_picto('', 'folder-open', 'class="paddingright"').$langs->trans("ExpandAll").'</a>&nbsp;&nbsp;';
229 print '<a id="hide_all" href="#">'.img_picto('', 'folder', 'class="paddingright"').$langs->trans("UndoExpandAll").'</a>&nbsp;';
230 }
231 print '</td>';
232 if ($action == 'treeview') {
233 print '<td class="left">'.$langs->trans('ProducedBy').'</td>';
234 }
235 print '<td class="linecolqty right">'.$langs->trans('Quantity').'</td>';
236 print '<td></td>'; // For unit
237 print '<td class="linecolstock right">'.$form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1).'</td>';
238 print '<td class="linecoltheoricalstock right">'.$form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc")).'</td>';
239 print '</tr>';
240
241 print '</thead>';
242 print '<tbody>';
243 if (count($TChildBom) > 0) {
244 if ($action == 'treeview') {
245 foreach ($TChildBom as $fk_bom => $TProduct) {
246 $repeatChar = '&emsp;';
247 if (!empty($TProduct['bom'])) {
248 $prod = new Product($db);
249 $prod->fetch($TProduct['bom']->fk_product);
250 if ($TProduct['parentid'] != $object->id) {
251 print '<tr class="sub_bom_lines oddeven" parentid="'.$TProduct['parentid'].'">';
252 } else {
253 print '<tr class="oddeven">';
254 }
255 if ($action == 'treeview') {
256 print '<td class="linecoldescription">'.str_repeat($repeatChar, $TProduct['level']).$prod->getNomUrl(1);
257 } else {
258 print '<td class="linecoldescription">'.str_repeat($repeatChar, $TProduct['level']).$TProduct['bom']->getNomUrl(1);
259 }
260 print ' <a class="collapse_bom" id="collapse-'.$fk_bom.'" href="#">';
261 print img_picto('', 'folder-open');
262 print '</a>';
263 print '</td>';
264 if ($action == 'treeview') {
265 print '<td class="left">'.$TProduct['bom']->getNomUrl(1).'</td>';
266 }
267 print '<td class="linecolqty right">'.$TProduct['qty'].'</td>';
268 print '<td>';
269 print '</td>';
270 print '<td class="linecolstock right"></td>';
271 print '<td class="linecoltheoricalstock right"></td>';
272 print '</tr>';
273 }
274 if (!empty($TProduct['product'])) {
275 foreach ($TProduct['product'] as $fk_product => $TInfos) {
276 $prod = new Product($db);
277 $prod->fetch($fk_product);
278 $prod->load_virtual_stock();
279 if (empty($prod->stock_reel)) {
280 $prod->stock_reel = 0;
281 }
282 if ($fk_bom != $object->id) {
283 print '<tr class="sub_bom_lines oddeven" parentid="'.$fk_bom.'">';
284 } else {
285 print '<tr class="oddeven">';
286 }
287 print '<td class="linecoldescription">'.str_repeat($repeatChar, $TInfos['level']).$prod->getNomUrl(1).'</td>';
288 if ($action == 'treeview') {
289 print '<td></td>';
290 }
291 print '<td class="linecolqty right">'.$TInfos['qty'].'</td>';
292 print '<td>';
293 print '</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 } else {
301 foreach ($TChildBom as $fk_product => $elem) {
302 $prod = new Product($db);
303 $prod->fetch($fk_product);
304 $prod->load_virtual_stock();
305 if (empty($prod->stock_reel)) {
306 $prod->stock_reel = 0;
307 }
308 print '<tr class="oddeven">';
309 print '<td class="linecoldescription">'.$prod->getNomUrl(1).'</td>';
310 print '<td class="linecolqty right">'.$elem['qty'].'</td>';
311 print '<td>';
312 $useunit = (($prod->type == Product::TYPE_PRODUCT && getDolGlobalInt('PRODUCT_USE_UNITS')) || (($prod->type == Product::TYPE_SERVICE) && ($elem['fk_unit'])));
313 if ($useunit) {
314 require_once DOL_DOCUMENT_ROOT.'/core/class/cunits.class.php';
315 $unit = new CUnits($db);
316 $unit->fetch($elem['fk_unit']);
317 print(isset($unit->label) ? "&nbsp;".$langs->trans(ucwords($unit->label))."&nbsp;" : '');
318 }
319 print '</td>';
320 print '<td class="linecolstock right">'.price2num($prod->stock_reel, 'MS').'</td>';
321 print '<td class="linecoltheoricalstock right">'.$prod->stock_theorique.'</td>';
322 print '</tr>';
323 }
324 }
325 }
326 print '</tbody>';
327 print '</table>';
328
329
330
331 /*
332 * ButAction
333 */
334 print '<div class="tabsAction">'."\n";
335 $parameters = array();
336 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
337 if ($reshook < 0) {
338 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
339 }
340 print '</div>'; ?>
341
342 <script type="text/javascript" language="javascript">
343 $(document).ready(function() {
344
345 function folderManage(element) {
346 var id_bom_line = element.attr('id').replace('collapse-', '');
347 let TSubLines = $('[parentid="'+ id_bom_line +'"]');
348
349 if(element.html().indexOf('folder-open') <= 0) {
350 $('[parentid="'+ id_bom_line +'"]').show();
351 element.html('<?php echo dol_escape_js(img_picto('', 'folder-open')); ?>');
352 }
353 else {
354 for (let i = 0; i < TSubLines.length; i++) {
355 let subBomFolder = $(TSubLines[i]).children('.linecoldescription').children('.collapse_bom');
356 if (subBomFolder.length > 0) {
357 folderManage(subBomFolder);
358 }
359 }
360 TSubLines.hide();
361 element.html('<?php echo dol_escape_js(img_picto('', 'folder')); ?>');
362 }
363 }
364
365 // When clicking on collapse
366 $(".collapse_bom").click(function() {
367 folderManage($(this));
368 return false;
369 });
370
371 // To Show all the sub bom lines
372 $("#show_all").click(function() {
373 console.log("We click on show all");
374 $("[class^=sub_bom_lines]").show();
375 $("[class^=collapse_bom]").html('<?php echo dol_escape_js(img_picto('', 'folder-open')); ?>');
376 return false;
377 });
378
379 // To Hide all the sub bom lines
380 $("#hide_all").click(function() {
381 console.log("We click on hide all");
382 $("[class^=sub_bom_lines]").hide();
383 $("[class^=collapse_bom]").html('<?php echo dol_escape_js(img_picto('', 'folder')); ?>');
384 return false;
385 });
386
387 });
388 </script>
389
390 <?php
391}
392
393// End of page
394llxFooter();
395$db->close();
$id
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:71
bomPrepareHead($object)
Prepare array of tabs for BillOfMaterials.
Definition bom.lib.php:79
Class for BOM.
Definition bom.class.php:42
Class of dictionary type of thirdparty (used by imports)
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.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
llxFooter()
Footer empty.
Definition document.php:107
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
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.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:149
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.