27require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobjectline.class.php';
39 public $element =
'stocktransferline';
44 public $table_element =
'stocktransfer_stocktransferline';
50 public $ismultientitymanaged = 0;
55 public $isextrafieldmanaged = 1;
60 public $picto =
'stocktransferline@stocktransfer';
63 const STATUS_DRAFT = 0;
64 const STATUS_VALIDATED = 1;
65 const STATUS_CANCELED = 9;
98 'rowid' => array(
'type'=>
'integer',
'label'=>
'TechnicalID',
'enabled'=>
'1',
'position'=>1,
'notnull'=>1,
'visible'=>0,
'noteditable'=>
'1',
'index'=>1,
'comment'=>
"Id"),
99 'amount' => array(
'type'=>
'price',
'label'=>
'Amount',
'enabled'=>
'1',
'position'=>40,
'notnull'=>0,
'visible'=>1,
'default'=>
'null',
'isameasure'=>
'1',
'help'=>
"Help text for amount",),
100 'qty' => array(
'type'=>
'real',
'label'=>
'Qty',
'enabled'=>
'1',
'position'=>45,
'notnull'=>0,
'visible'=>1,
'default'=>
'0',
'isameasure'=>
'1',
'css'=>
'maxwidth75imp',
'help'=>
"Help text for quantity",),
101 'fk_warehouse_destination' => array(
'type'=>
'integer:Entrepot:product/stock/class/entrepot.class.php',
'label'=>
'Entrepôt de destination',
'enabled'=>
'1',
'position'=>50,
'notnull'=>1,
'visible'=>1,),
102 'fk_warehouse_source' => array(
'type'=>
'integer:Entrepot:product/stock/class/entrepot.class.php',
'label'=>
'Entrepôt source',
'enabled'=>
'1',
'position'=>50,
'notnull'=>1,
'visible'=>1,),
103 'fk_stocktransfer' => array(
'type'=>
'integer:StockTransfer:stocktransfer/stock/class/stocktransfer.class.php',
'label'=>
'StockTransfer',
'enabled'=>
'1',
'position'=>50,
'notnull'=>1,
'visible'=>0,),
104 'fk_product' => array(
'type'=>
'integer:Product:product/class/product.class.php',
'label'=>
'Product',
'enabled'=>
'1',
'position'=>50,
'notnull'=>1,
'visible'=>1,),
105 'batch' => array(
'type'=>
'varchar(128)',
'label'=>
'Batch',
'enabled'=>
'1',
'position'=>1000,
'notnull'=>-1,
'visible'=>1,),
106 'pmp' => array(
'type'=>
'double',
'label'=>
'PMP',
'enabled'=>
'1',
'position'=>50,
'notnull'=>0,
'visible'=>1,),
107 'rang' => array(
'type'=>
'integer',
'label'=>
'Qty',
'enabled'=>
'1',
'position'=>45,
'notnull'=>0,
'visible'=>0,
'default'=>
'0',
'isameasure'=>
'1',
'css'=>
'maxwidth75imp',
'help'=>
"Help text for quantity",),
112 public $fk_warehouse_destination;
113 public $fk_warehouse_source;
114 public $fk_stocktransfer;
133 global $conf, $langs;
138 $this->fields[
'rowid'][
'visible'] = 0;
140 if (!isModEnabled(
'multicompany') && isset($this->fields[
'entity'])) {
141 $this->fields[
'entity'][
'enabled'] = 0;
151 foreach ($this->fields as $key => $val) {
152 if (isset($val[
'enabled']) && empty($val[
'enabled'])) {
153 unset($this->fields[$key]);
158 if (is_object($langs)) {
159 foreach ($this->fields as $key => $val) {
160 if (isset($val[
'arrayofkeyval']) && is_array($val[
'arrayofkeyval'])) {
161 foreach ($val[
'arrayofkeyval'] as $key2 => $val2) {
162 $this->fields[$key][
'arrayofkeyval'][$key2] = $langs->trans($val2);
190 global $langs, $extrafields;
195 $object =
new self($this->db);
200 $result = $object->fetchCommon($fromid);
201 if ($result > 0 && !empty($object->table_element_line)) {
202 $object->fetchLines();
211 unset($object->import_key);
215 $object->ref = empty($this->fields[
'ref'][
'default']) ?
"copy_of_".$object->ref : $this->fields[
'ref'][
'default'];
216 $object->label = empty($this->fields[
'label'][
'default']) ? $langs->trans(
"CopyOf").
" ".$object->label : $this->fields[
'label'][
'default'];
217 $object->status = self::STATUS_DRAFT;
220 if (is_array($object->array_options) && count($object->array_options) > 0) {
221 $extrafields->fetch_name_optionals_label($this->table_element);
222 foreach ($object->array_options as $key => $option) {
223 $shortkey = preg_replace(
'/options_/',
'', $key);
224 if (!empty($extrafields->attributes[$this->table_element][
'unique'][$shortkey])) {
226 unset($object->array_options[$key]);
232 $object->context[
'createfromclone'] =
'createfromclone';
233 $result = $object->createCommon($user);
236 $this->error = $object->error;
237 $this->errors = $object->errors;
249 if (property_exists($this,
'socid') && $this->socid == $object->socid) {
256 unset($object->context[
'createfromclone']);
263 $this->db->rollback();
275 public function fetch($id, $ref =
null)
278 if ($result > 0 && !empty($this->table_element_line)) {
291 $this->lines = array();
309 public function fetchAll($sortorder =
'', $sortfield =
'', $limit = 0, $offset = 0, array $filter = array(), $filtermode =
'AND')
317 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element.
' as t';
318 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
319 $sql .=
' WHERE t.entity IN ('.getEntity($this->element).
')';
321 $sql .=
' WHERE 1 = 1';
325 if (count($filter) > 0) {
326 foreach ($filter as $key => $value) {
327 if ($key ==
't.rowid') {
328 $sqlwhere[] = $key.
'='.$value;
329 } elseif (strpos($key,
'date') !==
false) {
330 $sqlwhere[] = $key.
' = \''.$this->db->idate($value).
'\'';
331 } elseif ($key ==
'customsql') {
332 $sqlwhere[] = $value;
334 $sqlwhere[] = $key.
' LIKE \'%'.$this->db->escape($value).
'%\'';
338 if (count($sqlwhere) > 0) {
339 $sql .=
" AND (".implode(
" ".$filtermode.
" ", $sqlwhere).
")";
342 if (!empty($sortfield)) {
343 $sql .= $this->db->order($sortfield, $sortorder);
345 if (!empty($limit)) {
346 $sql .=
' '.$this->db->plimit($limit, $offset);
349 $resql = $this->db->query($sql);
351 $num = $this->db->num_rows($resql);
353 while ($i < ($limit ? min($limit, $num) : $num)) {
354 $obj = $this->db->fetch_object($resql);
356 $record =
new self($this->db);
357 $record->setVarsFromFetchObj($obj);
359 $records[$record->id] = $record;
363 $this->db->free($resql);
367 $this->errors[] =
'Error '.$this->db->lasterror();
368 dol_syslog(__METHOD__.
' '.join(
',', $this->errors), LOG_ERR);
393 public function delete(
User $user, $notrigger =
false)
410 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
428 global $conf, $user, $langs;
430 require_once DOL_DOCUMENT_ROOT .
'/product/class/product.class.php';
431 include_once DOL_DOCUMENT_ROOT .
'/product/stock/class/mouvementstock.class.php';
432 include_once DOL_DOCUMENT_ROOT .
'/product/stock/stocktransfer/class/stocktransfer.class.php';
435 $p->fetch($this->fk_product);
437 $op[0] =
"+".trim($this->qty);
438 $op[1] =
"-".trim($this->qty);
441 $movementstock->origin_type = $st->origin_type;
442 $movementstock->origin_id = $this->fk_stocktransfer;
444 if (empty($this->batch)) {
457 $result = $movementstock->_create(
463 empty($direction) ? $this->pmp : 0,
473 if ($p->hasbatch()) {
474 $arraybatchinfo = $p->loadBatchInfo($this->batch);
475 if (count($arraybatchinfo) > 0) {
476 $firstrecord = array_shift($arraybatchinfo);
477 $dlc = $firstrecord[
'eatby'];
478 $dluo = $firstrecord[
'sellby'];
498 $result = $movementstock->_create(
504 empty($direction) ? $this->pmp : 0,
518 setEventMessages($langs->trans(
'StockTransferNoBatchForProduct', $p->getNomUrl()),
'',
'errors');
535 global $conf, $langs;
537 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
542 if ($this->
status == self::STATUS_VALIDATED) {
543 dol_syslog(get_class($this).
"::validate action abandonned: already validated", LOG_WARNING);
560 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
565 $this->newref = $num;
569 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
570 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
571 $sql .=
" status = ".self::STATUS_VALIDATED;
572 if (!empty($this->fields[
'date_validation'])) {
573 $sql .=
", date_validation = '".$this->db->idate($now).
"',";
575 if (!empty($this->fields[
'fk_user_valid'])) {
576 $sql .=
", fk_user_valid = ".((int) $user->id);
578 $sql .=
" WHERE rowid = ".((int) $this->
id);
580 dol_syslog(get_class($this).
"::validate()", LOG_DEBUG);
581 $resql = $this->db->query($sql);
584 $this->error = $this->db->lasterror();
588 if (!$error && !$notrigger) {
590 $result = $this->
call_trigger(
'STOCKTRANSFERLINE_VALIDATE', $user);
599 $this->oldref = $this->ref;
602 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
604 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filename = CONCAT('".$this->db->escape($this->newref).
"', SUBSTR(filename, ".(strlen($this->
ref) + 1).
")), filepath = 'stocktransferline/".$this->db->escape($this->newref).
"'";
605 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'stocktransferline/".$this->db->escape($this->
ref).
"' and entity = ".((int) $conf->entity);
606 $resql = $this->db->query($sql);
609 $this->error = $this->db->lasterror();
611 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'stocktransferline/".$this->db->escape($this->newref).
"'";
612 $sql .=
" WHERE filepath = 'stocktransferline/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
613 $resql = $this->db->query($sql);
616 $this->error = $this->db->lasterror();
622 $dirsource = $conf->stocktransfer->dir_output.
'/stocktransferline/'.$oldref;
623 $dirdest = $conf->stocktransfer->dir_output.
'/stocktransferline/'.$newref;
624 if (!$error && file_exists($dirsource)) {
625 dol_syslog(get_class($this).
"::validate() rename dir ".$dirsource.
" into ".$dirdest);
627 if (@rename($dirsource, $dirdest)) {
630 $listoffiles =
dol_dir_list($conf->stocktransfer->dir_output.
'/stocktransferline/'.$newref,
'files', 1,
'^'.preg_quote($oldref,
'/'));
631 foreach ($listoffiles as $fileentry) {
632 $dirsource = $fileentry[
'name'];
633 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
634 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
635 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
636 @rename($dirsource, $dirdest);
646 $this->
status = self::STATUS_VALIDATED;
653 $this->db->rollback();
669 if ($this->
status <= self::STATUS_DRAFT) {
680 return $this->
setStatusCommon($user, self::STATUS_DRAFT, $notrigger,
'STOCKTRANSFERLINE_UNVALIDATE');
690 public function cancel($user, $notrigger = 0)
693 if ($this->
status != self::STATUS_VALIDATED) {
704 return $this->
setStatusCommon($user, self::STATUS_CANCELED, $notrigger,
'STOCKTRANSFERLINE_CLOSE');
714 public function reopen($user, $notrigger = 0)
717 if ($this->
status != self::STATUS_CANCELED) {
728 return $this->
setStatusCommon($user, self::STATUS_VALIDATED, $notrigger,
'STOCKTRANSFERLINE_REOPEN');
741 public function getNomUrl($withpicto = 0, $option =
'', $notooltip = 0, $morecss =
'', $save_lastsearch_value = -1)
743 global $conf, $langs, $hookmanager;
745 if (!empty($conf->dol_no_mouse_hover)) {
751 $label =
'<u>'.$langs->trans(
"StockTransferLine").
'</u>';
753 $label .=
'<b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
754 if (isset($this->
status)) {
755 $label .=
'<br><b>'.$langs->trans(
"Status").
":</b> ".$this->
getLibStatut(5);
758 $url =
dol_buildpath(
'/stocktransfer/stocktransferline_card.php', 1).
'?id='.$this->id;
760 if ($option !=
'nolink') {
762 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
763 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
764 $add_save_lastsearch_values = 1;
766 if ($add_save_lastsearch_values) {
767 $url .=
'&save_lastsearch_values=1';
772 if (empty($notooltip)) {
774 $label = $langs->trans(
"ShowStockTransferLine");
775 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
777 $linkclose .=
' title="'.dol_escape_htmltag($label, 1).
'"';
778 $linkclose .=
' class="classfortooltip'.($morecss ?
' '.$morecss :
'').
'"';
780 $linkclose = ($morecss ?
' class="'.$morecss.
'"' :
'');
783 $linkstart =
'<a href="'.$url.
'"';
784 $linkstart .= $linkclose.
'>';
787 $result .= $linkstart;
789 if (empty($this->showphoto_on_popup)) {
791 $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);
795 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
797 list($class, $module) = explode(
'@', $this->picto);
800 $filename = $filearray[0][
'name'];
801 if (!empty($filename)) {
802 $pospoint = strpos($filearray[0][
'name'],
'.');
804 $pathtophoto = $class.
'/'.$this->
ref.
'/thumbs/'.substr($filename, 0, $pospoint).
'_mini'.substr($filename, $pospoint);
806 $result .=
'<div class="floatleft inline-block valignmiddle divphotoref"><div class="photoref"><img class="photo'.$module.
'" alt="No photo" border="0" src="'.DOL_URL_ROOT.
'/viewimage.php?modulepart='.$module.
'&entity='.$conf->entity.
'&file='.urlencode($pathtophoto).
'"></div></div>';
808 $result .=
'<div class="floatleft inline-block valignmiddle divphotoref"><img class="photouserphoto userphoto" alt="No photo" border="0" src="'.DOL_URL_ROOT.
'/viewimage.php?modulepart='.$module.
'&entity='.$conf->entity.
'&file='.urlencode($pathtophoto).
'"></div>';
813 $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);
818 if ($withpicto != 2) {
819 $result .= $this->ref;
825 global $action, $hookmanager;
826 $hookmanager->initHooks(array(
'stocktransferlinedao'));
827 $parameters = array(
'id'=>$this->
id,
'getnomurl'=>$result);
828 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
830 $result = $hookmanager->resPrint;
832 $result .= $hookmanager->resPrint;
860 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
863 $this->labelStatus[self::STATUS_DRAFT] = $langs->trans(
'Draft');
864 $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans(
'Enabled');
865 $this->labelStatus[self::STATUS_CANCELED] = $langs->trans(
'Disabled');
866 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans(
'Draft');
867 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans(
'Enabled');
868 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans(
'Disabled');
871 $statusType =
'status'.$status;
873 if ($status == self::STATUS_CANCELED) {
874 $statusType =
'status6';
877 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status],
'', $statusType, $mode);
888 $sql =
'SELECT rowid, date_creation as datec, tms as datem,';
889 $sql .=
' fk_user_creat, fk_user_modif';
890 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element.
' as t';
891 $sql .=
' WHERE t.rowid = '.((int) $id);
892 $result = $this->db->query($sql);
894 if ($this->db->num_rows($result)) {
895 $obj = $this->db->fetch_object($result);
896 $this->
id = $obj->rowid;
898 $this->user_creation_id = $obj->fk_user_creat;
899 $this->user_modification_id = $obj->fk_user_modif;
900 $this->date_creation = $this->db->jdate($obj->datec);
901 $this->date_modification = empty($obj->datem) ?
'' : $this->db->jdate($obj->datem);
904 $this->db->free($result);
928 global $langs, $conf;
929 $langs->load(
"stocks");
932 $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON =
'mod_stocktransferline_standard';
939 $classname = $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON;
942 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
943 foreach ($dirmodels as $reldir) {
947 $mybool |= @include_once $dir.$file;
950 if ($mybool ===
false) {
955 if (class_exists($classname)) {
956 $obj =
new $classname();
957 $numref = $obj->getNextValue($this);
959 if ($numref !=
'' && $numref !=
'-1') {
962 $this->error = $obj->error;
967 print $langs->trans(
"Error").
" ".$langs->trans(
"ClassNotFound").
' '.$classname;
971 print $langs->trans(
"ErrorNumberingModuleNotSetup", $this->element);
987 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
989 global $conf, $langs;
992 $includedocgeneration = 0;
994 $langs->load(
"stocks");
997 $modele =
'standard_stocktransferline';
999 if (!empty($this->model_pdf)) {
1000 $modele = $this->model_pdf;
1002 $modele = $conf->global->STOCKTRANSFERLINE_ADDON_PDF;
1006 $modelpath =
"core/modules/stocktransfer/doc/";
1008 if ($includedocgeneration) {
1009 $result = $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1038 $this->db->commit();
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
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.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
updateCommon(User $user, $notrigger=false)
Update object into database.
fetchLinesCommon($morewhere='', $noextrafields=0)
Load object in memory from the database.
fetchCommon($id, $ref=null, $morewhere='', $noextrafields=0)
Load object in memory from the database.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Dolibarr database access.
Class to manage stock movements.
Class to manage products or services.
Class for StockTransferLine.
reopen($user, $notrigger=0)
Set back to validated status.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
getLibStatut($mode=0)
Return label of the status.
setDraft($user, $notrigger=0)
Set draft status.
fetch($id, $ref=null)
Load object in memory from the database.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
__construct(DoliDB $db)
Constructor.
fetchLines()
Load object lines in memory from the database.
create(User $user, $notrigger=false)
Create object into database.
validate($user, $notrigger=0)
Validate object.
update(User $user, $notrigger=false)
Update object into database.
cancel($user, $notrigger=0)
Set cancel status.
doStockMovement($label, $code_inv, $fk_entrepot, $direction=1)
Makes all stock movements (add quantity, remove quantity or cancel all actions)
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter=array(), $filtermode='AND')
Load list of objects in memory from the database.
createFromClone(User $user, $fromid)
Clone an object into another one.
LibStatut($status, $mode=0)
Return the status.
info($id)
Load the info information in the object.
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module.
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.
Class to manage Dolibarr users.
dol_dir_list($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.
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_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_now($mode='auto')
Return date for now.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
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.