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