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);
254 $this->errors =
$object->errors;
266 if (property_exists($this,
'socid') && $this->socid ==
$object->socid) {
273 unset(
$object->context[
'createfromclone']);
280 $this->db->rollback();
292 public function fetch($id, $ref =
null)
295 if ($result > 0 && !empty($this->table_element_line)) {
308 $this->lines = array();
327 public function fetchAll($sortorder =
'', $sortfield =
'', $limit = 0, $offset = 0, $filter =
'', $filtermode =
'AND')
335 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element.
' as t';
336 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
337 $sql .=
' WHERE t.entity IN ('.getEntity($this->element).
')';
339 $sql .=
' WHERE 1 = 1';
346 $this->errors[] = $errormessage;
347 dol_syslog(__METHOD__.
' '.implode(
',', $this->errors), LOG_ERR);
351 if (!empty($sortfield)) {
352 $sql .= $this->db->order($sortfield, $sortorder);
354 if (!empty($limit)) {
355 $sql .=
' '.$this->db->plimit($limit, $offset);
358 $resql = $this->db->query($sql);
360 $num = $this->db->num_rows($resql);
362 while ($i < ($limit ? min($limit, $num) : $num)) {
363 $obj = $this->db->fetch_object($resql);
365 $record =
new self($this->db);
366 $record->setVarsFromFetchObj($obj);
368 $records[$record->id] = $record;
372 $this->db->free($resql);
376 $this->errors[] =
'Error '.$this->db->lasterror();
377 dol_syslog(__METHOD__.
' '.implode(
',', $this->errors), LOG_ERR);
402 public function delete(
User $user, $notrigger = 0)
419 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
437 global $user, $langs;
439 require_once DOL_DOCUMENT_ROOT .
'/product/class/product.class.php';
440 include_once DOL_DOCUMENT_ROOT .
'/product/stock/class/mouvementstock.class.php';
441 include_once DOL_DOCUMENT_ROOT .
'/product/stock/stocktransfer/class/stocktransfer.class.php';
444 $p->fetch($this->fk_product);
447 $op[0] =
"+".trim((
string) $this->qty);
448 $op[1] =
"-".trim((
string) $this->qty);
451 $movementstock->origin_type = $st->origin_type;
452 $movementstock->origin_id = $this->fk_stocktransfer;
454 if (empty($this->batch)) {
455 $result = $movementstock->_create(
459 (
float) $op[$direction],
461 empty($direction) ? $this->pmp : 0,
471 if ($p->hasbatch()) {
472 $arraybatchinfo = $p->loadBatchInfo($this->batch);
473 if (count($arraybatchinfo) > 0) {
474 $firstrecord = array_shift($arraybatchinfo);
475 $dlc = $firstrecord[
'eatby'];
476 $dluo = $firstrecord[
'sellby'];
482 $result = $movementstock->_create(
486 (
float) $op[$direction],
488 empty($direction) ? $this->pmp : 0,
502 $this->error = $langs->trans(
'StockTransferNoBatchForProduct', $p->getNomUrl());
503 $this->errors[] = $this->error;
520 global
$conf, $langs;
522 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
527 if ($this->
status == self::STATUS_VALIDATED) {
528 dol_syslog(get_class($this).
"::validate action abandoned: already validated", LOG_WARNING);
545 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
550 $this->newref = $num;
554 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
555 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
556 $sql .=
" status = ".self::STATUS_VALIDATED;
557 if (!empty($this->fields[
'date_validation'])) {
558 $sql .=
", date_validation = '".$this->db->idate($now).
"',";
560 if (!empty($this->fields[
'fk_user_valid'])) {
561 $sql .=
", fk_user_valid = ".((int) $user->id);
563 $sql .=
" WHERE rowid = ".((int) $this->
id);
565 dol_syslog(get_class($this).
"::validate()", LOG_DEBUG);
566 $resql = $this->db->query($sql);
569 $this->error = $this->db->lasterror();
573 if (!$error && !$notrigger) {
575 $result = $this->
call_trigger(
'STOCKTRANSFERLINE_VALIDATE', $user);
584 $this->oldref = $this->ref;
587 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
589 $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).
"'";
590 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'stocktransferline/".$this->db->escape($this->
ref).
"' and entity = ".((int)
$conf->entity);
591 $resql = $this->db->query($sql);
594 $this->error = $this->db->lasterror();
596 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'stocktransferline/".$this->db->escape($this->newref).
"'";
597 $sql .=
" WHERE filepath = 'stocktransferline/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
598 $resql = $this->db->query($sql);
601 $this->error = $this->db->lasterror();
607 $dirsource =
$conf->stocktransfer->dir_output.
'/stocktransferline/'.$oldref;
608 $dirdest =
$conf->stocktransfer->dir_output.
'/stocktransferline/'.$newref;
609 if (!$error && file_exists($dirsource)) {
610 dol_syslog(get_class($this).
"::validate() rename dir ".$dirsource.
" into ".$dirdest);
612 if (@rename($dirsource, $dirdest)) {
615 $listoffiles =
dol_dir_list(
$conf->stocktransfer->dir_output.
'/stocktransferline/'.$newref,
'files', 1,
'^'.preg_quote($oldref,
'/'));
616 foreach ($listoffiles as $fileentry) {
617 $dirsource = $fileentry[
'name'];
618 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
619 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
620 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
621 @rename($dirsource, $dirdest);
631 $this->
status = self::STATUS_VALIDATED;
638 $this->db->rollback();
654 if ($this->
status <= self::STATUS_DRAFT) {
665 return $this->
setStatusCommon($user, self::STATUS_DRAFT, $notrigger,
'STOCKTRANSFERLINE_UNVALIDATE');
675 public function cancel($user, $notrigger = 0)
678 if ($this->
status != self::STATUS_VALIDATED) {
689 return $this->
setStatusCommon($user, self::STATUS_CANCELED, $notrigger,
'STOCKTRANSFERLINE_CLOSE');
699 public function reopen($user, $notrigger = 0)
702 if ($this->
status != self::STATUS_CANCELED) {
713 return $this->
setStatusCommon($user, self::STATUS_VALIDATED, $notrigger,
'STOCKTRANSFERLINE_REOPEN');
726 public function getNomUrl($withpicto = 0, $option =
'', $notooltip = 0, $morecss =
'', $save_lastsearch_value = -1)
728 global
$conf, $langs, $hookmanager;
730 if (!empty(
$conf->dol_no_mouse_hover)) {
736 $label =
'<u>'.$langs->trans(
"StockTransferLine").
'</u>';
738 $label .=
'<b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
739 if (isset($this->
status)) {
740 $label .=
'<br><b>'.$langs->trans(
"Status").
":</b> ".$this->
getLibStatut(5);
743 $url =
dol_buildpath(
'/stocktransfer/stocktransferline_card.php', 1).
'?id='.$this->id;
745 if ($option !=
'nolink') {
747 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
748 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
749 $add_save_lastsearch_values = 1;
751 if ($add_save_lastsearch_values) {
752 $url .=
'&save_lastsearch_values=1';
757 if (empty($notooltip)) {
759 $label = $langs->trans(
"ShowStockTransferLine");
760 $linkclose .=
' alt="'.dolPrintHTMLForAttribute($label).
'"';
762 $linkclose .=
' title="'.dolPrintHTMLForAttribute($label).
'"';
763 $linkclose .=
' class="classfortooltip'.($morecss ?
' '.$morecss :
'').
'"';
765 $linkclose = ($morecss ?
' class="'.$morecss.
'"' :
'');
768 $linkstart =
'<a href="'.$url.
'"';
769 $linkstart .= $linkclose.
'>';
772 $result .= $linkstart;
774 if (empty($this->showphoto_on_popup)) {
776 $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);
780 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
782 list($class, $module) = explode(
'@', $this->picto);
785 $filename = $filearray[0][
'name'];
786 if (!empty($filename)) {
787 $pospoint = strpos($filearray[0][
'name'],
'.');
789 $pathtophoto = $class.
'/'.$this->
ref.
'/thumbs/'.substr($filename, 0, $pospoint).
'_mini'.substr($filename, $pospoint);
791 $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>';
793 $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>';
798 $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);
803 if ($withpicto != 2) {
804 $result .= $this->ref;
810 global $action, $hookmanager;
811 $hookmanager->initHooks(array(
'stocktransferlinedao'));
812 $parameters = array(
'id' => $this->
id,
'getnomurl' => $result);
813 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
815 $result = $hookmanager->resPrint;
817 $result .= $hookmanager->resPrint;
845 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
848 $this->labelStatus[self::STATUS_DRAFT] = $langs->trans(
'Draft');
849 $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans(
'Enabled');
850 $this->labelStatus[self::STATUS_CANCELED] = $langs->trans(
'Disabled');
851 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans(
'Draft');
852 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans(
'Enabled');
853 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans(
'Disabled');
856 $statusType =
'status'.$status;
858 if ($status == self::STATUS_CANCELED) {
859 $statusType =
'status6';
862 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status],
'', $statusType, $mode);
873 $sql =
'SELECT rowid, date_creation as datec, tms as datem,';
874 $sql .=
' fk_user_creat, fk_user_modif';
875 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element.
' as t';
876 $sql .=
' WHERE t.rowid = '.((int) $id);
877 $result = $this->db->query($sql);
879 if ($this->db->num_rows($result)) {
880 $obj = $this->db->fetch_object($result);
881 $this->
id = $obj->rowid;
883 $this->user_creation_id = $obj->fk_user_creat;
884 $this->user_modification_id = $obj->fk_user_modif;
885 $this->date_creation = $this->db->jdate($obj->datec);
886 $this->date_modification = empty($obj->datem) ?
'' : $this->db->jdate($obj->datem);
889 $this->db->free($result);
913 global $langs,
$conf;
914 $langs->load(
"stocks");
917 $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON =
'mod_stocktransferline_standard';
927 $dirmodels = array_merge(array(
'/'), (array)
$conf->modules_parts[
'models']);
928 foreach ($dirmodels as $reldir) {
932 $mybool = ((bool) @include_once $dir.$file) || $mybool;
940 if (class_exists($classname)) {
941 $obj =
new $classname();
942 '@phan-var-force ModeleNumRefStockTransfer $obj';
943 $numref = $obj->getNextValue($this);
945 if ($numref !=
'' && $numref !=
'-1') {
948 $this->error = $obj->error;
953 print $langs->trans(
"Error").
" ".$langs->trans(
"ClassNotFound").
' '.$classname;
957 print $langs->trans(
"ErrorNumberingModuleNotSetup", $this->element);
973 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
975 global
$conf, $langs;
978 $includedocgeneration = 0;
980 $langs->load(
"stocks");
983 $modele =
'standard_stocktransferline';
985 if (!empty($this->model_pdf)) {
986 $modele = $this->model_pdf;
992 $modelpath =
"core/modules/stocktransfer/doc/";
994 if ($includedocgeneration) {
995 $result = $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1024 $this->db->commit();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $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.
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.
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.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
dol_now($mode='auto')
Return date for now.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
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...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...