28require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
29require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobjectline.class.php';
42 public $element =
'inventory';
47 public $table_element =
'inventory';
52 public $ismultientitymanaged = 1;
57 public $isextrafieldmanaged = 0;
62 public $picto =
'inventory';
64 const STATUS_DRAFT = 0;
65 const STATUS_VALIDATED = 1;
66 const STATUS_RECORDED = 2;
67 const STATUS_CANCELED = 9;
99 public $fields = array(
100 'rowid' => array(
'type'=>
'integer',
'label'=>
'TechnicalID',
'visible'=>-1,
'enabled'=>1,
'position'=>1,
'notnull'=>1,
'index'=>1,
'comment'=>
'Id',),
101 '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'),
102 'entity' => array(
'type'=>
'integer',
'label'=>
'Entity',
'visible'=>0,
'enabled'=>1,
'position'=>20,
'notnull'=>1,
'index'=>1,),
103 'title' => array(
'type'=>
'varchar(255)',
'label'=>
'Label',
'visible'=>1,
'enabled'=>1,
'position'=>25,
'css'=>
'minwidth300',
'csslist'=>
'tdoverflowmax150',
'alwayseditable'=>1),
104 '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'),
105 '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'),
106 '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'),
107 'date_inventory' => array(
'type'=>
'date',
'label'=>
'DateValue',
'visible'=>1,
'enabled'=>
'$conf->global->STOCK_INVENTORY_ADD_A_VALUE_DATE',
'position'=>35,
'csslist'=>
'nowraponall'),
108 'date_creation' => array(
'type'=>
'datetime',
'label'=>
'DateCreation',
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>500,
'csslist'=>
'nowraponall'),
109 'tms' => array(
'type'=>
'timestamp',
'label'=>
'DateModification',
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>501,
'csslist'=>
'nowraponall'),
110 'date_validation' => array(
'type'=>
'datetime',
'label'=>
'DateValidation',
'visible'=>-2,
'enabled'=>1,
'position'=>502,
'csslist'=>
'nowraponall'),
111 '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'),
112 'fk_user_modif' => array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserModif',
'enabled'=>1,
'visible'=>-2,
'notnull'=>-1,
'position'=>511,
'csslist'=>
'tdoverflowmax150'),
113 'fk_user_valid' => array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserValidation',
'visible'=>-2,
'enabled'=>1,
'position'=>512,
'csslist'=>
'tdoverflowmax150'),
114 'import_key' => array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>-2,
'notnull'=>-1,
'index'=>0,
'position'=>1000),
115 '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'))
136 public $fk_warehouse;
146 public $categories_product;
147 public $date_inventory;
158 public $date_creation;
163 public $date_validation;
169 public $fk_user_creat;
174 public $fk_user_modif;
179 public $fk_user_valid;
194 public $table_element_line =
'inventorydet';
199 public $fk_element =
'fk_inventory';
204 public $class_element_line =
'Inventoryline';
209 protected $childtables = array();
213 protected $childtablesoncascade = array(
'inventorydet');
218 public $lines = array();
234 $this->fields[
'rowid'][
'visible'] = 0;
236 if (!isModEnabled(
'multicompany')) {
237 $this->fields[
'entity'][
'enabled'] = 0;
264 public function validate(
User $user, $notrigger =
false, $include_sub_warehouse = 0)
271 if ($this->
status == self::STATUS_DRAFT) {
273 $sql =
'DELETE FROM '.$this->db->prefix().
'inventorydet WHERE fk_inventory = '.((int) $this->
id);
274 $resql = $this->db->query($sql);
276 $this->error = $this->db->lasterror();
277 $this->db->rollback();
282 $sql =
"SELECT ps.rowid, ps.fk_entrepot as fk_warehouse, ps.fk_product, ps.reel,";
283 $sql .=
" pb.batch, pb.qty";
284 $sql .=
" FROM ".$this->db->prefix().
"product_stock as ps";
285 $sql .=
" LEFT JOIN ".$this->db->prefix().
"product_batch as pb ON pb.fk_product_stock = ps.rowid,";
286 $sql .=
" ".$this->db->prefix().
"product as p, ".$this->db->prefix().
"entrepot as e";
287 $sql .=
" WHERE p.entity IN (".getEntity(
'product').
")";
288 $sql .=
" AND ps.fk_product = p.rowid AND ps.fk_entrepot = e.rowid";
290 $sql .=
" AND p.fk_product_type = 0";
292 if ($this->fk_product > 0) {
293 $sql .=
" AND ps.fk_product = ".((int) $this->fk_product);
295 if ($this->fk_warehouse > 0) {
296 $sql .=
" AND (ps.fk_entrepot = ".((int) $this->fk_warehouse);
297 if (!empty($include_sub_warehouse) &&
getDolGlobalInt(
'INVENTORY_INCLUDE_SUB_WAREHOUSE')) {
298 $TChildWarehouses = array();
300 $sql .=
" OR ps.fk_entrepot IN (".$this->db->sanitize(join(
',', $TChildWarehouses)).
")";
304 if (!empty($this->categories_product)) {
305 $sql .=
" AND EXISTS (";
306 $sql .=
" SELECT cp.fk_product";
307 $sql .=
" FROM ".$this->db->prefix().
"categorie_product AS cp";
308 $sql .=
" WHERE cp.fk_product = ps.fk_product";
309 $sql .=
" AND cp.fk_categorie IN (".$this->db->sanitize($this->categories_product).
")";
313 $sql .=
" AND NOT EXISTS (";
314 $sql .=
" SELECT pa.rowid";
315 $sql .=
" FROM ".$this->db->prefix().
"product_association as pa";
316 $sql .=
" WHERE pa.fk_product_pere = ps.fk_product";
322 $resql = $this->db->query($sql);
324 $num = $this->db->num_rows($resql);
328 $obj = $this->db->fetch_object($resql);
330 $inventoryline->fk_inventory = $this->id;
331 $inventoryline->fk_warehouse = $obj->fk_warehouse;
332 $inventoryline->fk_product = $obj->fk_product;
333 $inventoryline->batch = $obj->batch;
334 $inventoryline->datec =
dol_now();
336 if (isModEnabled(
'productbatch')) {
337 $inventoryline->qty_stock = ($obj->batch ? $obj->qty : $obj->reel);
339 $inventoryline->qty_stock = $obj->reel;
342 $resultline = $inventoryline->create($user);
343 if ($resultline <= 0) {
344 $this->error = $inventoryline->error;
345 $this->errors = $inventoryline->errors;
354 $this->error = $this->db->lasterror();
359 $result = $this->
setStatut($this::STATUS_VALIDATED,
null,
'',
'INVENTORY_VALIDATED');
365 $this->db->rollback();
382 $sql =
'DELETE FROM '.$this->db->prefix().
'inventorydet WHERE fk_inventory = '.((int) $this->
id);
383 $resql = $this->db->query($sql);
385 $this->error = $this->db->lasterror();
386 $this->db->rollback();
390 $result = $this->
setStatut($this::STATUS_DRAFT,
null,
'',
'INVENTORY_DRAFT');
395 $this->db->rollback();
411 $result = $this->
setStatut($this::STATUS_RECORDED,
null,
'',
'INVENTORY_RECORDED');
416 $this->db->rollback();
433 $result = $this->
setStatut($this::STATUS_CANCELED,
null,
'',
'INVENTORY_CANCELED');
438 $this->db->rollback();
453 global $hookmanager, $langs;
458 $object =
new self($this->db);
463 $object->fetchCommon($fromid);
466 unset($object->fk_user_creat);
467 unset($object->import_key);
470 $object->ref =
"copy_of_".$object->ref;
471 $object->title = $langs->trans(
"CopyOf").
" ".$object->title;
475 $object->context[
'createfromclone'] =
'createfromclone';
476 $result = $object->createCommon($user);
479 $this->error = $object->error;
480 $this->errors = $object->errors;
483 unset($object->context[
'createfromclone']);
490 $this->db->rollback();
502 public function fetch($id, $ref =
null)
542 public function delete(
User $user, $notrigger =
false)
558 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
575 public function getNomUrl($withpicto = 0, $option =
'', $notooltip = 0, $morecss =
'', $save_lastsearch_value = -1)
577 global $db, $conf, $langs;
578 global $dolibarr_main_authentication, $dolibarr_main_demo;
581 if (!empty($conf->dol_no_mouse_hover)) {
588 $label =
'<u>'.$langs->trans(
"Inventory").
'</u>';
590 $label .=
'<b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
592 $url =
dol_buildpath(
'/product/inventory/card.php', 1).
'?id='.$this->id;
595 if (empty($notooltip)) {
597 $label = $langs->trans(
"ShowInventory");
598 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
600 $linkclose .=
' title="'.dol_escape_htmltag($label, 1).
'"';
601 $linkclose .=
' class="classfortooltip'.($morecss ?
' '.$morecss :
'').
'"';
603 $linkclose = ($morecss ?
' class="'.$morecss.
'"' :
'');
606 $linkstart =
'<a href="'.$url.
'"';
607 $linkstart .= $linkclose.
'>';
610 $result .= $linkstart;
612 $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);
614 if ($withpicto != 2) {
615 $result .= $this->ref;
647 $labelStatus = array();
648 $labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv(
'Draft');
649 $labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv(
'Validated').
' ('.$langs->transnoentitiesnoconv(
'InventoryStartedShort').
')';
650 $labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv(
'Canceled');
651 $labelStatus[self::STATUS_RECORDED] = $langs->transnoentitiesnoconv(
'Closed');
652 $labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv(
'Draft');
653 $labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv(
'InventoryStartedShort');
654 $labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv(
'Canceled');
655 $labelStatusShort[self::STATUS_RECORDED] = $langs->transnoentitiesnoconv(
'Closed');
657 $statusType =
'status'.$status;
658 if ($status == self::STATUS_RECORDED) {
659 $statusType =
'status6';
662 return dolGetStatus($labelStatus[$status], $labelStatusShort[$status],
'', $statusType, $mode);
674 global $conf, $langs;
676 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
678 $return =
'<div class="box-flex-item box-flex-grow-zero">';
679 $return .=
'<div class="info-box info-box-sm">';
680 $return .=
'<span class="info-box-icon bg-infobox-action">';
682 $return .=
'</span>';
683 $return .=
'<div class="info-box-content">';
684 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl() : $this->ref).
'</span>';
685 if ($selected >= 0) {
686 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
688 if (property_exists($this,
'label')) {
689 $return .=
' <div class="inline-block opacitymedium valignmiddle tdoverflowmax100">'.$this->label.
'</div>';
691 if (property_exists($this,
'amount')) {
693 $return .=
'<span class="info-box-label amount">'.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency).
'</span>';
695 if (method_exists($this,
'getLibStatut')) {
696 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
713 $sql =
"SELECT rowid, date_creation as datec, tms as datem, date_validation as datev,";
714 $sql .=
" fk_user_creat, fk_user_modif, fk_user_valid";
715 $sql .=
" FROM ".$this->db->prefix().$this->table_element.
" as t";
716 $sql .=
" WHERE t.rowid = ".((int) $id);
717 $result = $this->db->query($sql);
719 if ($this->db->num_rows($result)) {
720 $obj = $this->db->fetch_object($result);
722 $this->
id = $obj->rowid;
724 $this->user_creation_id = $obj->fk_user_creat;
725 $this->user_modification_id = $obj->fk_user_modif;
726 $this->user_validation_id = $obj->fk_user_valid;
728 $this->date_creation = $this->db->jdate($obj->datec);
729 $this->date_modification = $this->db->jdate($obj->datem);
730 $this->date_validation = $this->db->jdate($obj->datev);
733 $this->db->free($result);
760 $sql =
'SELECT rowid FROM '.MAIN_DB_PREFIX.
'entrepot';
761 $sql.=
' WHERE fk_parent='.(int) $id;
762 $sql.=
' ORDER BY rowid';
763 $resql = $this->db->query($sql);
764 if ($resql && $this->db->num_rows($resql)>0) {
765 while ($obj = $this->db->fetch_object($resql)) {
766 $TChildWarehouse[] = $obj->rowid;
784 public $element =
'inventoryline';
789 public $table_element =
'inventorydet';
794 public $ismultientitymanaged = 0;
799 public $isextrafieldmanaged = 0;
804 public $picto =
'stock';
827 public $fields = array(
828 'rowid' => array(
'type'=>
'integer',
'label'=>
'TechnicalID',
'visible'=>-1,
'enabled'=>1,
'position'=>1,
'notnull'=>1,
'index'=>1,
'comment'=>
'Id',),
829 'fk_inventory' => array(
'type'=>
'integer:Inventory:product/inventory/class/inventory.class.php',
'label'=>
'Inventory',
'visible'=>1,
'enabled'=>1,
'position'=>30,
'index'=>1,
'help'=>
'LinkToInventory'),
830 'fk_warehouse' => array(
'type'=>
'integer:Entrepot:product/stock/class/entrepot.class.php',
'label'=>
'Warehouse',
'visible'=>1,
'enabled'=>1,
'position'=>30,
'index'=>1,
'help'=>
'LinkToThirdparty'),
831 'fk_product' => array(
'type'=>
'integer:Product:product/class/product.class.php',
'label'=>
'Product',
'visible'=>1,
'enabled'=>1,
'position'=>32,
'index'=>1,
'help'=>
'LinkToProduct'),
832 'batch' => array(
'type'=>
'string',
'label'=>
'Batch',
'visible'=>1,
'enabled'=>1,
'position'=>32,
'index'=>1,
'help'=>
'LinkToProduct'),
833 'datec' => array(
'type'=>
'datetime',
'label'=>
'DateCreation',
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>500),
834 'tms' => array(
'type'=>
'timestamp',
'label'=>
'DateModification',
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>501),
835 '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)'),
836 'qty_view' => array(
'type'=>
'double',
'label'=>
'QtyBefore',
'visible'=>1,
'enabled'=>1,
'position'=>33,
'index'=>1,
'help'=>
'Qty before (filled once movements are validated)'),
837 'qty_regulated' => array(
'type'=>
'double',
'label'=>
'QtyDelta',
'visible'=>1,
'enabled'=>1,
'position'=>34,
'index'=>1,
'help'=>
'Qty aadded or removed (filled once movements are validated)'),
838 'pmp_real' => array(
'type'=>
'double',
'label'=>
'PMPReal',
'visible'=>1,
'enabled'=>1,
'position'=>35),
839 'pmp_expected' => array(
'type'=>
'double',
'label'=>
'PMPExpected',
'visible'=>1,
'enabled'=>1,
'position'=>36),
847 public $fk_inventory;
848 public $fk_warehouse;
855 public $qty_regulated;
857 public $pmp_expected;
879 public function fetch($id, $ref =
null)
905 public function delete(
User $user, $notrigger =
false)
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Parent class of all other business classes (invoices, contracts, proposals, orders,...
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
createCommon(User $user, $notrigger=false)
Create object into database.
deleteCommon(User $user, $notrigger=false, $forcechilddeletion=0)
Delete object in database.
setStatut($status, $elementId=null, $elementType='', $trigkey='', $fieldstatus='fk_statut')
Set status of an object.
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
updateCommon(User $user, $notrigger=false)
Update object into database.
fetchCommon($id, $ref=null, $morewhere='', $noextrafields=0)
Load object in memory from the database.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Dolibarr database access.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
create(User $user, $notrigger=false)
Create object into database.
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 informations d'ordre info dans l'objet commande.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
fetch($id, $ref=null)
Load object in memory from the database.
validate(User $user, $notrigger=false, $include_sub_warehouse=0)
Validate inventory (start it)
getChildWarehouse($id, &$TChildWarehouse)
Return the child warehouse of the current one.
setDraft(User $user, $notrigger=false)
Go back to draft.
static LibStatut($status, $mode=0)
Return the status.
setRecorded(User $user, $notrigger=false)
Set to inventory to status "Closed".
update(User $user, $notrigger=false)
Load object lines in memory from the database.
createFromClone(User $user, $fromid)
Clone and object into another one.
setCanceled(User $user, $notrigger=false)
Set to Canceled.
update(User $user, $notrigger=false)
Update object into database.
fetch($id, $ref=null)
Load object in memory from the database.
create(User $user, $notrigger=false)
Create object in database.
Class to manage Dolibarr users.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.