dolibarr 24.0.0-beta
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-2025 MDW <mdeweerd@users.noreply.github.com>
10 * Copyright (C) 2024 Mélina Joum <melina.joum@altairis.fr>
11 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 * or see https://www.gnu.org/
26 */
27
41{
42 global $db, $langs, $conf, $user;
43 $langs->load("products");
44
45 $label = $langs->trans('Product');
46 $usercancreadprice = getDolGlobalString('MAIN_USE_ADVANCED_PERMS') ? $user->hasRight('product', 'product_advance', 'read_prices') : $user->hasRight('product', 'read');
47 $usercancreadsupplierprice = getDolGlobalString('MAIN_USE_ADVANCED_PERMS') ? $user->hasRight('product', 'product_advance', 'read_supplier_prices') : $user->hasRight('product', 'read');
48
49 if ($object->isService()) {
50 $label = $langs->trans('Service');
51 $usercancreadprice = getDolGlobalString('MAIN_USE_ADVANCED_PERMS') ? $user->hasRight('service', 'service_advance', 'read_prices') : $user->hasRight('service', 'read');
52 $usercancreadsupplierprice = getDolGlobalString('MAIN_USE_ADVANCED_PERMS') ? $user->hasRight('service', 'service_advance', 'read_supplier_prices') : $user->hasRight('service', 'read');
53 }
54
55 $h = 0;
56 $head = array();
57
58 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/card.php', ['id' => $object->id]);
59 $head[$h][1] = $label;
60 $head[$h][2] = 'card';
61 $h++;
62
63 // if (!empty($object->status)) {
64 if ($usercancreadprice) {
65 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/price.php', ['id' => $object->id]);
66 $head[$h][1] = $langs->trans("SellingPrices");
67 $head[$h][2] = 'price';
68 $h++;
69 } else {
70 $head[$h][0] = '#';
71 $head[$h][1] = $langs->trans("SellingPrices");
72 $head[$h][2] = 'price';
73 $head[$h][5] = 'disabled';
74 $h++;
75 }
76 // }
77
78 // 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
79 if ((isModEnabled("supplier_proposal") || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && ($user->hasRight('fournisseur', 'lire') || $user->hasRight('supplier_order', 'read') || $user->hasRight('supplier_invoice', 'read'))
80 || (isModEnabled('margin') && $user->hasRight("margin", "liretous"))
81 ) {
82 if ($usercancreadsupplierprice) {
83 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/price_suppliers.php', ['id' => $object->id]);
84 $head[$h][1] = $langs->trans("BuyingPrices");
85 $head[$h][2] = 'suppliers';
86 $h++;
87 } else {
88 $head[$h][0] = '#';
89 $head[$h][1] = $langs->trans("BuyingPrices");
90 $head[$h][2] = 'suppliers';
91 $head[$h][5] = 'disabled';
92 $h++;
93 }
94 }
95 // }
96
97 // Multilangs
98 if (getDolGlobalInt('MAIN_MULTILANGS')) {
99 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/traduction.php', ['id' => $object->id]);
100 $head[$h][1] = $langs->trans("Translations");
101 $nbTranslations = !empty($object->multilangs) ? count($object->multilangs) : 0;
102 if ($nbTranslations > 0) {
103 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbTranslations.'</span>';
104 }
105 $head[$h][2] = 'translation';
106 $h++;
107 }
108
109 // Sub products
110 if (getDolGlobalString('PRODUIT_SOUSPRODUITS')) {
111 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/composition/card.php', ['id' => $object->id]);
112 $head[$h][1] = $langs->trans('AssociatedProducts');
113
114 $nbFather = $object->hasFatherOrChild(-1);
115 $nbChild = $object->hasFatherOrChild(1);
116 if ($nbFather > 0 || $nbChild > 0) {
117 $head[$h][1] .= '<span class="badge marginleftonlyshort">';
118 if ($nbFather) {
119 $head[$h][1] .= $nbFather;
120 }
121 $head[$h][1] .= ($nbFather && $nbChild) ? '+' : '';
122 if ($nbChild) {
123 $head[$h][1] .= $nbChild;
124 }
125 $head[$h][1] .= '</span>';
126 }
127 $head[$h][2] = 'subproduct';
128 $h++;
129 }
130
131 if (isModEnabled('variants') && ($object->isProduct() || $object->isService())) {
132 global $db;
133
134 require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination.class.php';
135
136 $prodcomb = new ProductCombination($db);
137
138 if ($prodcomb->fetchByFkProductChild($object->id) <= 0) {
139 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/variants/combinations.php', ['id' => $object->id]);
140 $head[$h][1] = $langs->trans('ProductCombinations');
141 $head[$h][2] = 'combinations';
142 $nbVariant = $prodcomb->countNbOfCombinationForFkProductParent($object->id);
143 if ($nbVariant > 0) {
144 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbVariant.'</span>';
145 }
146 }
147
148 $h++;
149 }
150
151 if (($object->isProduct() || ($object->isService() && getDolGlobalString('STOCK_SUPPORTS_SERVICES'))) && $object->stockable_product == Product::ENABLED_STOCK) { // If physical product we can stock (or service with option)
152 if (isModEnabled('stock') && $user->hasRight('stock', 'lire')) {
153 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/stock/product.php', ['id' => $object->id]);
154 $head[$h][1] = $langs->trans("Stock");
155 $head[$h][2] = 'stock';
156 $h++;
157 }
158 }
159
160 // Tab to link resources
161 if (isModEnabled('resource')) {
162 if ($object->isProduct() && getDolGlobalString('RESOURCE_ON_PRODUCTS')) {
163 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/resource/element_resource.php', ['element' => 'product', 'element_id' => $object->id]);
164 $head[$h][1] = $langs->trans("Resources");
165 $head[$h][2] = 'resources';
166 $h++;
167 }
168 if ($object->isService() && getDolGlobalString('RESOURCE_ON_SERVICES')) {
169 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/resource/element_resource.php', ['element' => 'service', 'element_id' => $object->id]);
170 $head[$h][1] = $langs->trans("Resources");
171 $head[$h][2] = 'resources';
172 $h++;
173 }
174 }
175 if (getDolGlobalString('MAIN_ENABLE_PRODUCTS_CONTACTS_TAB')) {
176 $objectsrc = $object;
177 if ($object->origin_type == 'product' && $object->origin_id > 0) {
178 $objectsrc = new Product($db);
179 $objectsrc->fetch($object->origin_id);
180 }
181 $nbContact = count($objectsrc->liste_contact(-1, 'internal')) + count($objectsrc->liste_contact(-1, 'external'));
182 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/contact.php', ['id' => $object->id]);
183 $head[$h][1] = $langs->trans("ContactsAddresses");
184 if ($nbContact > 0) {
185 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbContact.'</span>';
186 }
187 $head[$h][2] = 'contact';
188 $h++;
189 }
190 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/stats/facture.php', ['showmessage' => 1, 'id' => $object->id]);
191 $head[$h][1] = $langs->trans('Referers');
192 $head[$h][2] = 'referers';
193 $h++;
194
195 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/stats/index.php', ['id' => $object->id]);
196 $head[$h][1] = $langs->trans('Statistics');
197 $head[$h][2] = 'stats';
198 $h++;
199
200 // Show more tabs from modules
201 // Entries must be declared in modules descriptor with line
202 // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
203 // $this->tabs = array('entity:-tabname); to remove a tab
204 complete_head_from_modules($conf, $langs, $object, $head, $h, 'product', 'add', 'core');
205
206 // Notes
207 if (!getDolGlobalString('MAIN_DISABLE_NOTES_TAB')) {
208 $nbNote = 0;
209 if (!empty($object->note_private)) {
210 $nbNote++;
211 }
212 if (!empty($object->note_public)) {
213 $nbNote++;
214 }
215 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/note.php', ['id' => $object->id]);
216 $head[$h][1] = $langs->trans('Notes');
217 if ($nbNote > 0) {
218 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbNote.'</span>';
219 }
220 $head[$h][2] = 'note';
221 $h++;
222 }
223
224 // Attachments
225 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
226 require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
227 $upload_dir = null;
228 $nbFiles = 0;
229 if (isModEnabled("product") && ($object->type == Product::TYPE_PRODUCT)) {
230 $upload_dir = $conf->product->multidir_output[$object->entity ?? $conf->entity].'/'.dol_sanitizeFileName($object->ref);
231 }
232 if (isModEnabled("service") && ($object->type == Product::TYPE_SERVICE)) {
233 $upload_dir = $conf->service->multidir_output[$object->entity ?? $conf->entity].'/'.dol_sanitizeFileName($object->ref);
234 }
235 if ($upload_dir !== null) {
236 $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
237 }
238 if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) {
239 if (isModEnabled("product") && ($object->type == Product::TYPE_PRODUCT)) {
240 $upload_dir = $conf->product->multidir_output[$object->entity ?? $conf->entity].'/'.get_exdir($object->id, 2, 0, 0, $object, 'product').$object->id.'/photos';
241 }
242 if (isModEnabled("service") && ($object->type == Product::TYPE_SERVICE)) {
243 $upload_dir = $conf->service->multidir_output[$object->entity ?? $conf->entity].'/'.get_exdir($object->id, 2, 0, 0, $object, 'product').$object->id.'/photos';
244 }
245 if ($upload_dir !== null) {
246 $nbFiles += count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
247 }
248 }
249 $nbLinks = Link::count($db, $object->element, $object->id);
250 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/document.php', ['id' => $object->id]);
251 $head[$h][1] = $langs->trans('Documents');
252 if (($nbFiles + $nbLinks) > 0) {
253 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.($nbFiles + $nbLinks).'</span>';
254 }
255 $head[$h][2] = 'documents';
256 $h++;
257
258 // Log
259 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/messaging.php', ['id' => $object->id]);
260 $head[$h][1] = $langs->trans("Events");
261 if (isModEnabled('agenda') && ($user->hasRight('agenda', 'myactions', 'read') || $user->hasRight('agenda', 'allactions', 'read'))) {
262 $nbEvent = 0;
263 // Enable caching of product count actioncomm
264 require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php';
265 $cachekey = 'count_events_product_'.$object->id;
266 $dataretrieved = dol_getcache($cachekey);
267 if (!is_null($dataretrieved)) {
268 $nbEvent = $dataretrieved;
269 } else {
270 $sql = "SELECT COUNT(id) as nb";
271 $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm";
272 $sql .= " WHERE fk_element = ".((int) $object->id);
273 $sql .= " AND elementtype = 'product'";
274 $resql = $db->query($sql);
275 if ($resql) {
276 $obj = $db->fetch_object($resql);
277 $nbEvent = $obj->nb;
278 } else {
279 dol_syslog('Failed to count actioncomm '.$db->lasterror(), LOG_ERR);
280 }
281 dol_setcache($cachekey, $nbEvent, 120); // If setting cache fails, this is not a problem, so we do not test result.
282 }
283
284 $head[$h][1] .= '/';
285 $head[$h][1] .= $langs->trans("Agenda");
286 if ($nbEvent > 0) {
287 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbEvent.'</span>';
288 }
289 }
290 $head[$h][2] = 'agenda';
291 $h++;
292
293 complete_head_from_modules($conf, $langs, $object, $head, $h, 'product', 'add', 'external');
294
295 complete_head_from_modules($conf, $langs, $object, $head, $h, 'product', 'remove');
296
297 return $head;
298}
299
307{
308 global $db, $langs, $conf, $user;
309
310 // Load translation files required by the page
311 $langs->loadLangs(array("products", "productbatch"));
312
313 $h = 0;
314 $head = array();
315
316 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/stock/productlot_card.php', ['id' => $object->id]);
317 $head[$h][1] = $langs->trans("Lot");
318 $head[$h][2] = 'card';
319 $h++;
320
321 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/stock/stats/expedition.php', ['showmessage' => 1, 'id' => $object->id]);
322 $head[$h][1] = $langs->trans('Referers');
323 $head[$h][2] = 'referers';
324 $h++;
325
326 // Attachments
327 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
328 require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
329 $upload_dir = $conf->productbatch->multidir_output[$object->entity ?? $conf->entity].'/'.dol_sanitizeFileName($object->ref);
330 $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
331 $nbLinks = Link::count($db, $object->element, $object->id);
332 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/stock/productlot_document.php', ['id' => $object->id]);
333 $head[$h][1] = $langs->trans("Documents");
334 if (($nbFiles + $nbLinks) > 0) {
335 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.($nbFiles + $nbLinks).'</span>';
336 }
337 $head[$h][2] = 'documents';
338 $h++;
339
340 // Notes
341 if (!getDolGlobalString('MAIN_DISABLE_NOTES_TAB')) {
342 $nbNote = 0;
343 if (!empty($object->note_private)) {
344 $nbNote++;
345 }
346 if (!empty($object->note_public)) {
347 $nbNote++;
348 }
349 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT .'/product/stock/productlot_note.php', ['id' => $object->id]);
350 $head[$h][1] = $langs->trans('Notes');
351 if ($nbNote > 0) {
352 $head[$h][1] .= '<span class="badge marginleftonlyshort">' . $nbNote . '</span>';
353 }
354 $head[$h][2] = 'note';
355 $h++;
356 }
357
358 // Show more tabs from modules
359 // Entries must be declared in modules descriptor with line
360 // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
361 // $this->tabs = array('entity:-tabname); to remove a tab
362 complete_head_from_modules($conf, $langs, $object, $head, $h, 'productlot');
363
364 complete_head_from_modules($conf, $langs, $object, $head, $h, 'productlot', 'remove');
365
366 // Log
367 /*
368 $head[$h][0] = DOL_URL_ROOT.'/product/info.php', ['id' => $object->id]);
369 $head[$h][1] = $langs->trans("Info");
370 $head[$h][2] = 'info';
371 $h++;
372 */
373
374 return $head;
375}
376
377
378
385{
386 global $langs, $conf, $extrafields;
387
388 $extrafields->fetch_name_optionals_label('product');
389 $extrafields->fetch_name_optionals_label('product_lang');
390 $extrafields->fetch_name_optionals_label('product_price');
391 $extrafields->fetch_name_optionals_label('product_customer_price');
392 $extrafields->fetch_name_optionals_label('product_fournisseur_price');
393
394 $h = 0;
395 $head = array();
396
397 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT."/product/admin/product.php");
398 $head[$h][1] = $langs->trans('Parameters');
399 $head[$h][2] = 'general';
400 $h++;
401
402 if (getDolGlobalString('PRODUIT_MULTIPRICES') && getDolGlobalString('PRODUIT_MULTIPRICES_ALLOW_AUTOCALC_PRICELEVEL')) {
403 $head[$h] = array(
404 0 => dolBuildUrl(DOL_URL_ROOT."/product/admin/price_rules.php"),
405 1 => $langs->trans('MultipriceRules'),
406 2 => 'generator'
407 );
408 $h++;
409 }
410
411 // Show more tabs from modules
412 // Entries must be declared in modules descriptor with line
413 // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
414 // $this->tabs = array('entity:-tabname); to remove a tab
415 complete_head_from_modules($conf, $langs, null, $head, $h, 'product_admin');
416
417 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/admin/product_extrafields.php');
418 $head[$h][1] = $langs->trans("ExtraFields");
419 $nbExtrafields = isset($extrafields->attributes['product']['count']) ? $extrafields->attributes['product']['count'] : 0;
420 if ($nbExtrafields > 0) {
421 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbExtrafields.'</span>';
422 }
423 $head[$h][2] = 'attributes';
424 $h++;
425
426 // Multilangs Extrafields
427 if (getDolGlobalInt('MAIN_MULTILANGS')) {
428 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/admin/product_lang_extrafields.php');
429 $head[$h][1] = $langs->trans("TranslationsExtrafields");
430 $nbExtrafields = isset($extrafields->attributes['product_lang']['count']) ? $extrafields->attributes['product_lang']['count'] : 0;
431 if ($nbExtrafields > 0) {
432 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbExtrafields.'</span>';
433 }
434 $head[$h][2] = 'translationAttributes';
435 $h++;
436 }
437
438 // Extrafields for price levels
439 if (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) {
440 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/admin/product_price_extrafields.php');
441 $head[$h][1] = $langs->trans("ProductLevelExtraFields");
442 $nbExtrafields = isset($extrafields->attributes['product_price']['count']) ? $extrafields->attributes['product_price']['count'] : 0;
443 if ($nbExtrafields > 0) {
444 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbExtrafields.'</span>';
445 }
446 $head[$h][2] = 'levelAttributes';
447 $h++;
448 }
449
450 // Extrafields for price per customer
451 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) {
452 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/admin/product_customer_extrafields.php');
453 $head[$h][1] = $langs->trans("ProductCustomerExtraFields");
454 $nbExtrafields = isset($extrafields->attributes['product_customer_price']['count']) ? $extrafields->attributes['product_customer_price']['count'] : 0;
455 if ($nbExtrafields > 0) {
456 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbExtrafields.'</span>';
457 }
458 $head[$h][2] = 'customerAttributes';
459 $h++;
460 }
461
462 // Supplier prices
463 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/admin/product_supplier_extrafields.php');
464 $head[$h][1] = $langs->trans("ProductSupplierExtraFields");
465 $nbExtrafields = isset($extrafields->attributes['product_fournisseur_price']['count']) ? $extrafields->attributes['product_fournisseur_price']['count'] : 0;
466 if ($nbExtrafields > 0) {
467 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbExtrafields.'</span>';
468 }
469 $head[$h][2] = 'supplierAttributes';
470 $h++;
471
472 complete_head_from_modules($conf, $langs, null, $head, $h, 'product_admin', 'remove');
473
474 return $head;
475}
476
477
478
485{
486 global $langs, $conf, $user, $extrafields;
487
488 $extrafields->fetch_name_optionals_label('product_lot');
489
490 $h = 0;
491 $head = array();
492
493 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT."/product/admin/product_lot.php");
494 $head[$h][1] = $langs->trans('Parameters');
495 $head[$h][2] = 'settings';
496 $h++;
497
498 // Show more tabs from modules
499 // Entries must be declared in modules descriptor with line
500 // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
501 // $this->tabs = array('entity:-tabname); to remove a tab
502 complete_head_from_modules($conf, $langs, null, $head, $h, 'product_lot_admin');
503
504 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/product/admin/product_lot_extrafields.php');
505 $head[$h][1] = $langs->trans("ExtraFields");
506 $nbExtrafields = $extrafields->attributes['product_lot']['count'];
507 if ($nbExtrafields > 0) {
508 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbExtrafields.'</span>';
509 }
510 $head[$h][2] = 'attributes';
511 $h++;
512
513 complete_head_from_modules($conf, $langs, null, $head, $h, 'product_lot_admin', 'remove');
514
515 return $head;
516}
517
518
519
527function show_stats_for_company($product, $socid)
528{
529 global $langs, $user, $db, $hookmanager;
530
531 $form = new Form($db);
532
533 $nblines = 0;
534
535 print '<tr class="liste_titre">';
536 print '<td class="liste_titre left">';
537 print $form->textwithpicto($langs->trans("Referers"), $langs->trans("ClinkOnALinkOfColumn", $langs->transnoentitiesnoconv("Referers")));
538 print '</td>';
539 print '<td class="liste_titre right">'.$langs->trans("NbOfThirdParties").'</td>';
540 print '<td class="liste_titre right">'.$langs->trans("NbOfObjectReferers").'</td>';
541 print '<td class="liste_titre right">'.$langs->trans("TotalQuantity").'</td>';
542 print '</tr>';
543
544 // Customer proposals
545 if (isModEnabled("propal") && $user->hasRight('propal', 'lire')) {
546 $nblines++;
547 $ret = $product->load_stats_propale($socid);
548 if ($ret < 0) {
550 }
551 $langs->load("propal");
552 print '<tr><td>';
553 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stats/propal.php', ['id' => $product->id], false, 'anchorundermenu').'">'.img_object('', 'propal', 'class="pictofixedwidth"').$langs->trans("Proposals").'</a>';
554 print '</td><td class="right">';
555 print $product->stats_propale['customers'];
556 print '</td><td class="right">';
557 print $product->stats_propale['nb'];
558 print '</td><td class="right">';
559 print price($product->stats_propale['qty'], 1, $langs, 0, 0);
560 print '</td>';
561 print '</tr>';
562 }
563 // Supplier proposals
564 if (isModEnabled('supplier_proposal') && $user->hasRight('supplier_proposal', 'lire')) {
565 $nblines++;
566 $ret = $product->load_stats_proposal_supplier($socid);
567 if ($ret < 0) {
569 }
570 $langs->load("supplier_proposal");
571 print '<tr><td>';
572 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stats/supplier_proposal.php', ['id' => $product->id], false, 'anchorundermenu').'">'.img_object('', 'supplier_proposal', 'class="pictofixedwidth"').$langs->trans("SupplierProposals").'</a>';
573 print '</td><td class="right">';
574 print $product->stats_proposal_supplier['suppliers'];
575 print '</td><td class="right">';
576 print $product->stats_proposal_supplier['nb'];
577 print '</td><td class="right">';
578 print price($product->stats_proposal_supplier['qty'], 1, $langs, 0, 0);
579 print '</td>';
580 print '</tr>';
581 }
582 // Sales orders
583 if (isModEnabled('order') && $user->hasRight('commande', 'lire')) {
584 $nblines++;
585 $ret = $product->load_stats_commande($socid);
586 if ($ret < 0) {
588 }
589 $langs->load("orders");
590 print '<tr><td>';
591 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stats/commande.php', ['id' => $product->id], false, 'anchorundermenu').'">'.img_object('', 'order', 'class="pictofixedwidth"').$langs->trans("CustomersOrders").'</a>';
592 print '</td><td class="right">';
593 print $product->stats_commande['customers'];
594 print '</td><td class="right">';
595 print $product->stats_commande['nb'];
596 print '</td><td class="right">';
597 print price($product->stats_commande['qty'], 1, $langs, 0, 0);
598 print '</td>';
599 print '</tr>';
600 }
601 // Supplier orders
602 if ((isModEnabled("fournisseur") && !getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight('fournisseur', 'commande', 'lire')) || (isModEnabled("supplier_order") && $user->hasRight('supplier_order', 'lire'))) {
603 $nblines++;
604 $ret = $product->load_stats_commande_fournisseur($socid);
605 if ($ret < 0) {
607 }
608 $langs->load("orders");
609 print '<tr><td>';
610 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stats/commande_fournisseur.php', ['id' => $product->id], false, 'anchorundermenu').'">'.img_object('', 'supplier_order', 'class="pictofixedwidth"').$langs->trans("SuppliersOrders").'</a>';
611 print '</td><td class="right">';
612 print $product->stats_commande_fournisseur['suppliers'];
613 print '</td><td class="right">';
614 print $product->stats_commande_fournisseur['nb'];
615 print '</td><td class="right">';
616 print price($product->stats_commande_fournisseur['qty'], 1, $langs, 0, 0);
617 print '</td>';
618 print '</tr>';
619 }
620 // Customer invoices
621 if (isModEnabled('invoice') && $user->hasRight('facture', 'lire')) {
622 $nblines++;
623 $ret = $product->load_stats_facture($socid);
624 if ($ret < 0) {
626 }
627 $langs->load("bills");
628 print '<tr><td>';
629 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stats/facture.php', ['id' => $product->id], false, 'anchorundermenu').'">'.img_object('', 'bill', 'class="pictofixedwidth"').$langs->trans("CustomersInvoices").'</a>';
630 print '</td><td class="right">';
631 print $product->stats_facture['customers'];
632 print '</td><td class="right">';
633 print $product->stats_facture['nb'];
634 print '</td><td class="right">';
635 print price($product->stats_facture['qty'], 1, $langs, 0, 0);
636 print '</td>';
637 print '</tr>';
638 }
639 // Customer template invoices
640 if (isModEnabled("invoice") && $user->hasRight('facture', 'lire')) {
641 $nblines++;
642 $ret = $product->load_stats_facturerec($socid);
643 if ($ret < 0) {
645 }
646 $langs->load("bills");
647 print '<tr><td>';
648 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stats/facturerec.php', ['id' => $product->id], false, 'anchorundermenu').'">'.img_object('', 'bill', 'class="pictofixedwidth"').$langs->trans("RecurringInvoiceTemplate").'</a>';
649 print '</td><td class="right">';
650 print $product->stats_facturerec['customers'];
651 print '</td><td class="right">';
652 print $product->stats_facturerec['nb'];
653 print '</td><td class="right">';
654 print $product->stats_facturerec['qty'];
655 print '</td>';
656 print '</tr>';
657 }
658 // Supplier invoices
659 if ((isModEnabled("fournisseur") && !getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight('fournisseur', 'facture', 'lire')) || (isModEnabled("supplier_invoice") && $user->hasRight('supplier_invoice', 'lire'))) {
660 $nblines++;
661 $ret = $product->load_stats_facture_fournisseur($socid);
662 if ($ret < 0) {
664 }
665 $langs->load("bills");
666 print '<tr><td>';
667 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stats/facture_fournisseur.php', ['id' => $product->id], false, 'anchorundermenu').'">'.img_object('', 'supplier_invoice', 'class="pictofixedwidth"').$langs->trans("SuppliersInvoices").'</a>';
668 print '</td><td class="right">';
669 print $product->stats_facture_fournisseur['suppliers'];
670 print '</td><td class="right">';
671 print $product->stats_facture_fournisseur['nb'];
672 print '</td><td class="right">';
673 print price($product->stats_facture_fournisseur['qty'], 1, $langs, 0, 0);
674 print '</td>';
675 print '</tr>';
676 }
677 // Supplier template invoices
678 /* TODO
679 if (isModEnabled("invoice") && $user->hasRight('fournisseur', 'facture', 'lire')) {
680 $nblines++;
681 $ret = $product->load_stats_facture_fournisseurrec($socid);
682 if ($ret < 0) {
683 dol_print_error($db);
684 }
685 $langs->load("bills");
686 print '<tr><td>';
687 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stats/facture_facturerec.php', ['id' => $product->id], false, 'anchorundermenu').'">'.img_object('', 'bill', 'class="pictofixedwidth"').$langs->trans("RecurringInvoiceTemplate").'</a>';
688 print '</td><td class="right">';
689 print $product->stats_facturefournrec['customers'];
690 print '</td><td class="right">';
691 print $product->stats_facturefournrec['nb'];
692 print '</td><td class="right">';
693 print $product->stats_facturefournrec['qty'];
694 print '</td>';
695 print '</tr>';
696 }
697 */
698
699 // Shipments
700 if (isModEnabled('shipping') && $user->hasRight('shipping', 'lire')) {
701 $nblines++;
702 $ret = $product->load_stats_sending($socid);
703 if ($ret < 0) {
705 }
706 $langs->load("sendings");
707 print '<tr><td>';
708 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stats/expedition.php', ['id' => $product->id], false, 'anchorundermenu').'">'.img_object('', 'shipment', 'class="pictofixedwidth"').$langs->trans("Shipments").'</a>';
709 print '</td><td class="right">';
710 print $product->stats_expedition['customers'];
711 print '</td><td class="right">';
712 print $product->stats_expedition['nb'];
713 print '</td><td class="right">';
714 print $product->stats_expedition['qty'];
715 print '</td>';
716 print '</tr>';
717 }
718
719 // Receptions
720 if ((isModEnabled("reception") && $user->hasRight('reception', 'lire'))) {
721 $nblines++;
722 $ret = $product->load_stats_reception($socid);
723 if ($ret < 0) {
725 }
726 $langs->load("receptions");
727 print '<tr><td>';
728 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stats/reception.php', ['id' => $product->id], false, 'anchorundermenu').'">'.img_object('', 'reception', 'class="pictofixedwidth"').$langs->trans("Receptions").'</a>';
729 print '</td><td class="right">';
730 print $product->stats_reception['suppliers'];
731 print '</td><td class="right">';
732 print $product->stats_reception['nb'];
733 print '</td><td class="right">';
734 print $product->stats_reception['qty'];
735 print '</td>';
736 print '</tr>';
737 }
738
739 // Contracts
740 if (isModEnabled('contract') && $user->hasRight('contrat', 'lire')) {
741 $nblines++;
742 $ret = $product->load_stats_contrat($socid);
743 if ($ret < 0) {
745 }
746 $langs->load("contracts");
747 print '<tr><td>';
748 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stats/contrat.php', ['id' => $product->id], false, 'anchorundermenu').'">'.img_object('', 'contract', 'class="pictofixedwidth"').$langs->trans("Contracts").'</a>';
749 print '</td><td class="right">';
750 print $product->stats_contrat['customers'];
751 print '</td><td class="right">';
752 print $product->stats_contrat['nb'];
753 print '</td><td class="right">';
754 print price($product->stats_contrat['qty'], 1, $langs, 0, 0);
755 print '</td>';
756 print '</tr>';
757 }
758
759 // BOM
760 if (isModEnabled('bom') && $user->hasRight('bom', 'read')) {
761 $nblines++;
762 $ret = $product->load_stats_bom($socid);
763 if ($ret < 0) {
764 setEventMessage($product->error, 'errors');
765 }
766 $langs->load("mrp");
767
768 print '<tr><td>';
769 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stats/bom.php', ['id' => $product->id], false, 'anchorundermenu').'">'.img_object('', 'bom', 'class="pictofixedwidth"').$langs->trans("BOM").'</a>';
770 print '</td><td class="right">';
771
772 print '</td><td class="right">';
773 print $form->textwithpicto((string) $product->stats_bom['nb_toconsume'], $langs->trans("RowMaterial"));
774 print ' ';
775 print $form->textwithpicto((string) $product->stats_bom['nb_toproduce'], $langs->trans("Finished"));
776 print '</td><td class="right">';
777 print $form->textwithpicto((string) $product->stats_bom['qty_toconsume'], $langs->trans("RowMaterial"));
778 print ' ';
779 print $form->textwithpicto((string) $product->stats_bom['qty_toproduce'], $langs->trans("Finished"));
780 print '</td>';
781 print '</tr>';
782 }
783
784 // MO
785 if (isModEnabled('mrp') && $user->hasRight('mrp', 'read')) {
786 $nblines++;
787 $ret = $product->load_stats_mo($socid);
788 if ($ret < 0) {
789 setEventMessages($product->error, $product->errors, 'errors');
790 }
791 $langs->load("mrp");
792 print '<tr><td>';
793 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stats/mo.php', ['id' => $product->id], false, 'anchorundermenu').'">'.img_object('', 'mrp', 'class="pictofixedwidth"').$langs->trans("MO").'</a>';
794 print '</td><td class="right">';
795 print $form->textwithpicto((string) $product->stats_mo['customers_toconsume'], $langs->trans("ToConsume"));
796 print ' ';
797 print $form->textwithpicto((string) $product->stats_mo['customers_consumed'], $langs->trans("QtyAlreadyConsumed"));
798 print ' ';
799 print $form->textwithpicto((string) $product->stats_mo['customers_toproduce'], $langs->trans("QtyToProduce"));
800 print ' ';
801 print $form->textwithpicto((string) $product->stats_mo['customers_produced'], $langs->trans("QtyAlreadyProduced"));
802 print '</td><td class="right">';
803 print $form->textwithpicto((string) $product->stats_mo['nb_toconsume'], $langs->trans("ToConsume"));
804 print ' ';
805 print $form->textwithpicto((string) $product->stats_mo['nb_consumed'], $langs->trans("QtyAlreadyConsumed"));
806 print ' ';
807 print $form->textwithpicto((string) $product->stats_mo['nb_toproduce'], $langs->trans("QtyToProduce"));
808 print ' ';
809 print $form->textwithpicto((string) $product->stats_mo['nb_produced'], $langs->trans("QtyAlreadyProduced"));
810 print '</td><td class="right">';
811 print $form->textwithpicto((string) $product->stats_mo['qty_toconsume'], $langs->trans("ToConsume"));
812 print ' ';
813 print $form->textwithpicto((string) $product->stats_mo['qty_consumed'], $langs->trans("QtyAlreadyConsumed"));
814 print ' ';
815 print $form->textwithpicto((string) $product->stats_mo['qty_toproduce'], $langs->trans("QtyToProduce"));
816 print ' ';
817 print $form->textwithpicto((string) $product->stats_mo['qty_produced'], $langs->trans("QtyAlreadyProduced"));
818 print '</td>';
819 print '</tr>';
820 }
821 $parameters = array('socid' => $socid);
822 $reshook = $hookmanager->executeHooks('addMoreProductStat', $parameters, $product, $nblines); // Note that $action and $object may have been modified by some hooks // TODO: Verify that $nblines is the correct value for argument $action
823 if ($reshook < 0) {
824 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
825 }
826
827 print $hookmanager->resPrint;
828
829
830 return $nblines++;
831}
832
840function show_stats_for_batch($batch, $socid)
841{
842 global $conf, $langs, $user, $db, $hookmanager;
843
844 $langs->LoadLangs(array('sendings', 'orders', 'receptions'));
845
846 $form = new Form($db);
847
848 $nblines = 0;
849
850 print '<tr class="liste_titre">';
851 print '<td class="left" width="25%">'.$langs->trans("Referers").'</td>';
852 print '<td class="right" width="25%">'.$langs->trans("NbOfThirdParties").'</td>';
853 print '<td class="right" width="25%">'.$langs->trans("NbOfObjectReferers").'</td>';
854 print '<td class="right" width="25%">'.$langs->trans("TotalQuantity").'</td>';
855 print '</tr>';
856
857 // Expeditions
858 if (isModEnabled('shipping') && $user->hasRight('expedition', 'lire')) {
859 $nblines++;
860 $ret = $batch->loadStatsExpedition($socid);
861 if ($ret < 0) {
863 }
864 $langs->load("bills");
865 print '<tr><td>';
866 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stock/stats/expedition.php', ['id' => $batch->id]).'">'.img_object('', 'bill', 'class="pictofixedwidth"').$langs->trans("Shipments").'</a>';
867 print '</td><td class="right">';
868 print $batch->stats_expedition['customers'];
869 print '</td><td class="right">';
870 print $batch->stats_expedition['nb'];
871 print '</td><td class="right">';
872 print $batch->stats_expedition['qty'];
873 print '</td>';
874 print '</tr>';
875 }
876
877 if (isModEnabled("reception") && $user->hasRight('reception', 'lire')) {
878 $nblines++;
879 $ret = $batch->loadStatsReception($socid);
880 if ($ret < 0) {
882 }
883 $langs->load("bills");
884 print '<tr><td>';
885 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stock/stats/reception.php', ['id' => $batch->id]).'">'.img_object('', 'bill', 'class="pictofixedwidth"').$langs->trans("Receptions").'</a>';
886 print '</td><td class="right">';
887 print $batch->stats_reception['customers'];
888 print '</td><td class="right">';
889 print $batch->stats_reception['nb'];
890 print '</td><td class="right">';
891 print $batch->stats_reception['qty'];
892 print '</td>';
893 print '</tr>';
894 } elseif (isModEnabled('supplier_order') && $user->hasRight('fournisseur', 'commande', 'lire')) {
895 $nblines++;
896 $ret = $batch->loadStatsSupplierOrder($socid);
897 if ($ret < 0) {
899 }
900 $langs->load("bills");
901 print '<tr><td>';
902 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stock/stats/commande_fournisseur.php', ['id' => $batch->id]).'">'.img_object('', 'bill', 'class="pictofixedwidth"').$langs->trans("SuppliersOrders").'</a>';
903 print '</td><td class="right">';
904 print $batch->stats_supplier_order['customers'];
905 print '</td><td class="right">';
906 print $batch->stats_supplier_order['nb'];
907 print '</td><td class="right">';
908 print $batch->stats_supplier_order['qty'];
909 print '</td>';
910 print '</tr>';
911 }
912
913 if (isModEnabled('mrp') && $user->hasRight('mrp', 'read')) {
914 $nblines++;
915 $ret = $batch->loadStatsMo($socid);
916 if ($ret < 0) {
918 }
919 $langs->load("mrp");
920 print '<tr><td>';
921 print '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/product/stock/stats/mo.php', ['id' => $batch->id]).'">'.img_object('', 'mrp', 'class="pictofixedwidth"').$langs->trans("MO").'</a>';
922 print '</td><td class="right">';
923 // 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
924 print $form->textwithpicto((string) $batch->stats_mo['customers_consumed'], $langs->trans("QtyAlreadyConsumed"));
925 // 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
926 print $form->textwithpicto((string) $batch->stats_mo['customers_produced'], $langs->trans("QtyAlreadyProduced"));
927 print '</td><td class="right">';
928 // 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
929 print $form->textwithpicto((string) $batch->stats_mo['nb_consumed'], $langs->trans("QtyAlreadyConsumed"));
930 // 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
931 print $form->textwithpicto((string) $batch->stats_mo['nb_produced'], $langs->trans("QtyAlreadyProduced"));
932 print '</td><td class="right">';
933 // 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
934 print $form->textwithpicto((string) $batch->stats_mo['qty_consumed'], $langs->trans("QtyAlreadyConsumed"));
935 // 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
936 print $form->textwithpicto((string) $batch->stats_mo['qty_produced'], $langs->trans("QtyAlreadyProduced"));
937 print '</td>';
938 print '</tr>';
939 }
940
941 $parameters = array('socid' => $socid);
942 $reshook = $hookmanager->executeHooks('addMoreBatchProductStat', $parameters, $batch, $nblines); // Note that $action and $object may have been modified by some hooks // TODO: Verify that $nblines is the correct value for argument $action
943 if ($reshook < 0) {
944 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
945 }
946
947 print $hookmanager->resPrint;
948
949
950 return $nblines++;
951}
952
965function measuring_units_string($unitscale = null, $measuring_style = '', $unitid = 0, $use_short_label = 0, $outputlangs = null)
966{
967 return measuringUnitString($unitid, $measuring_style, $unitscale, $use_short_label, $outputlangs);
968}
969
981function measuringUnitString($unitid, $measuring_style = '', $unitscale = null, $use_short_label = 0, $outputlangs = null)
982{
983 global $langs, $db;
984 global $measuring_unit_cache;
985
986 if (empty($outputlangs)) {
987 $outputlangs = $langs;
988 }
989
990 if (empty($measuring_unit_cache[$unitid.'_'.$measuring_style.'_'.$unitscale.'_'.$use_short_label])) {
991 require_once DOL_DOCUMENT_ROOT.'/core/class/cunits.class.php';
992 $measuringUnits = new CUnits($db);
993
994 if ($measuring_style == '' && $unitscale == '') {
995 $arrayforfilter = array(
996 't.rowid' => $unitid,
997 't.active' => 1
998 );
999 } elseif ($unitscale !== '') {
1000 $arrayforfilter = array(
1001 't.scale' => $unitscale,
1002 't.unit_type' => $measuring_style,
1003 't.active' => 1
1004 );
1005 } else {
1006 $arrayforfilter = array(
1007 't.rowid' => $unitid,
1008 't.unit_type' => $measuring_style,
1009 't.active' => 1
1010 );
1011 }
1012 $result = $measuringUnits->fetchAll('', '', 0, 0, $arrayforfilter);
1013
1014 if ($result < 0) {
1015 return -1;
1016 } else {
1017 if (is_array($measuringUnits->records) && count($measuringUnits->records) > 0) {
1018 if ($use_short_label == 1) {
1019 $labeltoreturn = $measuringUnits->records[key($measuringUnits->records)]->short_label;
1020 } elseif ($use_short_label == 2) {
1021 $labeltoreturn = $outputlangs->transnoentitiesnoconv(ucfirst((string) $measuringUnits->records[key($measuringUnits->records)]->label).'Short');
1022 } else {
1023 $labeltoreturn = $outputlangs->transnoentitiesnoconv((string) $measuringUnits->records[key($measuringUnits->records)]->label);
1024 }
1025 } else {
1026 $labeltoreturn = '';
1027 }
1028 $measuring_unit_cache[$unitid.'_'.$measuring_style.'_'.$unitscale.'_'.$use_short_label] = $labeltoreturn;
1029 return $labeltoreturn;
1030 }
1031 } else {
1032 return $measuring_unit_cache[$unitid.'_'.$measuring_style.'_'.$unitscale.'_'.$use_short_label];
1033 }
1034}
1035
1043function measuring_units_squared($unitscale)
1044{
1045 $measuring_units = array();
1046 $measuring_units[0] = 0; // m -> m3
1047 $measuring_units[-1] = -2; // dm-> dm2
1048 $measuring_units[-2] = -4; // cm -> cm2
1049 $measuring_units[-3] = -6; // mm -> mm2
1050 $measuring_units[98] = 98; // foot -> foot2
1051 $measuring_units[99] = 99; // inch -> inch2
1052 return $measuring_units[$unitscale];
1053}
1054
1055
1064{
1065 $measuring_units = array();
1066 $measuring_units[0] = 0; // m -> m2
1067 $measuring_units[-1] = -3; // dm-> dm3
1068 $measuring_units[-2] = -6; // cm -> cm3
1069 $measuring_units[-3] = -9; // mm -> mm3
1070 $measuring_units[98] = 88; // foot -> foot3
1071 $measuring_units[99] = 89; // inch -> inch3
1072 return $measuring_units[$unit];
1073}
1074
1082{
1083 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1084 global $db, $conf;
1085
1086 $productarray = array();
1087 $sql = "SELECT p.rowid as id, p.ref, p.label, p.description, p.entity";
1088 $sql .= " FROM ".MAIN_DB_PREFIX."product as p";
1089 $sql .= " WHERE p.entity IN (".getEntity('product').")";
1090 $sql .= " AND p.rowid = ".((int) $id);
1091
1092 $resql = $db->query($sql);
1093
1094 if ($resql) {
1095 $productarray = $db->fetch_array($resql);
1096 } else {
1098 return -1;
1099 }
1100
1101 $object = new Product($db);
1102 $result = $object->fetch($id);
1103 if ($result < 0) {
1104 dol_print_error($db, $object->error, $object->errors);
1105 }
1106 $entity = (empty($object->entity) ? $conf->entity : $object->entity);
1107 $productarray["image"] = $object->show_photos('product', $conf->product->multidir_output[$entity], 1, 1, 0, 0, 0, 120, 160, 1, '');
1108 if ($object->nbphoto <= 0) {
1109 $productarray["image"] = "";
1110 }
1111 return $productarray;
1112}
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
Class of dictionary type of thirdparty (used by imports)
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.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
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:64
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
setEventMessage($mesgs, $style='mesgs', $noduplicate=0, $attop=0)
Set event message in dol_events session object.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
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_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.
isModEnabled($module)
Is Dolibarr module enabled.
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_setcache($memoryid, $data, $expire=0, $filecache=0, $replace=0)
Save data into a memory area shared by all users, all sessions on server.
dol_getcache($memoryid, $filecache=0)
Read a memory area shared by all users, all sessions on server.
measuring_units_squared($unitscale)
Transform a given unit scale into the square of that unit, if known.
show_stats_for_batch($batch, $socid)
Show stats for product batch.
measuringUnitString($unitid, $measuring_style='', $unitscale=null, $use_short_label=0, $outputlangs=null)
Return translation label of a unit key.
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.
getProductForEmailTemplate($id)
Retrieve and return product for mail template.
show_stats_for_company($product, $socid)
Show stats for a product.
productlot_prepare_head($object)
Prepare array with list of tabs.
measuring_units_string($unitscale=null, $measuring_style='', $unitid=0, $use_short_label=0, $outputlangs=null)
Return translation label of a unit key.
product_lot_admin_prepare_head()
Return array head with list of tabs to view object information.
measuring_units_cubed($unit)
Transform a given unit scale into the cube of that unit, if known.