dolibarr 25.0.0-alpha
inventory.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2007-2019 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2014-2016 Juanjo Menent <jmenent@2byte.es>
4 * Copyright (C) 2015 Florian Henry <florian.henry@open-concept.pro>
5 * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
6 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
7 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
8 * Copyright (C) 2026 Jose Martinez <jose.martinez@pichinov.com>
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 */
23
30// Put here all includes required by your class file
31require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
32require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
33//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
34//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
35
41{
45 public $element = 'inventory';
46
50 public $table_element = 'inventory';
51
55 public $picto = 'inventory';
56
57 const STATUS_DRAFT = 0; // Draft
58 const STATUS_VALIDATED = 1; // Inventory is in process
59 const STATUS_RECORDED = 2; // Inventory is finisged. Stock movement has been recorded.
60 const STATUS_CANCELED = 9; // Canceled
61
88 // BEGIN MODULEBUILDER PROPERTIES
92 public $fields = array(
93 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'visible' => -1, 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'index' => 1, 'comment' => 'Id',),
94 'ref' => array('type' => 'varchar(64)', 'label' => 'Ref', 'visible' => 1, 'enabled' => 1, 'position' => 10, 'notnull' => 1, 'index' => 1, 'searchall' => 1, 'comment' => 'Reference of object', 'css' => 'maxwidth150'),
95 'entity' => array('type' => 'integer', 'label' => 'Entity', 'visible' => 0, 'enabled' => 1, 'position' => 20, 'notnull' => 1, 'index' => 1,),
96 'title' => array('type' => 'varchar(255)', 'label' => 'Label', 'visible' => 1, 'enabled' => 1, 'position' => 25, 'css' => 'minwidth300', 'csslist' => 'tdoverflowmax150', 'alwayseditable' => 1),
97 'fk_warehouse' => array('type' => 'integer:Entrepot:product/stock/class/entrepot.class.php', 'label' => 'Warehouse', 'visible' => 1, 'enabled' => 1, 'position' => 30, 'index' => 1, 'help' => 'InventoryForASpecificWarehouse', 'picto' => 'stock', 'css' => 'minwidth300 maxwidth500 widthcentpercentminusx', 'csslist' => 'tdoverflowmax150'),
98 'fk_product' => array('type' => 'integer:Product:product/class/product.class.php', 'label' => 'Product', 'get_name_url_params' => '0::0:-1:0::1', 'visible' => 1, 'enabled' => 1, 'position' => 32, 'index' => 1, 'help' => 'InventoryForASpecificProduct', 'picto' => 'product', 'css' => 'minwidth300 maxwidth500 widthcentpercentminusx', 'csslist' => 'tdoverflowmax150'),
99 'categories_product' => array('type' => 'chkbxlst:categorie:label:rowid::type=0:0:', 'label' => 'OrProductsWithCategories', 'visible' => 3, 'enabled' => 1, 'position' => 33, 'help' => '', 'picto' => 'category', 'css' => 'minwidth300 maxwidth500 widthcentpercentminusx'),
100 'date_inventory' => array('type' => 'date', 'label' => 'DateValue', 'visible' => 1, 'enabled' => 'getDolGlobalInt("STOCK_INVENTORY_ADD_A_VALUE_DATE")', 'position' => 35, 'csslist' => 'nowraponall'), // This date is not used so disabled by default.
101 'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 500, 'csslist' => 'nowraponall'),
102 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 501, 'csslist' => 'nowraponall'),
103 'date_validation' => array('type' => 'datetime', 'label' => 'DateValidation', 'visible' => -2, 'enabled' => 1, 'position' => 502, 'csslist' => 'nowraponall'),
104 'fk_user_creat' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 510, 'foreignkey' => 'user.rowid', 'csslist' => 'tdoverflowmax150'),
105 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 511, 'csslist' => 'tdoverflowmax150'),
106 'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserValidation', 'visible' => -2, 'enabled' => 1, 'position' => 512, 'csslist' => 'tdoverflowmax150'),
107 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'index' => 0, 'position' => 1000),
108 'status' => array('type' => 'integer', 'label' => 'Status', 'visible' => 4, 'enabled' => 1, 'position' => 1000, 'notnull' => 1, 'default' => '0', 'index' => 1, 'arrayofkeyval' => array(0 => 'Draft', 1 => 'Validated', 2 => 'Closed', 9 => 'Canceled'))
109 );
110
114 public $rowid;
115
119 public $ref;
120
124 public $fk_warehouse;
125
129 public $fk_product;
130
134 public $categories_product;
138 public $date_inventory;
142 public $title;
143
147 public $status;
148
152 public $fk_user_creat;
153
157 public $fk_user_modif;
158
162 public $fk_user_valid;
163
167 public $import_key;
168 // END MODULEBUILDER PROPERTIES
169
170
171
172 // If this object has a subtable with lines
173
177 public $table_element_line = 'inventorydet';
178
182 public $fk_element = 'fk_inventory';
183
187 public $class_element_line = 'Inventoryline';
188
192 protected $childtables = array();
196 protected $childtablesoncascade = array('inventorydet');
197
201 public $lines = array();
202
203
204
210 public function __construct(DoliDB $db)
211 {
212 $this->db = $db;
213
214 $this->ismultientitymanaged = 1;
215 $this->isextrafieldmanaged = 0;
216
217 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID')) {
218 $this->fields['rowid']['visible'] = 0;
219 }
220 if (!isModEnabled('multicompany')) {
221 $this->fields['entity']['enabled'] = 0;
222 }
223 }
224
225
233 public function create(User $user, $notrigger = 0)
234 {
235 $result = $this->createCommon($user, $notrigger);
236
237 return $result;
238 }
239
248 public function validate(User $user, $notrigger = 0, $include_sub_warehouse = 0)
249 {
250 $this->db->begin();
251
252 $result = 0;
253
254 if ($this->status == self::STATUS_DRAFT) {
255 // Delete inventory
256 $sql = 'DELETE FROM '.$this->db->prefix().'inventorydet WHERE fk_inventory = '.((int) $this->id);
257 $resql = $this->db->query($sql);
258 if (!$resql) {
259 $this->error = $this->db->lasterror();
260 $this->db->rollback();
261 return -1;
262 }
263
264 // Scan existing stock to prefill the inventory
265 $sql = "SELECT ps.rowid, ps.fk_entrepot as fk_warehouse, ps.fk_product, ps.reel,";
266 if (isModEnabled('productbatch')) {
267 $sql .= " COALESCE(pb.batch, '') as batch, pb.qty as qty,";
268 } else {
269 $sql .= " '' as batch, 0 as qty,";
270 }
271 $sql .= " p.ref, p.tobatch";
272 $sql .= " FROM ".$this->db->prefix()."product_stock as ps";
273 if (isModEnabled('productbatch')) {
274 $sql .= " LEFT JOIN ".$this->db->prefix()."product_batch as pb ON pb.fk_product_stock = ps.rowid";
275 }
276 $sql .= ", ".$this->db->prefix()."product as p, ".$this->db->prefix()."entrepot as e";
277 $sql .= " WHERE p.entity IN (".getEntity('product').")";
278 $sql .= " AND ps.fk_product = p.rowid AND ps.fk_entrepot = e.rowid";
279 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
280 $sql .= " AND p.fk_product_type = 0";
281 }
282 if ($this->fk_product > 0) {
283 $sql .= " AND ps.fk_product = ".((int) $this->fk_product);
284 }
285 if ($this->fk_warehouse > 0) {
286 $sql .= " AND (ps.fk_entrepot = ".((int) $this->fk_warehouse);
287 if (!empty($include_sub_warehouse) && getDolGlobalInt('INVENTORY_INCLUDE_SUB_WAREHOUSE')) {
288 $TChildWarehouses = array();
289 $this->getChildWarehouse($this->fk_warehouse, $TChildWarehouses);
290 if (!empty($TChildWarehouses)) {
291 $sql .= " OR ps.fk_entrepot IN (" . $this->db->sanitize(implode(',', $TChildWarehouses)) . ")";
292 }
293 }
294 $sql .= ')';
295 }
296 if (!empty($this->categories_product)) {
297 $sql .= " AND EXISTS (";
298 $sql .= " SELECT cp.fk_product";
299 $sql .= " FROM ".$this->db->prefix()."categorie_product AS cp";
300 $sql .= " WHERE cp.fk_product = ps.fk_product";
301 $sql .= " AND cp.fk_categorie IN (".$this->db->sanitize($this->categories_product).")";
302 $sql .= ")";
303 }
304 if (getDolGlobalInt('PRODUIT_SOUSPRODUITS')) {
305 $sql .= " AND NOT EXISTS (";
306 $sql .= " SELECT pa.rowid";
307 $sql .= " FROM ".$this->db->prefix()."product_association as pa";
308 $sql .= " WHERE pa.fk_product_pere = ps.fk_product";
309 $sql .= ")";
310 }
311 $sql .= " ORDER BY p.rowid";
312
313 $inventoryline = new InventoryLine($this->db);
314
315 $resql = $this->db->query($sql);
316 if ($resql) {
317 $num = $this->db->num_rows($resql);
318
319 $i = 0;
320 while ($i < $num) {
321 $obj = $this->db->fetch_object($resql);
322
323 $inventoryline->fk_inventory = $this->id;
324 $inventoryline->fk_warehouse = $obj->fk_warehouse;
325 $inventoryline->fk_product = $obj->fk_product;
326 $inventoryline->batch = $obj->batch;
327 $inventoryline->datec = dol_now();
328
329 if (isModEnabled('productbatch')) {
330 if ($obj->batch && empty($obj->tobatch)) {
331 // Bad consistency of data. The product is not a product with lot/serial but we found a stock for some lot/serial.
332 $result = -2;
333 $this->error = 'The product ID='.$obj->ref." has stock with lot/serial but is configured to not manage lot/serial. You must first fix this, this way: Set the product to have 'Management of Lot/Serial' to Yes, then set it back to 'Management of Lot/Serial to No";
334 break;
335 }
336
337 $inventoryline->qty_stock = ($obj->batch ? $obj->qty : $obj->reel); // If there is batch detail, we take qty for batch, else global qty
338 } else {
339 $inventoryline->qty_stock = $obj->reel;
340 }
341
342 $resultline = $inventoryline->create($user);
343 if ($resultline <= 0) {
344 $this->error = $inventoryline->error;
345 $this->errors = $inventoryline->errors;
346 $result = -1;
347 break;
348 }
349
350 $i++;
351 }
352 } else {
353 $result = -1;
354 $this->error = $this->db->lasterror();
355 }
356 }
357
358 if ($result >= 0) {
359 $result = $this->setStatut($this::STATUS_VALIDATED, null, '', 'INVENTORY_VALIDATED');
360 }
361
362 if ($result > 0) {
363 $this->db->commit();
364 } else {
365 $this->db->rollback();
366 }
367 return $result;
368 }
369
377 public function setDraft(User $user, $notrigger = 0)
378 {
379 $this->db->begin();
380
381 // Delete inventory
382 $sql = 'DELETE FROM '.$this->db->prefix().'inventorydet WHERE fk_inventory = '.((int) $this->id);
383 $resql = $this->db->query($sql);
384 if (!$resql) {
385 $this->error = $this->db->lasterror();
386 $this->db->rollback();
387 return -1;
388 }
389
390 $result = $this->setStatut($this::STATUS_DRAFT, null, '', 'INVENTORY_DRAFT');
391
392 if ($result > 0) {
393 $this->db->commit();
394 } else {
395 $this->db->rollback();
396 }
397 return $result;
398 }
399
407 public function setRecorded(User $user, $notrigger = 0)
408 {
409 $this->db->begin();
410
411 $result = $this->setStatut($this::STATUS_RECORDED, null, '', 'INVENTORY_RECORDED');
412
413 if ($result > 0) {
414 $this->db->commit();
415 } else {
416 $this->db->rollback();
417 return -1;
418 }
419 return $result;
420 }
421
429 public function setCanceled(User $user, $notrigger = 0)
430 {
431 $this->db->begin();
432
433 $result = $this->setStatut($this::STATUS_CANCELED, null, '', 'INVENTORY_CANCELED');
434
435 if ($result > 0) {
436 $this->db->commit();
437 } else {
438 $this->db->rollback();
439 return -1;
440 }
441 return $result;
442 }
443
451 public function createFromClone(User $user, $fromid)
452 {
453 global $langs;
454
455 $error = 0;
456
457 dol_syslog(__METHOD__, LOG_DEBUG);
458
459 $object = new self($this->db);
460
461 $this->db->begin();
462
463 // Load source object
464 $object->fetchCommon($fromid);
465 // Reset some properties
466 unset($object->id);
467 unset($object->fk_user_creat);
468 unset($object->import_key);
469
470 // Clear fields
471 $object->ref = "copy_of_".$object->ref;
472 $object->title = $langs->trans("CopyOf")." ".$object->title;
473 // ...
474
475 // Create clone
476 $object->context['createfromclone'] = 'createfromclone';
477 $result = $object->createCommon($user);
478 if ($result < 0) {
479 $error++;
481 }
482
483 unset($object->context['createfromclone']);
484
485 // End
486 if (!$error) {
487 $this->db->commit();
488 return $object;
489 } else {
490 $this->db->rollback();
491 return -1;
492 }
493 }
494
502 public function fetch($id, $ref = null)
503 {
504 $result = $this->fetchCommon($id, $ref);
505 //if ($result > 0 && !empty($this->table_element_line)) $this->fetchLines();
506 return $result;
507 }
508
514 /*public function fetchLines()
515 {
516 $this->lines=array();
517
518 // Load lines with object MyObjectLine
519
520 return count($this->lines)?1:0;
521 }*/
522
530 public function update(User $user, $notrigger = 0)
531 {
532 return $this->updateCommon($user, $notrigger);
533 }
534
542 public function delete(User $user, $notrigger = 0)
543 {
544 return $this->deleteCommon($user, $notrigger);
545 }
546
555 public function deleteLine(User $user, $idline, $notrigger = 0)
556 {
557 if ($this->status < 0) {
558 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
559 return -2;
560 }
561
562 return $this->deleteLineCommon($user, $idline, $notrigger);
563 }
564
575 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
576 {
577 global $conf, $langs;
578
579 if (!empty($conf->dol_no_mouse_hover)) {
580 $notooltip = 1; // Force disable tooltips
581 }
582
583 $result = '';
584
585 $label = '<u>'.$langs->trans("Inventory").'</u>';
586 $label .= '<br>';
587 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
588
589 $url = dol_buildpath('/product/inventory/card.php', 1).'?id='.$this->id;
590
591 $linkclose = '';
592 if (empty($notooltip)) {
593 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
594 $label = $langs->trans("ShowInventory");
595 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
596 }
597 $linkclose .= ' title="'.dolPrintHTMLForAttribute($label).'"';
598 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
599 } else {
600 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
601 }
602
603 $linkstart = '<a href="'.$url.'"';
604 $linkstart .= $linkclose.'>';
605 $linkend = '</a>';
606
607 $result .= $linkstart;
608 if ($withpicto) {
609 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
610 }
611 if ($withpicto != 2) {
612 $result .= $this->ref;
613 }
614 $result .= $linkend;
615 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
616
617 return $result;
618 }
619
626 public function getLibStatut($mode = 0)
627 {
628 return $this->LibStatut($this->status, $mode);
629 }
630
631 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
639 public function LibStatut($status, $mode = 0)
640 {
641 // phpcs:enable
642 global $langs, $hookmanager;
643
644 $labelStatus = array();
645 $labelStatusShort = array();
646 $labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
647 $labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated').' ('.$langs->transnoentitiesnoconv('InventoryStartedShort').')';
648 $labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
649 $labelStatus[self::STATUS_RECORDED] = $langs->transnoentitiesnoconv('Closed');
650 $labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
651 $labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('InventoryStartedShort');
652 $labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
653 $labelStatusShort[self::STATUS_RECORDED] = $langs->transnoentitiesnoconv('Closed');
654
655 $statusType = 'status'.$status;
656 if ($status == self::STATUS_RECORDED) {
657 $statusType = 'status6';
658 }
659
660 $parameters = array('status' => $status, 'mode' => $mode);
661 $reshook = $hookmanager->executeHooks('LibStatut', $parameters, $this); // Note that $action and $object may have been modified by hook
662 if ($reshook > 0) {
663 return $hookmanager->resPrint;
664 }
665 return dolGetStatus($labelStatus[$status], $labelStatusShort[$status], '', $statusType, $mode);
666 }
667
675 public function getKanbanView($option = '', $arraydata = null)
676 {
677 global $conf, $langs;
678
679 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
680
681 $return = '<div class="box-flex-item box-flex-grow-zero">';
682 $return .= '<div class="info-box info-box-sm">';
683 $return .= '<span class="info-box-icon bg-infobox-action">';
684 $return .= img_picto('', $this->picto);
685 $return .= '</span>';
686 $return .= '<div class="info-box-content">';
687 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
688 if ($selected >= 0) {
689 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
690 }
691 if (property_exists($this, 'label')) {
692 $return .= ' <div class="inline-block opacitymedium valignmiddle tdoverflowmax100">'.$this->label.'</div>';
693 }
694 if (property_exists($this, 'amount')) {
695 $return .= '<br>';
696 $return .= '<span class="info-box-label amount">'.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency).'</span>';
697 }
698 if (method_exists($this, 'getLibStatut')) {
699 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
700 }
701 $return .= '</div>';
702 $return .= '</div>';
703 $return .= '</div>';
704
705 return $return;
706 }
707
714 public function info($id)
715 {
716 $sql = "SELECT rowid, date_creation as datec, tms as datem, date_validation as datev,";
717 $sql .= " fk_user_creat, fk_user_modif, fk_user_valid";
718 $sql .= " FROM ".$this->db->prefix().$this->table_element." as t";
719 $sql .= " WHERE t.rowid = ".((int) $id);
720 $result = $this->db->query($sql);
721 if ($result) {
722 if ($this->db->num_rows($result)) {
723 $obj = $this->db->fetch_object($result);
724
725 $this->id = $obj->rowid;
726
727 $this->user_creation_id = $obj->fk_user_creat;
728 $this->user_modification_id = $obj->fk_user_modif;
729 $this->user_validation_id = $obj->fk_user_valid;
730
731 $this->date_creation = $this->db->jdate($obj->datec);
732 $this->date_modification = $this->db->jdate($obj->datem);
733 $this->date_validation = $this->db->jdate($obj->datev);
734 }
735
736 $this->db->free($result);
737 } else {
738 dol_print_error($this->db);
739 }
740 }
741
748 public function initAsSpecimen()
749 {
750 $ret = $this->initAsSpecimenCommon();
751 $this->title = '';
752
753 return $ret;
754 }
755
763 public function getChildWarehouse($id, &$TChildWarehouse)
764 {
765 $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'entrepot';
766 $sql .= ' WHERE fk_parent='.(int) $id;
767 $sql .= ' ORDER BY rowid';
768 $resql = $this->db->query($sql);
769 if ($resql && $this->db->num_rows($resql) > 0) {
770 while ($obj = $this->db->fetch_object($resql)) {
771 $TChildWarehouse[] = $obj->rowid;
772 $this->getChildWarehouse($obj->rowid, $TChildWarehouse);
773 }
774 return 1;
775 } else {
776 return -1;
777 }
778 }
779
780
787 public function getNextNumRef()
788 {
789 global $langs, $conf;
790 $langs->load("stocks");
791
792 if (!getDolGlobalString('INVENTORY_ADDON')) {
793 return ''; // Free reference, typed by the user (historical behaviour)
794 }
795
796 $mybool = false;
797
798 $file = getDolGlobalString('INVENTORY_ADDON').".php";
799 $classname = getDolGlobalString('INVENTORY_ADDON');
800
801 // Include file with class
802 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
803 foreach ($dirmodels as $reldir) {
804 $dir = dol_buildpath($reldir."core/modules/inventory/");
805
806 // Load file with numbering class (if found)
807 $mybool = ((bool) @include_once $dir.$file) || $mybool;
808 }
809
810 if (!$mybool) {
811 dol_print_error(null, "Failed to include file ".$file);
812 return '';
813 }
814
815 if (class_exists($classname)) {
816 $obj = new $classname();
817 '@phan-var-force ModeleNumRefInventory $obj';
818 $numref = $obj->getNextValue($this);
819
820 if ($numref != '' && $numref != '-1') {
821 return $numref;
822 } else {
823 $this->error = $obj->error;
824 return '';
825 }
826 }
827
828 return '';
829 }
830
842 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
843 {
844 global $langs;
845
846 $langs->load("stocks");
847
848 if (!dol_strlen($modele)) {
849 $modele = ''; // Remove this once a pdf_standard.php exists.
850
851 if ($this->model_pdf) {
852 $modele = $this->model_pdf;
853 } elseif (getDolGlobalString('INVENTORY_ADDON_PDF')) {
854 $modele = getDolGlobalString('INVENTORY_ADDON_PDF');
855 }
856 }
857
858 $modelpath = "core/modules/inventory/doc/";
859
860 if (empty($modele)) {
861 return 1; // Remove this once a pdf_standard.php exists.
862 }
863
864 return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
865 }
866}
867
872{
876 public $element = 'inventoryline';
877
881 public $table_element = 'inventorydet';
882
886 public $parent_element = 'inventory';
887
891 public $fk_parent_attribute = 'fk_inventory';
892
896 public $picto = 'stock';
897
915 // BEGIN MODULEBUILDER PROPERTIES
919 public $fields = array(
920 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'visible' => -1, 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'index' => 1, 'comment' => 'Id',),
921 'fk_inventory' => array('type' => 'integer:Inventory:product/inventory/class/inventory.class.php', 'label' => 'Inventory', 'visible' => 1, 'enabled' => 1, 'position' => 30, 'index' => 1, 'help' => 'LinkToInventory'),
922 'fk_warehouse' => array('type' => 'integer:Entrepot:product/stock/class/entrepot.class.php', 'label' => 'Warehouse', 'visible' => 1, 'enabled' => 1, 'position' => 30, 'index' => 1, 'help' => 'LinkToThirdparty'),
923 'fk_product' => array('type' => 'integer:Product:product/class/product.class.php', 'label' => 'Product', 'visible' => 1, 'enabled' => 1, 'position' => 32, 'index' => 1, 'help' => 'LinkToProduct'),
924 'batch' => array('type' => 'string', 'label' => 'Batch', 'visible' => 1, 'enabled' => 1, 'position' => 32, 'index' => 1, 'help' => 'LinkToProduct'),
925 'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 500),
926 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 501),
927 'qty_stock' => array('type' => 'double', 'label' => 'QtyFound', 'visible' => 1, 'enabled' => 1, 'position' => 32, 'index' => 1, 'help' => 'Qty we found/want (to define during draft edition)'),
928 'qty_view' => array('type' => 'double', 'label' => 'QtyBefore', 'visible' => 1, 'enabled' => 1, 'position' => 33, 'index' => 1, 'help' => 'Qty before (filled once movements are validated)'),
929 'qty_regulated' => array('type' => 'double', 'label' => 'QtyDelta', 'visible' => 1, 'enabled' => 1, 'position' => 34, 'index' => 1, 'help' => 'Qty added or removed (filled once movements are validated)'),
930 'pmp_real' => array('type' => 'double', 'label' => 'PMPReal', 'visible' => 1, 'enabled' => 1, 'position' => 35),
931 'pmp_expected' => array('type' => 'double', 'label' => 'PMPExpected', 'visible' => 1, 'enabled' => 1, 'position' => 36),
932 );
933
937 public $rowid;
938
942 public $fk_inventory;
946 public $fk_warehouse;
950 public $fk_product;
954 public $batch;
958 public $datec;
959
963 public $qty_stock;
964
968 public $qty_view;
969
973 public $qty_regulated;
974
978 public $pmp_real;
982 public $pmp_expected;
983
989 public function __construct($db)
990 {
991 $this->db = $db;
992 $this->ismultientitymanaged = 0;
993
994 $this->isextrafieldmanaged = 0;
995 }
1003 public function create(User $user, $notrigger = 0)
1004 {
1005 return $this->createCommon($user, $notrigger);
1006 }
1007
1015 public function fetch($id, $ref = null)
1016 {
1017 $result = $this->fetchCommon($id, $ref);
1018 //if ($result > 0 && !empty($this->table_element_line)) $this->fetchLines();
1019 return $result;
1020 }
1021
1029 public function update(User $user, $notrigger = 0)
1030 {
1031 return $this->updateCommon($user, $notrigger);
1032 }
1033
1041 public function delete(User $user, $notrigger = 0)
1042 {
1043 return $this->deleteCommon($user, $notrigger);
1044 //return $this->deleteCommon($user, $notrigger, 1);
1045 }
1046}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
deleteLineCommon(User $user, $idline, $notrigger=0)
Delete a line of object in database.
setStatut($status, $elementId=null, $elementType='', $trigkey='', $fieldstatus='')
Set status of an object.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
setErrorsFromObject($object)
setErrorsFromObject
createCommon(User $user, $notrigger=0)
Create object in the database.
updateCommon(User $user, $notrigger=0)
Update object into database.
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
fetchCommon($id, $ref=null, $morewhere='', $noextrafields=0)
Load object in memory from the database.
deleteCommon(User $user, $notrigger=0, $forcechilddeletion=0)
Delete object in database.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Dolibarr database access.
Class for Inventory.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionally the picto)
create(User $user, $notrigger=0)
Create object into database.
setRecorded(User $user, $notrigger=0)
Set to inventory to status "Closed".
LibStatut($status, $mode=0)
Return the status.
getKanbanView($option='', $arraydata=null)
Return a thumb for kanban views.
__construct(DoliDB $db)
Constructor.
getLibStatut($mode=0)
Return the label of the status.
info($id)
Charge les information d'ordre info dans l'objet commande.
setDraft(User $user, $notrigger=0)
Go back to draft.
update(User $user, $notrigger=0)
Load object lines in memory from the database.
setCanceled(User $user, $notrigger=0)
Set to Canceled.
validate(User $user, $notrigger=0, $include_sub_warehouse=0)
Validate inventory (start it)
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
deleteLine(User $user, $idline, $notrigger=0)
Delete a line of object in database.
fetch($id, $ref=null)
Load object in memory from the database.
getChildWarehouse($id, &$TChildWarehouse)
Return the child warehouse of the current one.
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
createFromClone(User $user, $fromid)
Clone and object into another one.
Class InventoryLine.
update(User $user, $notrigger=0)
Update object into database.
__construct($db)
Constructor.
create(User $user, $notrigger=0)
Create object in database.
fetch($id, $ref=null)
Load object in memory from the database.
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:169
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_now($mode='gmt')
Return date for now.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
print $langs trans('Date')." left Ref Label right Qty right Price right TotalHT right TotalTTC right right right right right right right right right centpercent right TotalHT right n right VAT right n right TotalVAT right n No sujeto a RE IRPF right TotalLT1 right n right TotalLT2 right n right TotalTTC right n takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency right TotalTTC takeposcustomercurrency right takeposcustomercurrency n right Paid right PaymentTypeShortLIQ right SELECT p pos_change as p datep as p p num_paiement as f pf amount as amount
Definition receipt.php:489