dolibarr 18.0.6
product.lib.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2006-2015 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
4 * Copyright (C) 2009-2010 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
6 * Copyright (C) 2015-2016 Marcos García <marcosgdf@gmail.com>
7 * Copyright (C) 2023 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 * or see https://www.gnu.org/
22 */
23
36function product_prepare_head($object)
37{
38 global $db, $langs, $conf, $user;
39 $langs->load("products");
40
41 $label = $langs->trans('Product');
42 $usercancreadprice = getDolGlobalString('MAIN_USE_ADVANCED_PERMS')?$user->hasRight('product', 'product_advance', 'read_prices'):$user->hasRight('product', 'read');
43
44 if ($object->isService()) {
45 $label = $langs->trans('Service');
46 $usercancreadprice = getDolGlobalString('MAIN_USE_ADVANCED_PERMS')?$user->hasRight('service', 'service_advance', 'read_prices'):$user->hasRight('service', 'read');
47 }
48
49 $h = 0;
50 $head = array();
51
52 $head[$h][0] = DOL_URL_ROOT."/product/card.php?id=".$object->id;
53 $head[$h][1] = $label;
54 $head[$h][2] = 'card';
55 $h++;
56
57 if (!empty($object->status)) {
58 if ($usercancreadprice) {
59 $head[$h][0] = DOL_URL_ROOT."/product/price.php?id=".$object->id;
60 $head[$h][1] = $langs->trans("SellingPrices");
61 $head[$h][2] = 'price';
62 $h++;
63 } else {
64 $head[$h][0] = '#';
65 $head[$h][1] = $langs->trans("SellingPrices");
66 $head[$h][2] = 'price';
67 $head[$h][5] = 'disabled';
68 $h++;
69 }
70 }
71
72 if (!empty($object->status_buy) || (isModEnabled('margin') && !empty($object->status))) { // If margin is on and product on sell, we may need the cost price even if product os not on purchase
73 if ((isModEnabled("supplier_proposal") || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && ($user->hasRight('fournisseur', 'lire') || $user->hasRight('supplier_order', 'read') || $user->hasRight('supplier_invoice', 'read'))
74 || (isModEnabled('margin') && $user->hasRight("margin", "liretous"))
75 ) {
76 if ($usercancreadprice) {
77 $head[$h][0] = DOL_URL_ROOT."/product/fournisseurs.php?id=".$object->id;
78 $head[$h][1] = $langs->trans("BuyingPrices");
79 $head[$h][2] = 'suppliers';
80 $h++;
81 } else {
82 $head[$h][0] = '#';
83 $head[$h][1] = $langs->trans("BuyingPrices");
84 $head[$h][2] = 'suppliers';
85 $head[$h][5] = 'disabled';
86 $h++;
87 }
88 }
89 }
90
91 // Multilangs
92 if (getDolGlobalInt('MAIN_MULTILANGS')) {
93 $head[$h][0] = DOL_URL_ROOT."/product/traduction.php?id=".$object->id;
94 $head[$h][1] = $langs->trans("Translations");
95 $head[$h][2] = 'translation';
96 $h++;
97 }
98
99 // Sub products
100 if (!empty($conf->global->PRODUIT_SOUSPRODUITS)) {
101 $head[$h][0] = DOL_URL_ROOT."/product/composition/card.php?id=".$object->id;
102 $head[$h][1] = $langs->trans('AssociatedProducts');
103
104 $nbFatherAndChild = $object->hasFatherOrChild();
105 if ($nbFatherAndChild > 0) {
106 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbFatherAndChild.'</span>';
107 }
108 $head[$h][2] = 'subproduct';
109 $h++;
110 }
111
112 if (isModEnabled('variants') && ($object->isProduct() || $object->isService())) {
113 global $db;
114
115 require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination.class.php';
116
117 $prodcomb = new ProductCombination($db);
118
119 if ($prodcomb->fetchByFkProductChild($object->id) <= 0) {
120 $head[$h][0] = DOL_URL_ROOT."/variants/combinations.php?id=".$object->id;
121 $head[$h][1] = $langs->trans('ProductCombinations');
122 $head[$h][2] = 'combinations';
123 $nbVariant = $prodcomb->countNbOfCombinationForFkProductParent($object->id);
124 if ($nbVariant > 0) {
125 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbVariant.'</span>';
126 }
127 }
128
129 $h++;
130 }
131
132 if ($object->isProduct() || ($object->isService() && !empty($conf->global->STOCK_SUPPORTS_SERVICES))) { // If physical product we can stock (or service with option)
133 if (isModEnabled('stock') && $user->hasRight('stock', 'lire')) {
134 $head[$h][0] = DOL_URL_ROOT."/product/stock/product.php?id=".$object->id;
135 $head[$h][1] = $langs->trans("Stock");
136 $head[$h][2] = 'stock';
137 $h++;
138 }
139 }
140
141 // Tab to link resources
142 if (isModEnabled('resource')) {
143 if ($object->isProduct() && !empty($conf->global->RESOURCE_ON_PRODUCTS)) {
144 $head[$h][0] = DOL_URL_ROOT.'/resource/element_resource.php?element=product&ref='.$object->ref;
145 $head[$h][1] = $langs->trans("Resources");
146 $head[$h][2] = 'resources';
147 $h++;
148 }
149 if ($object->isService() && !empty($conf->global->RESOURCE_ON_SERVICES)) {
150 $head[$h][0] = DOL_URL_ROOT.'/resource/element_resource.php?element=service&ref='.$object->ref;
151 $head[$h][1] = $langs->trans("Resources");
152 $head[$h][2] = 'resources';
153 $h++;
154 }
155 }
156
157 $head[$h][0] = DOL_URL_ROOT."/product/stats/facture.php?showmessage=1&id=".$object->id;
158 $head[$h][1] = $langs->trans('Referers');
159 $head[$h][2] = 'referers';
160 $h++;
161
162 $head[$h][0] = DOL_URL_ROOT."/product/stats/card.php?id=".$object->id;
163 $head[$h][1] = $langs->trans('Statistics');
164 $head[$h][2] = 'stats';
165 $h++;
166
167 // Show more tabs from modules
168 // Entries must be declared in modules descriptor with line
169 // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
170 // $this->tabs = array('entity:-tabname); to remove a tab
171 complete_head_from_modules($conf, $langs, $object, $head, $h, 'product', 'add', 'core');
172
173 // Notes
174 if (empty($conf->global->MAIN_DISABLE_NOTES_TAB)) {
175 $nbNote = 0;
176 if (!empty($object->note_private)) {
177 $nbNote++;
178 }
179 if (!empty($object->note_public)) {
180 $nbNote++;
181 }
182 $head[$h][0] = DOL_URL_ROOT.'/product/note.php?id='.$object->id;
183 $head[$h][1] = $langs->trans('Notes');
184 if ($nbNote > 0) {
185 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbNote.'</span>';
186 }
187 $head[$h][2] = 'note';
188 $h++;
189 }
190
191 // Attachments
192 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
193 require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
194 if (isModEnabled("product") && ($object->type == Product::TYPE_PRODUCT)) {
195 $upload_dir = $conf->product->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref);
196 }
197 if (isModEnabled("service") && ($object->type == Product::TYPE_SERVICE)) {
198 $upload_dir = $conf->service->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref);
199 }
200 $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
201 if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) {
202 if (isModEnabled("product") && ($object->type == Product::TYPE_PRODUCT)) {
203 $upload_dir = $conf->product->multidir_output[$object->entity].'/'.get_exdir($object->id, 2, 0, 0, $object, 'product').$object->id.'/photos';
204 }
205 if (isModEnabled("service") && ($object->type == Product::TYPE_SERVICE)) {
206 $upload_dir = $conf->service->multidir_output[$object->entity].'/'.get_exdir($object->id, 2, 0, 0, $object, 'product').$object->id.'/photos';
207 }
208 $nbFiles += count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
209 }
210 $nbLinks = Link::count($db, $object->element, $object->id);
211 $head[$h][0] = DOL_URL_ROOT.'/product/document.php?id='.$object->id;
212 $head[$h][1] = $langs->trans('Documents');
213 if (($nbFiles + $nbLinks) > 0) {
214 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.($nbFiles + $nbLinks).'</span>';
215 }
216 $head[$h][2] = 'documents';
217 $h++;
218
219 // Log
220 $head[$h][0] = DOL_URL_ROOT.'/product/agenda.php?id='.$object->id;
221 $head[$h][1] = $langs->trans("Events");
222 if (isModEnabled('agenda') && ($user->hasRight('agenda', 'myactions', 'read') || $user->hasRight('agenda', 'allactions', 'read'))) {
223 $head[$h][1] .= '/';
224 $head[$h][1] .= $langs->trans("Agenda");
225 }
226 $head[$h][2] = 'agenda';
227 $h++;
228
229 complete_head_from_modules($conf, $langs, $object, $head, $h, 'product', 'add', 'external');
230
231 complete_head_from_modules($conf, $langs, $object, $head, $h, 'product', 'remove');
232
233 return $head;
234}
235
242function productlot_prepare_head($object)
243{
244 global $db, $langs, $conf, $user;
245
246 // Load translation files required by the page
247 $langs->loadLangs(array("products", "productbatch"));
248
249 $h = 0;
250 $head = array();
251
252 $head[$h][0] = DOL_URL_ROOT."/product/stock/productlot_card.php?id=".$object->id;
253 $head[$h][1] = $langs->trans("Lot");
254 $head[$h][2] = 'card';
255 $h++;
256
257 $head[$h][0] = DOL_URL_ROOT."/product/stock/stats/expedition.php?showmessage=1&id=".$object->id;
258 $head[$h][1] = $langs->trans('Referers');
259 $head[$h][2] = 'referers';
260 $h++;
261
262 // Attachments
263 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
264 require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
265 $upload_dir = $conf->productbatch->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref);
266 $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
267 $nbLinks = Link::count($db, $object->element, $object->id);
268 $head[$h][0] = DOL_URL_ROOT."/product/stock/productlot_document.php?id=".$object->id;
269 $head[$h][1] = $langs->trans("Documents");
270 if (($nbFiles + $nbLinks) > 0) {
271 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.($nbFiles + $nbLinks).'</span>';
272 }
273 $head[$h][2] = 'documents';
274 $h++;
275
276 // Notes
277 if (empty($conf->global->MAIN_DISABLE_NOTES_TAB)) {
278 $nbNote = 0;
279 if (!empty($object->note_private)) {
280 $nbNote++;
281 }
282 if (!empty($object->note_public)) {
283 $nbNote++;
284 }
285 $head[$h][0] = DOL_URL_ROOT .'/product/stock/productlot_note.php?id=' . $object->id;
286 $head[$h][1] = $langs->trans('Notes');
287 if ($nbNote > 0) {
288 $head[$h][1] .= '<span class="badge marginleftonlyshort">' . $nbNote . '</span>';
289 }
290 $head[$h][2] = 'note';
291 $h++;
292 }
293
294 // Show more tabs from modules
295 // Entries must be declared in modules descriptor with line
296 // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
297 // $this->tabs = array('entity:-tabname); to remove a tab
298 complete_head_from_modules($conf, $langs, $object, $head, $h, 'productlot');
299
300 complete_head_from_modules($conf, $langs, $object, $head, $h, 'productlot', 'remove');
301
302 // Log
303 /*
304 $head[$h][0] = DOL_URL_ROOT.'/product/info.php?id='.$object->id;
305 $head[$h][1] = $langs->trans("Info");
306 $head[$h][2] = 'info';
307 $h++;
308 */
309
310 return $head;
311}
312
313
314
321{
322 global $langs, $conf, $user, $db;
323
324 $extrafields = new ExtraFields($db);
325 $extrafields->fetch_name_optionals_label('product');
326 $extrafields->fetch_name_optionals_label('product_fournisseur_price');
327
328 $h = 0;
329 $head = array();
330
331 $head[$h][0] = DOL_URL_ROOT."/product/admin/product.php";
332 $head[$h][1] = $langs->trans('Parameters');
333 $head[$h][2] = 'general';
334 $h++;
335
336 if (!empty($conf->global->PRODUIT_MULTIPRICES) && !empty($conf->global->PRODUIT_MULTIPRICES_ALLOW_AUTOCALC_PRICELEVEL)) {
337 $head[$h] = array(
338 0 => DOL_URL_ROOT."/product/admin/price_rules.php",
339 1 => $langs->trans('MultipriceRules'),
340 2 => 'generator'
341 );
342 $h++;
343 }
344
345 // Show more tabs from modules
346 // Entries must be declared in modules descriptor with line
347 // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
348 // $this->tabs = array('entity:-tabname); to remove a tab
349 complete_head_from_modules($conf, $langs, null, $head, $h, 'product_admin');
350
351 $head[$h][0] = DOL_URL_ROOT.'/product/admin/product_extrafields.php';
352 $head[$h][1] = $langs->trans("ExtraFields");
353 $nbExtrafields = $extrafields->attributes['product']['count'];
354 if ($nbExtrafields > 0) {
355 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbExtrafields.'</span>';
356 }
357 $head[$h][2] = 'attributes';
358 $h++;
359
360 $head[$h][0] = DOL_URL_ROOT.'/product/admin/product_supplier_extrafields.php';
361 $head[$h][1] = $langs->trans("ProductSupplierExtraFields");
362 $nbExtrafields = $extrafields->attributes['product_fournisseur_price']['count'];
363 if ($nbExtrafields > 0) {
364 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbExtrafields.'</span>';
365 }
366 $head[$h][2] = 'supplierAttributes';
367 $h++;
368
369 complete_head_from_modules($conf, $langs, null, $head, $h, 'product_admin', 'remove');
370
371 return $head;
372}
373
374
375
382{
383 global $langs, $conf, $user, $db;
384
385 $extrafields = new ExtraFields($db);
386 $extrafields->fetch_name_optionals_label('product_lot');
387
388 $h = 0;
389 $head = array();
390
391 $head[$h][0] = DOL_URL_ROOT."/product/admin/product_lot.php";
392 $head[$h][1] = $langs->trans('Parameters');
393 $head[$h][2] = 'settings';
394 $h++;
395
396 // Show more tabs from modules
397 // Entries must be declared in modules descriptor with line
398 // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
399 // $this->tabs = array('entity:-tabname); to remove a tab
400 complete_head_from_modules($conf, $langs, null, $head, $h, 'product_lot_admin');
401
402 $head[$h][0] = DOL_URL_ROOT.'/product/admin/product_lot_extrafields.php';
403 $head[$h][1] = $langs->trans("ExtraFields");
404 $nbExtrafields = $extrafields->attributes['product_lot']['count'];
405 if ($nbExtrafields > 0) {
406 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbExtrafields.'</span>';
407 }
408 $head[$h][2] = 'attributes';
409 $h++;
410
411 complete_head_from_modules($conf, $langs, null, $head, $h, 'product_lot_admin', 'remove');
412
413 return $head;
414}
415
416
417
425function show_stats_for_company($product, $socid)
426{
427 global $conf, $langs, $user, $db, $hookmanager;
428
429 $form = new Form($db);
430
431 $nblines = 0;
432
433 print '<tr class="liste_titre">';
434 print '<td class="left" width="25%">'.$langs->trans("Referers").'</td>';
435 print '<td class="right" width="25%">'.$langs->trans("NbOfThirdParties").'</td>';
436 print '<td class="right" width="25%">'.$langs->trans("NbOfObjectReferers").'</td>';
437 print '<td class="right" width="25%">'.$langs->trans("TotalQuantity").'</td>';
438 print '</tr>';
439
440 // Customer proposals
441 if (isModEnabled("propal") && $user->hasRight('propal', 'lire')) {
442 $nblines++;
443 $ret = $product->load_stats_propale($socid);
444 if ($ret < 0) {
445 dol_print_error($db);
446 }
447 $langs->load("propal");
448 print '<tr><td>';
449 print '<a href="propal.php?id='.$product->id.'">'.img_object('', 'propal', 'class="pictofixedwidth"').$langs->trans("Proposals").'</a>';
450 print '</td><td class="right">';
451 print $product->stats_propale['customers'];
452 print '</td><td class="right">';
453 print $product->stats_propale['nb'];
454 print '</td><td class="right">';
455 print price($product->stats_propale['qty'], 1, $langs, 0, 0);
456 print '</td>';
457 print '</tr>';
458 }
459 // Supplier proposals
460 if (isModEnabled('supplier_proposal') && $user->hasRight('supplier_proposal', 'lire')) {
461 $nblines++;
462 $ret = $product->load_stats_proposal_supplier($socid);
463 if ($ret < 0) {
464 dol_print_error($db);
465 }
466 $langs->load("supplier_proposal");
467 print '<tr><td>';
468 print '<a href="supplier_proposal.php?id='.$product->id.'">'.img_object('', 'supplier_proposal', 'class="pictofixedwidth"').$langs->trans("SupplierProposals").'</a>';
469 print '</td><td class="right">';
470 print $product->stats_proposal_supplier['suppliers'];
471 print '</td><td class="right">';
472 print $product->stats_proposal_supplier['nb'];
473 print '</td><td class="right">';
474 print price($product->stats_proposal_supplier['qty'], 1, $langs, 0, 0);
475 print '</td>';
476 print '</tr>';
477 }
478 // Sales orders
479 if (isModEnabled('commande') && $user->hasRight('commande', 'lire')) {
480 $nblines++;
481 $ret = $product->load_stats_commande($socid);
482 if ($ret < 0) {
483 dol_print_error($db);
484 }
485 $langs->load("orders");
486 print '<tr><td>';
487 print '<a href="commande.php?id='.$product->id.'">'.img_object('', 'order', 'class="pictofixedwidth"').$langs->trans("CustomersOrders").'</a>';
488 print '</td><td class="right">';
489 print $product->stats_commande['customers'];
490 print '</td><td class="right">';
491 print $product->stats_commande['nb'];
492 print '</td><td class="right">';
493 print price($product->stats_commande['qty'], 1, $langs, 0, 0);
494 print '</td>';
495 print '</tr>';
496 }
497 // Supplier orders
498 if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight('fournisseur', 'commande', 'lire')) || (isModEnabled("supplier_order") && $user->hasRight('supplier_order', 'lire'))) {
499 $nblines++;
500 $ret = $product->load_stats_commande_fournisseur($socid);
501 if ($ret < 0) {
502 dol_print_error($db);
503 }
504 $langs->load("orders");
505 print '<tr><td>';
506 print '<a href="commande_fournisseur.php?id='.$product->id.'">'.img_object('', 'supplier_order', 'class="pictofixedwidth"').$langs->trans("SuppliersOrders").'</a>';
507 print '</td><td class="right">';
508 print $product->stats_commande_fournisseur['suppliers'];
509 print '</td><td class="right">';
510 print $product->stats_commande_fournisseur['nb'];
511 print '</td><td class="right">';
512 print price($product->stats_commande_fournisseur['qty'], 1, $langs, 0, 0);
513 print '</td>';
514 print '</tr>';
515 }
516 // Customer invoices
517 if (isModEnabled('facture') && $user->hasRight('facture', 'lire')) {
518 $nblines++;
519 $ret = $product->load_stats_facture($socid);
520 if ($ret < 0) {
521 dol_print_error($db);
522 }
523 $langs->load("bills");
524 print '<tr><td>';
525 print '<a href="facture.php?id='.$product->id.'">'.img_object('', 'bill', 'class="pictofixedwidth"').$langs->trans("CustomersInvoices").'</a>';
526 print '</td><td class="right">';
527 print $product->stats_facture['customers'];
528 print '</td><td class="right">';
529 print $product->stats_facture['nb'];
530 print '</td><td class="right">';
531 print price($product->stats_facture['qty'], 1, $langs, 0, 0);
532 print '</td>';
533 print '</tr>';
534 }
535 // Customer template invoices
536 if (isModEnabled("facture") && $user->hasRight('facture', 'lire')) {
537 $nblines++;
538 $ret = $product->load_stats_facturerec($socid);
539 if ($ret < 0) {
540 dol_print_error($db);
541 }
542 $langs->load("bills");
543 print '<tr><td>';
544 print '<a href="facturerec.php?id='.$product->id.'">'.img_object('', 'bill', 'class="pictofixedwidth"').$langs->trans("RecurringInvoiceTemplate").'</a>';
545 print '</td><td class="right">';
546 print $product->stats_facture['customers'];
547 print '</td><td class="right">';
548 print $product->stats_facturerec['nb'];
549 print '</td><td class="right">';
550 print $product->stats_facturerec['qty'];
551 print '</td>';
552 print '</tr>';
553 }
554 // Supplier invoices
555 if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight('fournisseur', 'facture', 'lire')) || (isModEnabled("supplier_invoice") && $user->hasRight('supplier_invoice', 'lire'))) {
556 $nblines++;
557 $ret = $product->load_stats_facture_fournisseur($socid);
558 if ($ret < 0) {
559 dol_print_error($db);
560 }
561 $langs->load("bills");
562 print '<tr><td>';
563 print '<a href="facture_fournisseur.php?id='.$product->id.'">'.img_object('', 'supplier_invoice', 'class="pictofixedwidth"').$langs->trans("SuppliersInvoices").'</a>';
564 print '</td><td class="right">';
565 print $product->stats_facture_fournisseur['suppliers'];
566 print '</td><td class="right">';
567 print $product->stats_facture_fournisseur['nb'];
568 print '</td><td class="right">';
569 print price($product->stats_facture_fournisseur['qty'], 1, $langs, 0, 0);
570 print '</td>';
571 print '</tr>';
572 }
573
574 // Contracts
575 if (isModEnabled('contrat') && $user->hasRight('contrat', 'lire')) {
576 $nblines++;
577 $ret = $product->load_stats_contrat($socid);
578 if ($ret < 0) {
579 dol_print_error($db);
580 }
581 $langs->load("contracts");
582 print '<tr><td>';
583 print '<a href="contrat.php?id='.$product->id.'">'.img_object('', 'contract', 'class="pictofixedwidth"').$langs->trans("Contracts").'</a>';
584 print '</td><td class="right">';
585 print $product->stats_contrat['customers'];
586 print '</td><td class="right">';
587 print $product->stats_contrat['nb'];
588 print '</td><td class="right">';
589 print price($product->stats_contrat['qty'], 1, $langs, 0, 0);
590 print '</td>';
591 print '</tr>';
592 }
593
594 // BOM
595 if (isModEnabled('bom') && $user->hasRight('bom', 'read')) {
596 $nblines++;
597 $ret = $product->load_stats_bom($socid);
598 if ($ret < 0) {
599 setEventMessage($product->error, 'errors');
600 }
601 $langs->load("mrp");
602
603 print '<tr><td>';
604 print '<a href="bom.php?id='.$product->id.'">'.img_object('', 'bom', 'class="pictofixedwidth"').$langs->trans("BOM").'</a>';
605 print '</td><td class="right">';
606
607 print '</td><td class="right">';
608 print $form->textwithpicto($product->stats_bom['nb_toconsume'], $langs->trans("RowMaterial"));
609 print $form->textwithpicto($product->stats_bom['nb_toproduce'], $langs->trans("Finished"));
610 print '</td><td class="right">';
611 print $form->textwithpicto($product->stats_bom['qty_toconsume'], $langs->trans("RowMaterial"));
612 print $form->textwithpicto($product->stats_bom['qty_toproduce'], $langs->trans("Finished"));
613 print '</td>';
614 print '</tr>';
615 }
616
617 // MO
618 if (isModEnabled('mrp') && !empty($user->rights->mrp->read)) {
619 $nblines++;
620 $ret = $product->load_stats_mo($socid);
621 if ($ret < 0) {
622 setEventMessages($product->error, $product->errors, 'errors');
623 }
624 $langs->load("mrp");
625 print '<tr><td>';
626 print '<a href="mo.php?id='.$product->id.'">'.img_object('', 'mrp', 'class="pictofixedwidth"').$langs->trans("MO").'</a>';
627 print '</td><td class="right">';
628 print $form->textwithpicto($product->stats_mo['customers_toconsume'], $langs->trans("ToConsume"));
629 print $form->textwithpicto($product->stats_mo['customers_consumed'], $langs->trans("QtyAlreadyConsumed"));
630 print $form->textwithpicto($product->stats_mo['customers_toproduce'], $langs->trans("QtyToProduce"));
631 print $form->textwithpicto($product->stats_mo['customers_produced'], $langs->trans("QtyAlreadyProduced"));
632 print '</td><td class="right">';
633 print $form->textwithpicto($product->stats_mo['nb_toconsume'], $langs->trans("ToConsume"));
634 print $form->textwithpicto($product->stats_mo['nb_consumed'], $langs->trans("QtyAlreadyConsumed"));
635 print $form->textwithpicto($product->stats_mo['nb_toproduce'], $langs->trans("QtyToProduce"));
636 print $form->textwithpicto($product->stats_mo['nb_produced'], $langs->trans("QtyAlreadyProduced"));
637 print '</td><td class="right">';
638 print $form->textwithpicto($product->stats_mo['qty_toconsume'], $langs->trans("ToConsume"));
639 print $form->textwithpicto($product->stats_mo['qty_consumed'], $langs->trans("QtyAlreadyConsumed"));
640 print $form->textwithpicto($product->stats_mo['qty_toproduce'], $langs->trans("QtyToProduce"));
641 print $form->textwithpicto($product->stats_mo['qty_produced'], $langs->trans("QtyAlreadyProduced"));
642 print '</td>';
643 print '</tr>';
644 }
645 $parameters = array('socid'=>$socid);
646 $reshook = $hookmanager->executeHooks('addMoreProductStat', $parameters, $product, $nblines); // Note that $action and $object may have been modified by some hooks
647 if ($reshook < 0) {
648 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
649 }
650
651 print $hookmanager->resPrint;
652
653
654 return $nblines++;
655}
656
664function show_stats_for_batch($batch, $socid)
665{
666 global $conf, $langs, $user, $db, $hookmanager;
667
668 $langs->LoadLangs(array('sendings', 'orders', 'receptions'));
669
670 $form = new Form($db);
671
672 $nblines = 0;
673
674 print '<tr class="liste_titre">';
675 print '<td class="left" width="25%">'.$langs->trans("Referers").'</td>';
676 print '<td class="right" width="25%">'.$langs->trans("NbOfThirdParties").'</td>';
677 print '<td class="right" width="25%">'.$langs->trans("NbOfObjectReferers").'</td>';
678 print '<td class="right" width="25%">'.$langs->trans("TotalQuantity").'</td>';
679 print '</tr>';
680
681 // Expeditions
682 if (isModEnabled('expedition') && !empty($user->rights->expedition->lire)) {
683 $nblines++;
684 $ret = $batch->loadStatsExpedition($socid);
685 if ($ret < 0) {
686 dol_print_error($db);
687 }
688 $langs->load("bills");
689 print '<tr><td>';
690 print '<a href="'.dol_buildpath('/product/stock/stats/expedition.php', 1).'?id='.$batch->id.'">'.img_object('', 'bill', 'class="pictofixedwidth"').$langs->trans("Shipments").'</a>';
691 print '</td><td class="right">';
692 print $batch->stats_expedition['customers'];
693 print '</td><td class="right">';
694 print $batch->stats_expedition['nb'];
695 print '</td><td class="right">';
696 print $batch->stats_expedition['qty'];
697 print '</td>';
698 print '</tr>';
699 }
700
701 if (isModEnabled("reception") && !empty($user->rights->reception->lire)) {
702 $nblines++;
703 $ret = $batch->loadStatsReception($socid);
704 if ($ret < 0) {
705 dol_print_error($db);
706 }
707 $langs->load("bills");
708 print '<tr><td>';
709 print '<a href="'.dol_buildpath('/product/stock/stats/reception.php', 1).'?id='.$batch->id.'">'.img_object('', 'bill', 'class="pictofixedwidth"').$langs->trans("Receptions").'</a>';
710 print '</td><td class="right">';
711 print $batch->stats_reception['customers'];
712 print '</td><td class="right">';
713 print $batch->stats_reception['nb'];
714 print '</td><td class="right">';
715 print $batch->stats_reception['qty'];
716 print '</td>';
717 print '</tr>';
718 } elseif (isModEnabled('supplier_order') && !empty($user->rights->fournisseur->commande->lire)) {
719 $nblines++;
720 $ret = $batch->loadStatsSupplierOrder($socid);
721 if ($ret < 0) {
722 dol_print_error($db);
723 }
724 $langs->load("bills");
725 print '<tr><td>';
726 print '<a href="'.dol_buildpath('/product/stock/stats/commande_fournisseur.php', 1).'?id='.$batch->id.'">'.img_object('', 'bill', 'class="pictofixedwidth"').$langs->trans("SuppliersOrders").'</a>';
727 print '</td><td class="right">';
728 print $batch->stats_supplier_order['customers'];
729 print '</td><td class="right">';
730 print $batch->stats_supplier_order['nb'];
731 print '</td><td class="right">';
732 print $batch->stats_supplier_order['qty'];
733 print '</td>';
734 print '</tr>';
735 }
736
737 if (isModEnabled('mrp') && !empty($user->rights->mrp->read)) {
738 $nblines++;
739 $ret = $batch->loadStatsMo($socid);
740 if ($ret < 0) {
741 dol_print_error($db);
742 }
743 $langs->load("mrp");
744 print '<tr><td>';
745 print '<a href="'.dol_buildpath('/product/stock/stats/mo.php', 1).'?id='.$batch->id.'">'.img_object('', 'mrp', 'class="pictofixedwidth"').$langs->trans("MO").'</a>';
746 print '</td><td class="right">';
747 // print $form->textwithpicto($batch->stats_mo['customers_toconsume'], $langs->trans("ToConsume")); Makes no sense with batch, at this moment we don't know batch number
748 print $form->textwithpicto($batch->stats_mo['customers_consumed'], $langs->trans("QtyAlreadyConsumed"));
749 // print $form->textwithpicto($batch->stats_mo['customers_toproduce'], $langs->trans("QtyToProduce")); Makes no sense with batch, at this moment we don't know batch number
750 print $form->textwithpicto($batch->stats_mo['customers_produced'], $langs->trans("QtyAlreadyProduced"));
751 print '</td><td class="right">';
752 // print $form->textwithpicto($batch->stats_mo['nb_toconsume'], $langs->trans("ToConsume")); Makes no sense with batch, at this moment we don't know batch number
753 print $form->textwithpicto($batch->stats_mo['nb_consumed'], $langs->trans("QtyAlreadyConsumed"));
754 // print $form->textwithpicto($batch->stats_mo['nb_toproduce'], $langs->trans("QtyToProduce")); Makes no sense with batch, at this moment we don't know batch number
755 print $form->textwithpicto($batch->stats_mo['nb_produced'], $langs->trans("QtyAlreadyProduced"));
756 print '</td><td class="right">';
757 // print $form->textwithpicto($batch->stats_mo['qty_toconsume'], $langs->trans("ToConsume")); Makes no sense with batch, at this moment we don't know batch number
758 print $form->textwithpicto($batch->stats_mo['qty_consumed'], $langs->trans("QtyAlreadyConsumed"));
759 // print $form->textwithpicto($batch->stats_mo['qty_toproduce'], $langs->trans("QtyToProduce")); Makes no sense with batch, at this moment we don't know batch number
760 print $form->textwithpicto($batch->stats_mo['qty_produced'], $langs->trans("QtyAlreadyProduced"));
761 print '</td>';
762 print '</tr>';
763 }
764
765 $parameters = array('socid'=>$socid);
766 $reshook = $hookmanager->executeHooks('addMoreBatchProductStat', $parameters, $batch, $nblines); // Note that $action and $object may have been modified by some hooks
767 if ($reshook < 0) {
768 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
769 }
770
771 print $hookmanager->resPrint;
772
773
774 return $nblines++;
775}
776
789function measuring_units_string($scale = '', $measuring_style = '', $unit = 0, $use_short_label = 0, $outputlangs = null)
790{
791 return measuringUnitString($unit, $measuring_style, $scale, $use_short_label, $outputlangs);
792}
793
805function measuringUnitString($unit, $measuring_style = '', $scale = '', $use_short_label = 0, $outputlangs = null)
806{
807 global $langs, $db;
808 global $measuring_unit_cache;
809
810 if (empty($outputlangs)) {
811 $outputlangs = $langs;
812 }
813
814 if (empty($measuring_unit_cache[$unit.'_'.$measuring_style.'_'.$scale.'_'.$use_short_label])) {
815 require_once DOL_DOCUMENT_ROOT.'/core/class/cunits.class.php';
816 $measuringUnits = new CUnits($db);
817
818 if ($measuring_style == '' && $scale == '') {
819 $arrayforfilter = array(
820 't.rowid' => $unit,
821 't.active' => 1
822 );
823 } elseif ($scale !== '') {
824 $arrayforfilter = array(
825 't.scale' => $scale,
826 't.unit_type' => $measuring_style,
827 't.active' => 1
828 );
829 } else {
830 $arrayforfilter = array(
831 't.rowid' => $unit,
832 't.unit_type' => $measuring_style,
833 't.active' => 1
834 );
835 }
836 $result = $measuringUnits->fetchAll('', '', 0, 0, $arrayforfilter);
837
838 if ($result < 0) {
839 return -1;
840 } else {
841 if (is_array($measuringUnits->records) && count($measuringUnits->records) > 0) {
842 if ($use_short_label) {
843 $labeltoreturn = $measuringUnits->records[key($measuringUnits->records)]->short_label;
844 } else {
845 $labeltoreturn = $outputlangs->transnoentitiesnoconv($measuringUnits->records[key($measuringUnits->records)]->label);
846 }
847 } else {
848 $labeltoreturn = '';
849 }
850 $measuring_unit_cache[$unit.'_'.$measuring_style.'_'.$scale.'_'.$use_short_label] = $labeltoreturn;
851 return $labeltoreturn;
852 }
853 } else {
854 return $measuring_unit_cache[$unit.'_'.$measuring_style.'_'.$scale.'_'.$use_short_label];
855 }
856}
857
866{
867 $measuring_units = array();
868 $measuring_units[0] = 0; // m -> m3
869 $measuring_units[-1] = -2; // dm-> dm2
870 $measuring_units[-2] = -4; // cm -> cm2
871 $measuring_units[-3] = -6; // mm -> mm2
872 $measuring_units[98] = 98; // foot -> foot2
873 $measuring_units[99] = 99; // inch -> inch2
874 return $measuring_units[$unit];
875}
876
877
886{
887 $measuring_units = array();
888 $measuring_units[0] = 0; // m -> m2
889 $measuring_units[-1] = -3; // dm-> dm3
890 $measuring_units[-2] = -6; // cm -> cm3
891 $measuring_units[-3] = -9; // mm -> mm3
892 $measuring_units[98] = 88; // foot -> foot3
893 $measuring_units[99] = 89; // inch -> inch3
894 return $measuring_units[$unit];
895}
Class of dictionary type of thirdparty (used by imports)
Class to manage standard extra fields.
Class to manage generation of HTML components Only common components must be here.
Class ProductCombination Used to represent a product combination.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:62
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
setEventMessage($mesgs, $style='mesgs', $noduplicate=0)
Set event message in dol_events session object.
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 dolibarr global constant int value.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, $mode='add', $filterorigmodule='')
Complete or removed entries into a head array (used to build tabs).
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
show_stats_for_batch($batch, $socid)
Show stats for product batch.
product_prepare_head($object)
Prepare array with list of tabs.
product_admin_prepare_head()
Return array head with list of tabs to view object informations.
measuringUnitString($unit, $measuring_style='', $scale='', $use_short_label=0, $outputlangs=null)
Return translation label of a unit key.
measuring_units_string($scale='', $measuring_style='', $unit=0, $use_short_label=0, $outputlangs=null)
Return translation label of a unit key.
show_stats_for_company($product, $socid)
Show stats for company.
productlot_prepare_head($object)
Prepare array with list of tabs.
product_lot_admin_prepare_head()
Return array head with list of tabs to view object informations.
measuring_units_squared($unit)
Transform a given unit scale into the square of that unit, if known.
measuring_units_cubed($unit)
Transform a given unit scale into the cube of that unit, if known.