28require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobjectline.class.php';
40 public $element =
'stocktransferline';
45 public $table_element =
'stocktransfer_stocktransferline';
50 public $picto =
'stocktransferline@stocktransfer';
52 const STATUS_DRAFT = 0;
53 const STATUS_VALIDATED = 1;
54 const STATUS_CANCELED = 9;
86 public $fields = array(
87 'rowid' => array(
'type' =>
'integer',
'label' =>
'TechnicalID',
'enabled' => 1,
'position' => 1,
'notnull' => 1,
'visible' => 0,
'noteditable' => 1,
'index' => 1,
'comment' =>
"Id"),
88 'amount' => array(
'type' =>
'price',
'label' =>
'Amount',
'enabled' => 1,
'position' => 40,
'notnull' => 0,
'visible' => 1,
'default' =>
'null',
'isameasure' => 1,
'help' =>
"Help text for amount",),
89 '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",),
90 '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,),
91 '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,),
92 'fk_stocktransfer' => array(
'type' =>
'integer:StockTransfer:stocktransfer/stock/class/stocktransfer.class.php',
'label' =>
'StockTransfer',
'enabled' => 1,
'position' => 50,
'notnull' => 1,
'visible' => 0,),
93 'fk_product' => array(
'type' =>
'integer:Product:product/class/product.class.php',
'label' =>
'Product',
'enabled' => 1,
'position' => 50,
'notnull' => 1,
'visible' => 1,),
94 'batch' => array(
'type' =>
'varchar(128)',
'label' =>
'Batch',
'enabled' => 1,
'position' => 1000,
'notnull' => -1,
'visible' => 1,),
95 'pmp' => array(
'type' =>
'double',
'label' =>
'PMP',
'enabled' => 1,
'position' => 50,
'notnull' => 0,
'visible' => 1,),
96 '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",),
114 public $fk_warehouse_destination;
118 public $fk_warehouse_source;
122 public $fk_stocktransfer;
147 global
$conf, $langs;
151 $this->ismultientitymanaged = 0;
152 $this->isextrafieldmanaged = 1;
155 $this->fields[
'rowid'][
'visible'] = 0;
157 if (!
isModEnabled(
'multicompany') && isset($this->fields[
'entity'])) {
158 $this->fields[
'entity'][
'enabled'] = 0;
168 foreach ($this->fields as $key => $val) {
169 if (isset($val[
'enabled']) && empty($val[
'enabled'])) {
170 unset($this->fields[$key]);
175 if (is_object($langs)) {
176 foreach ($this->fields as $key => $val) {
177 if (isset($val[
'arrayofkeyval']) && is_array($val[
'arrayofkeyval'])) {
178 foreach ($val[
'arrayofkeyval'] as $key2 => $val2) {
179 $this->fields[$key][
'arrayofkeyval'][$key2] = $langs->trans($val2);
207 global $langs, $extrafields;
217 $result =
$object->fetchCommon($fromid);
218 if ($result > 0 && !empty(
$object->table_element_line)) {
232 $object->ref = empty($this->fields[
'ref'][
'default']) ?
"copy_of_".$object->ref : $this->fields[
'ref'][
'default'];
233 $object->label = empty($this->fields[
'label'][
'default']) ? $langs->trans(
"CopyOf").
" ".
$object->label : $this->fields[
'label'][
'default'];
234 $object->status = self::STATUS_DRAFT;
237 if (is_array(
$object->array_options) && count(
$object->array_options) > 0) {
238 $extrafields->fetch_name_optionals_label($this->table_element);
239 foreach (
$object->array_options as $key => $option) {
240 $shortkey = preg_replace(
'/options_/',
'', $key);
241 if (!empty($extrafields->attributes[$this->table_element][
'unique'][$shortkey])) {
243 unset(
$object->array_options[$key]);
249 $object->context[
'createfromclone'] =
'createfromclone';
250 $result =
$object->createCommon($user);
265 if (property_exists($this,
'socid') && $this->socid ==
$object->socid) {
272 unset(
$object->context[
'createfromclone']);
279 $this->db->rollback();
291 public function fetch($id, $ref =
null)
294 if ($result > 0 && !empty($this->table_element_line)) {
307 $this->lines = array();
326 public function fetchAll($sortorder =
'', $sortfield =
'', $limit = 0, $offset = 0, $filter =
'', $filtermode =
'AND')
334 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element.
' as t';
335 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
336 $sql .=
' WHERE t.entity IN ('.getEntity($this->element).
')';
338 $sql .=
' WHERE 1 = 1';
343 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
345 $this->errors[] = $errormessage;
346 dol_syslog(__METHOD__.
' '.implode(
',', $this->errors), LOG_ERR);
350 if (!empty($sortfield)) {
351 $sql .= $this->db->order($sortfield, $sortorder);
353 if (!empty($limit)) {
354 $sql .=
' '.$this->db->plimit($limit, $offset);
357 $resql = $this->db->query($sql);
359 $num = $this->db->num_rows($resql);
361 while ($i < ($limit ? min($limit, $num) : $num)) {
362 $obj = $this->db->fetch_object($resql);
364 $record =
new self($this->db);
365 $record->setVarsFromFetchObj($obj);
367 $records[$record->id] = $record;
371 $this->db->free($resql);
375 $this->errors[] =
'Error '.$this->db->lasterror();
376 dol_syslog(__METHOD__.
' '.implode(
',', $this->errors), LOG_ERR);
401 public function delete(
User $user, $notrigger = 0)
418 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
436 global $user, $langs;
438 require_once DOL_DOCUMENT_ROOT .
'/product/class/product.class.php';
439 include_once DOL_DOCUMENT_ROOT .
'/product/stock/class/mouvementstock.class.php';
440 include_once DOL_DOCUMENT_ROOT .
'/product/stock/stocktransfer/class/stocktransfer.class.php';
443 $p->fetch($this->fk_product);
446 $op[0] =
"+".trim((
string) $this->qty);
447 $op[1] =
"-".trim((
string) $this->qty);
450 $movementstock->origin_type = $st->origin_type;
451 $movementstock->origin_id = $this->fk_stocktransfer;
453 if (empty($this->batch)) {
454 $result = $movementstock->_create(
458 (
float) $op[$direction],
460 empty($direction) ? $this->pmp : 0,
470 if ($p->hasbatch()) {
471 $arraybatchinfo = $p->loadBatchInfo($this->batch);
472 if (count($arraybatchinfo) > 0) {
473 $firstrecord = array_shift($arraybatchinfo);
474 $dlc = $firstrecord[
'eatby'];
475 $dluo = $firstrecord[
'sellby'];
481 $result = $movementstock->_create(
485 (
float) $op[$direction],
487 empty($direction) ? $this->pmp : 0,
501 $this->error = $langs->trans(
'StockTransferNoBatchForProduct', $p->getNomUrl());
502 $this->errors[] = $this->error;
519 global
$conf, $langs;
521 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
526 if ($this->
status == self::STATUS_VALIDATED) {
527 dol_syslog(get_class($this).
"::validate action abandoned: already validated", LOG_WARNING);
544 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
549 $this->newref = $num;
553 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
554 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
555 $sql .=
" status = ".self::STATUS_VALIDATED;
556 if (!empty($this->fields[
'date_validation'])) {
557 $sql .=
", date_validation = '".$this->db->idate($now).
"',";
559 if (!empty($this->fields[
'fk_user_valid'])) {
560 $sql .=
", fk_user_valid = ".((int) $user->id);
562 $sql .=
" WHERE rowid = ".((int) $this->
id);
564 dol_syslog(get_class($this).
"::validate()", LOG_DEBUG);
565 $resql = $this->db->query($sql);
568 $this->error = $this->db->lasterror();
572 if (!$error && !$notrigger) {
574 $result = $this->call_trigger(
'STOCKTRANSFERLINE_VALIDATE', $user);
583 $this->oldref = $this->ref;
586 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
588 $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).
"'";
589 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'stocktransferline/".$this->db->escape($this->
ref).
"' and entity = ".((int)
$conf->entity);
590 $resql = $this->db->query($sql);
593 $this->error = $this->db->lasterror();
595 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'stocktransferline/".$this->db->escape($this->newref).
"'";
596 $sql .=
" WHERE filepath = 'stocktransferline/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
597 $resql = $this->db->query($sql);
600 $this->error = $this->db->lasterror();
606 $dirsource =
$conf->stocktransfer->dir_output.
'/stocktransferline/'.$oldref;
607 $dirdest =
$conf->stocktransfer->dir_output.
'/stocktransferline/'.$newref;
608 if (!$error && file_exists($dirsource)) {
609 dol_syslog(get_class($this).
"::validate() rename dir ".$dirsource.
" into ".$dirdest);
611 if (@rename($dirsource, $dirdest)) {
614 $listoffiles =
dol_dir_list(
$conf->stocktransfer->dir_output.
'/stocktransferline/'.$newref,
'files', 1,
'^'.preg_quote($oldref,
'/'));
615 foreach ($listoffiles as $fileentry) {
616 $dirsource = $fileentry[
'name'];
617 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
618 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
619 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
620 @rename($dirsource, $dirdest);
630 $this->
status = self::STATUS_VALIDATED;
637 $this->db->rollback();
653 if ($this->
status <= self::STATUS_DRAFT) {
664 return $this->
setStatusCommon($user, self::STATUS_DRAFT, $notrigger,
'STOCKTRANSFERLINE_UNVALIDATE');
674 public function cancel($user, $notrigger = 0)
677 if ($this->
status != self::STATUS_VALIDATED) {
688 return $this->
setStatusCommon($user, self::STATUS_CANCELED, $notrigger,
'STOCKTRANSFERLINE_CLOSE');
698 public function reopen($user, $notrigger = 0)
701 if ($this->
status != self::STATUS_CANCELED) {
712 return $this->
setStatusCommon($user, self::STATUS_VALIDATED, $notrigger,
'STOCKTRANSFERLINE_REOPEN');
725 public function getNomUrl($withpicto = 0, $option =
'', $notooltip = 0, $morecss =
'', $save_lastsearch_value = -1)
727 global
$conf, $langs, $hookmanager;
729 if (!empty(
$conf->dol_no_mouse_hover)) {
735 $label =
'<u>'.$langs->trans(
"StockTransferLine").
'</u>';
737 $label .=
'<b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
738 if (isset($this->
status)) {
739 $label .=
'<br><b>'.$langs->trans(
"Status").
":</b> ".$this->
getLibStatut(5);
742 $url =
dol_buildpath(
'/stocktransfer/stocktransferline_card.php', 1).
'?id='.$this->id;
744 if ($option !=
'nolink') {
746 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
747 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
748 $add_save_lastsearch_values = 1;
750 if ($add_save_lastsearch_values) {
751 $url .=
'&save_lastsearch_values=1';
756 if (empty($notooltip)) {
758 $label = $langs->trans(
"ShowStockTransferLine");
759 $linkclose .=
' alt="'.dolPrintHTMLForAttribute($label).
'"';
761 $linkclose .=
' title="'.dolPrintHTMLForAttribute($label).
'"';
762 $linkclose .=
' class="classfortooltip'.($morecss ?
' '.$morecss :
'').
'"';
764 $linkclose = ($morecss ?
' class="'.$morecss.
'"' :
'');
767 $linkstart =
'<a href="'.$url.
'"';
768 $linkstart .= $linkclose.
'>';
771 $result .= $linkstart;
773 if (empty($this->showphoto_on_popup)) {
775 $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);
779 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
781 list($class, $module) = explode(
'@', $this->picto);
784 $filename = $filearray[0][
'name'];
785 if (!empty($filename)) {
786 $pospoint = strpos($filearray[0][
'name'],
'.');
788 $pathtophoto = $class.
'/'.$this->
ref.
'/thumbs/'.substr($filename, 0, $pospoint).
'_mini'.substr($filename, $pospoint);
790 $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>';
792 $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>';
797 $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);
802 if ($withpicto != 2) {
803 $result .= $this->ref;
809 global $action, $hookmanager;
810 $hookmanager->initHooks(array(
'stocktransferlinedao'));
811 $parameters = array(
'id' => $this->
id,
'getnomurl' => $result);
812 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
814 $result = $hookmanager->resPrint;
816 $result .= $hookmanager->resPrint;
844 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
847 $this->labelStatus[self::STATUS_DRAFT] = $langs->trans(
'Draft');
848 $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans(
'Enabled');
849 $this->labelStatus[self::STATUS_CANCELED] = $langs->trans(
'Disabled');
850 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans(
'Draft');
851 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans(
'Enabled');
852 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans(
'Disabled');
855 $statusType =
'status'.$status;
857 if ($status == self::STATUS_CANCELED) {
858 $statusType =
'status6';
861 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status],
'', $statusType, $mode);
872 $sql =
'SELECT rowid, date_creation as datec, tms as datem,';
873 $sql .=
' fk_user_creat, fk_user_modif';
874 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element.
' as t';
875 $sql .=
' WHERE t.rowid = '.((int) $id);
876 $result = $this->db->query($sql);
878 if ($this->db->num_rows($result)) {
879 $obj = $this->db->fetch_object($result);
880 $this->
id = $obj->rowid;
882 $this->user_creation_id = $obj->fk_user_creat;
883 $this->user_modification_id = $obj->fk_user_modif;
884 $this->date_creation = $this->db->jdate($obj->datec);
885 $this->date_modification = empty($obj->datem) ?
'' : $this->db->jdate($obj->datem);
888 $this->db->free($result);
912 global $langs,
$conf;
913 $langs->load(
"stocks");
916 $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON =
'mod_stocktransferline_standard';
926 $dirmodels = array_merge(array(
'/'), (array)
$conf->modules_parts[
'models']);
927 foreach ($dirmodels as $reldir) {
931 $mybool = ((bool) @include_once $dir.$file) || $mybool;
939 if (class_exists($classname)) {
940 $obj =
new $classname();
941 '@phan-var-force ModeleNumRefStockTransfer $obj';
942 $numref = $obj->getNextValue($this);
944 if ($numref !=
'' && $numref !=
'-1') {
947 $this->error = $obj->error;
952 print $langs->trans(
"Error").
" ".$langs->trans(
"ClassNotFound").
' '.$classname;
956 print $langs->trans(
"ErrorNumberingModuleNotSetup", $this->element);
972 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
974 global
$conf, $langs;
977 $includedocgeneration = 0;
979 $langs->load(
"stocks");
982 $modele =
'standard_stocktransferline';
984 if (!empty($this->model_pdf)) {
985 $modele = $this->model_pdf;
991 $modelpath =
"core/modules/stocktransfer/doc/";
993 if ($includedocgeneration) {
994 $result = $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1023 $this->db->commit();
if(! $sortfield) if(! $sortorder) $object
deleteLineCommon(User $user, $idline, $notrigger=0)
Delete a line of object in database.
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.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
updateCommon(User $user, $notrigger=0)
Update object into database.
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.
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.
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 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.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter='', $filtermode='AND')
Load list of objects 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.
validate($user, $notrigger=0)
Validate object.
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.
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.
update(User $user, $notrigger=0)
Update object into database.
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 optionally the picto)
create(User $user, $notrigger=0)
Create object into database.
deleteLine(User $user, $idline, $notrigger=0)
Delete a line of object in 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...
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.
dol_now($mode='gmt')
Return date for now.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php