dolibarr 18.0.6
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') $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';
132llxHeader('', $title, $help_url);
133
134
135// Part to show record
136if ($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
349llxFooter();
350$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:56
llxFooter()
Empty footer.
Definition wrapper.php:70
bomPrepareHead($object)
Prepare array of tabs for BillOfMaterials.
Definition bom.lib.php:78
Class for BOM.
Definition bom.class.php:39
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.
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:120
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.