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