dolibarr  17.0.4
stocktransfer.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
4  * Copyright (C) 2022 Frédéric France <frederic.france@netlogic.fr>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
26 // Put here all includes required by your class file
27 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
28 require_once DOL_DOCUMENT_ROOT.'/core/class/commonincoterm.class.php';
29 
30 //require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
31 //require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
32 
37 {
38  use CommonIncoterm;
42  public $element = 'stocktransfer';
43 
47  public $table_element = 'stocktransfer_stocktransfer';
48 
53  public $ismultientitymanaged = 0;
54 
58  public $isextrafieldmanaged = 1;
59 
65  public $ref_client;
66 
70  public $ref_customer;
71 
72 
76  public $picto = 'stock';
77 
78  public $date_prevue_depart;
79  public $date_prevue_arrivee;
80  public $date_reelle_depart;
81  public $date_reelle_arrivee;
82 
83 
84  const STATUS_DRAFT = 0;
85  const STATUS_VALIDATED = 1;
86  const STATUS_TRANSFERED = 2;
87  const STATUS_CLOSED = 3;
88 
89 
115  // BEGIN MODULEBUILDER PROPERTIES
119  public $fields=array(
120  'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"),
121  'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>'1', 'position'=>1, 'default'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"),
122  'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>4, 'noteditable'=>'1', 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object"),
123  'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>0, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth200'/*, 'help'=>"Help text"*/, 'showoncombobox'=>'1',),
124  'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>31, 'notnull'=>0, 'visible'=>3,),
125  'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'enabled'=>'$conf->project->enabled', 'position'=>32, 'notnull'=>-1, 'visible'=>-1, 'index'=>1,),
126  'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'label'=>'ThirdParty', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1/*, 'help'=>"LinkToThirdparty"*/,),
127  'fk_warehouse_source' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Entrepôt source', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1, 'help'=>'HelpWarehouseStockTransferSource',),
128  'fk_warehouse_destination' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Entrepôt de destination', 'enabled'=>'1', 'position'=>51, 'notnull'=>0, 'visible'=>1, 'help'=>'HelpWarehouseStockTransferDestination'),
129  'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,),
130  'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0,),
131  'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,),
132  'date_prevue_depart' => array('type'=>'date', 'label'=>'DatePrevueDepart', 'enabled'=>'1', 'position'=>100, 'notnull'=>0, 'visible'=>1,),
133  'date_reelle_depart' => array('type'=>'date', 'label'=>'DateReelleDepart', 'enabled'=>'1', 'position'=>101, 'notnull'=>0, 'visible'=>5,),
134  'date_prevue_arrivee' => array('type'=>'date', 'label'=>'DatePrevueArrivee', 'enabled'=>'1', 'position'=>102, 'notnull'=>0, 'visible'=>1,),
135  'date_reelle_arrivee' => array('type'=>'date', 'label'=>'DateReelleArrivee', 'enabled'=>'1', 'position'=>103, 'notnull'=>0, 'visible'=>5,),
136  'lead_time_for_warning' => array('type'=>'integer', 'label'=>'LeadTimeForWarning', 'enabled'=>'1', 'position'=>200, 'default'=>0, 'notnull'=>0, 'visible'=>1),
137  'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2,),
138  'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>'1', 'position'=>510, 'notnull'=>1, 'visible'=>-2, 'foreignkey'=>'user.rowid',),
139  'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ChangedBy', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,),
140  'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,),
141  'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,),
142  'fk_incoterms' => array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-2, 'position'=>220),
143  'location_incoterms' => array('type'=>'varchar(255)', 'label'=>'IncotermLabel', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-2, 'position'=>225),
144  'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'visible'=>5, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '2'=>'StockStransferDecremented', '3'=>'StockStransferIncremented'),),
145  );
146  public $rowid;
147  public $ref;
148  public $label;
149  public $fk_soc;
150  public $fk_project;
151  public $description;
152  public $note_public;
153  public $note_private;
154  public $date_creation;
155  public $tms;
156  public $lead_time_for_warning;
157  public $fk_user_creat;
158  public $fk_user_modif;
159  public $import_key;
160  public $model_pdf;
161  public $status;
162  // END MODULEBUILDER PROPERTIES
163 
164 
165  // If this object has a subtable with lines
166 
170  public $table_element_line = 'stocktransfer_stocktransferline';
171 
175  public $fk_element = 'fk_stocktransfer';
176 
180  //public $class_element_line = 'StockTransferline';
181 
185  //protected $childtables = array();
186 
192  protected $childtablesoncascade = array('stocktransfer_stocktransferline');
193 
197  //public $lines = array();
198 
199 
200 
206  public function __construct(DoliDB $db)
207  {
208  global $conf, $langs;
209 
210  $this->db = $db;
211  $this->origin_type = 'StockTransfer@product/stock/stocktransfer';
212 
213  if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) $this->fields['rowid']['visible'] = 0;
214  if (!isModEnabled('multicompany') && isset($this->fields['entity'])) $this->fields['entity']['enabled'] = 0;
215 
216  // Example to show how to set values of fields definition dynamically
217  /*if ($user->rights->stocktransfer->stocktransfer->read) {
218  $this->fields['myfield']['visible'] = 1;
219  $this->fields['myfield']['noteditable'] = 0;
220  }*/
221 
222  // Unset fields that are disabled
223  foreach ($this->fields as $key => $val) {
224  if (isset($val['enabled']) && empty($val['enabled'])) {
225  unset($this->fields[$key]);
226  }
227  }
228 
229  // Translate some data of arrayofkeyval
230  if (is_object($langs)) {
231  foreach ($this->fields as $key => $val) {
232  if (isset($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
233  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
234  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
235  }
236  }
237  }
238  }
239  }
240 
248  public function create(User $user, $notrigger = false)
249  {
250  $model_pdf = GETPOST('model');
251  if (!empty($model_pdf)) $this->model_pdf = $model_pdf;
252  $this->status = (int) $this->status;
253  if ($this->fk_warehouse_source <= 0) $this->fk_warehouse_source = 0;
254  if ($this->fk_warehouse_destination <= 0) $this->fk_warehouse_destination = 0;
255  return $this->createCommon($user, $notrigger);
256  }
257 
265  public function createFromClone(User $user, $fromid)
266  {
267  global $langs, $extrafields;
268  $error = 0;
269 
270  dol_syslog(__METHOD__, LOG_DEBUG);
271 
272  $object = new self($this->db);
273 
274  $this->db->begin();
275 
276  // Load source object
277  $result = $object->fetchCommon($fromid);
278  if ($result > 0 && !empty($object->table_element_line)) $object->fetchLines();
279 
280  // get lines so they will be clone
281  //foreach($this->lines as $line)
282  // $line->fetch_optionals();
283 
284  // Reset some properties
285  unset($object->id);
286  unset($object->fk_user_creat);
287  unset($object->import_key);
288  unset($object->date_prevue_depart);
289  unset($object->date_prevue_arrivee);
290  unset($object->date_reelle_depart);
291  unset($object->date_reelle_arrivee);
292 
293 
294  // Clear fields
295  $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default'];
296  $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
297  $object->status = self::STATUS_DRAFT;
298  // ...
299  // Clear extrafields that are unique
300  if (is_array($object->array_options) && count($object->array_options) > 0) {
301  $extrafields->fetch_name_optionals_label($this->table_element);
302  foreach ($object->array_options as $key => $option) {
303  $shortkey = preg_replace('/options_/', '', $key);
304  if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
305  //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
306  unset($object->array_options[$key]);
307  }
308  }
309  }
310 
311  // Create clone
312  $object->context['createfromclone'] = 'createfromclone';
313  $result = $object->createCommon($user);
314  if ($result < 0) {
315  $error++;
316  $this->error = $object->error;
317  $this->errors = $object->errors;
318  }
319 
320  if (!$error) {
321  // copy internal contacts
322  if ($this->copy_linked_contact($object, 'internal') < 0) {
323  $error++;
324  }
325  }
326 
327  if (!$error) {
328  // copy external contacts if same company
329  if (property_exists($this, 'socid') && $this->socid == $object->socid) {
330  if ($this->copy_linked_contact($object, 'external') < 0)
331  $error++;
332  }
333  }
334 
335  unset($object->context['createfromclone']);
336 
337  // End
338  if (!$error) {
339  $this->db->commit();
340  return $object;
341  } else {
342  $this->db->rollback();
343  return -1;
344  }
345  }
346 
354  public function fetch($id, $ref = null)
355  {
356  $result = $this->fetchCommon($id, $ref);
357  if ($result > 0 && !empty($this->table_element_line)) $this->fetchLines();
358  return $result;
359  }
360 
366  public function fetchLines()
367  {
368  require_once DOL_DOCUMENT_ROOT . '/product/stock/stocktransfer/class/stocktransferline.class.php';
369  $this->lines = array();
370 
371  $result = $this->fetchLinesCommon();
372  usort($this->lines, array('stocktransfer', 'cmp'));
373  return $result;
374  }
375 
383  public function cmp($a, $b)
384  {
385  if ($a->rang == $b->rang) {
386  return 0;
387  }
388  return ($a->rang < $b->rang) ? -1 : 1;
389  }
390 
396  public function getValorisationTotale()
397  {
398 
399  $total_pmp = 0;
400 
401  if (empty($this->lines)) $this->fetchLines();
402  if (!empty($this->lines)) {
403  foreach ($this->lines as $l) $total_pmp+= ($l->pmp * $l->qty);
404  }
405 
406  return $total_pmp;
407  }
408 
420  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
421  {
422  global $conf;
423 
424  dol_syslog(__METHOD__, LOG_DEBUG);
425 
426  $records = array();
427 
428  $sql = 'SELECT ';
429  $sql .= $this->getFieldList();
430  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
431  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
432  else $sql .= ' WHERE 1 = 1';
433  // Manage filter
434  $sqlwhere = array();
435  if (count($filter) > 0) {
436  foreach ($filter as $key => $value) {
437  if ($key == 't.rowid') {
438  $sqlwhere[] = $key.'='.$value;
439  } elseif (strpos($key, 'date') !== false) {
440  $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\'';
441  } elseif ($key == 'customsql') {
442  $sqlwhere[] = $value;
443  } else {
444  $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\'';
445  }
446  }
447  }
448  if (count($sqlwhere) > 0) {
449  $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")";
450  }
451 
452  if (!empty($sortfield)) {
453  $sql .= $this->db->order($sortfield, $sortorder);
454  }
455  if (!empty($limit)) {
456  $sql .= ' '.$this->db->plimit($limit, $offset);
457  }
458 
459  $resql = $this->db->query($sql);
460  if ($resql) {
461  $num = $this->db->num_rows($resql);
462  $i = 0;
463  while ($i < ($limit ? min($limit, $num) : $num)) {
464  $obj = $this->db->fetch_object($resql);
465 
466  $record = new self($this->db);
467  $record->setVarsFromFetchObj($obj);
468 
469  $records[$record->id] = $record;
470 
471  $i++;
472  }
473  $this->db->free($resql);
474 
475  return $records;
476  } else {
477  $this->errors[] = 'Error '.$this->db->lasterror();
478  dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
479 
480  return -1;
481  }
482  }
483 
491  public function update(User $user, $notrigger = false)
492  {
493  $this->tms = ''; // Will be done automatically because tms field is on update cascade
494  $res = $this->updateCommon($user, $notrigger);
495  if ($this->socid > 0 || $this->fk_soc > 0 && empty($this->thirdparty)) $this->fetch_thirdparty();
496  if (empty($this->socid) && empty($this->fk_soc)) unset($this->thirdparty);
497  return $res;
498  }
499 
507  public function delete(User $user, $notrigger = false)
508  {
509  if ($this->status > self::STATUS_VALIDATED) {
510  return 0;
511  } else {
512  return $this->deleteCommon($user, $notrigger);
513  }
514  }
515 
524  public function deleteLine(User $user, $idline, $notrigger = false)
525  {
526  if ($this->status < 0) {
527  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
528  return -2;
529  }
530 
531  $res = $this->deleteLineCommon($user, $idline, $notrigger);
532  $this->line_order(true);
533  return $res;
534  }
535 
536 
544  public function validate($user, $notrigger = 0)
545  {
546  global $conf, $langs;
547 
548  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
549 
550  $error = 0;
551 
552  // Protection
553  if ($this->status == self::STATUS_VALIDATED) {
554  dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
555  return 0;
556  }
557 
558  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer->write))
559  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer->stocktransfer_advance->validate))))
560  {
561  $this->error='NotEnoughPermissions';
562  dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
563  return -1;
564  }*/
565 
566  $now = dol_now();
567 
568  $this->db->begin();
569 
570  // Define new ref
571  if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
572  $num = $this->getNextNumRef();
573  } else {
574  $num = $this->ref;
575  }
576  $this->newref = $num;
577 
578  if (!empty($num)) {
579  // Validate
580  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
581  $sql .= " SET ref = '".$this->db->escape($num)."',";
582  $sql .= " status = ".self::STATUS_VALIDATED;
583  if (!empty($this->fields['date_validation'])) $sql .= ", date_validation = '".$this->db->idate($now)."',";
584  if (!empty($this->fields['fk_user_valid'])) $sql .= ", fk_user_valid = ".((int) $user->id);
585  $sql .= " WHERE rowid = ".((int) $this->id);
586 
587  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
588  $resql = $this->db->query($sql);
589  if (!$resql) {
590  dol_print_error($this->db);
591  $this->error = $this->db->lasterror();
592  $error++;
593  }
594 
595  if (!$error && !$notrigger) {
596  // Call trigger
597  $result = $this->call_trigger('STOCKTRANSFER_VALIDATE', $user);
598  if ($result < 0) $error++;
599  // End call triggers
600  }
601  }
602 
603  if (!$error) {
604  $this->oldref = $this->ref;
605 
606  // Rename directory if dir was a temporary ref
607  if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
608  // Now we rename also files into index
609  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'stocktransfer/".$this->db->escape($this->newref)."'";
610  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransfer/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity);
611  $resql = $this->db->query($sql);
612  if (!$resql) { $error++; $this->error = $this->db->lasterror(); }
613 
614  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
615  $oldref = dol_sanitizeFileName($this->ref);
616  $newref = dol_sanitizeFileName($num);
617  $dirsource = $conf->stocktransfer->dir_output.'/stocktransfer/'.$oldref;
618  $dirdest = $conf->stocktransfer->dir_output.'/stocktransfer/'.$newref;
619  if (!$error && file_exists($dirsource)) {
620  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
621 
622  if (@rename($dirsource, $dirdest)) {
623  dol_syslog("Rename ok");
624  // Rename docs starting with $oldref with $newref
625  $listoffiles = dol_dir_list($conf->stocktransfer->dir_output.'/stocktransfer/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
626  foreach ($listoffiles as $fileentry) {
627  $dirsource = $fileentry['name'];
628  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
629  $dirsource = $fileentry['path'].'/'.$dirsource;
630  $dirdest = $fileentry['path'].'/'.$dirdest;
631  @rename($dirsource, $dirdest);
632  }
633  }
634  }
635  }
636  }
637 
638  // Set new ref and current status
639  if (!$error) {
640  $this->ref = $num;
641  $this->status = self::STATUS_VALIDATED;
642  }
643 
644  if (!$error) {
645  $this->db->commit();
646  return 1;
647  } else {
648  $this->db->rollback();
649  return -1;
650  }
651  }
652 
653 
661  public function setDraft($user, $notrigger = 0)
662  {
663  // Protection
664  if ($this->status <= self::STATUS_DRAFT) {
665  return 0;
666  }
667 
668  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
669  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
670  {
671  $this->error='Permission denied';
672  return -1;
673  }*/
674 
675  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'STOCKTRANSFER_UNVALIDATE');
676  }
677 
685  public function cancel($user, $notrigger = 0)
686  {
687  // Protection
688  if ($this->status != self::STATUS_VALIDATED) {
689  return 0;
690  }
691 
692  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
693  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
694  {
695  $this->error='Permission denied';
696  return -1;
697  }*/
698 
699  return $this->setStatusCommon($user, self::STATUS_CLOSED, $notrigger, 'STOCKTRANSFER_CLOSE');
700  }
701 
709  public function reopen($user, $notrigger = 0)
710  {
711  // Protection
712  if ($this->status != self::STATUS_CLOSED) {
713  return 0;
714  }
715 
716  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
717  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
718  {
719  $this->error='Permission denied';
720  return -1;
721  }*/
722 
723  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'STOCKTRANSFER_REOPEN');
724  }
725 
736  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
737  {
738  global $conf, $langs, $hookmanager;
739 
740  if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips
741 
742  $result = '';
743 
744  $label = '<u>'.$langs->trans("StockTransfer").'</u>';
745  $label .= '<br>';
746  $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
747  if (isset($this->status)) {
748  $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
749  }
750 
751  $url = dol_buildpath('/product/stock/stocktransfer/stocktransfer_card.php', 1).'?id='.$this->id;
752 
753  if ($option != 'nolink') {
754  // Add param to save lastsearch_values or not
755  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
756  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1;
757  if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1';
758  }
759 
760  $linkclose = '';
761  if (empty($notooltip)) {
762  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
763  $label = $langs->trans("ShowStockTransfer");
764  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
765  }
766  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
767  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
768  } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
769 
770  $linkstart = '<a href="'.$url.'"';
771  $linkstart .= $linkclose.'>';
772  $linkend = '</a>';
773 
774  $result .= $linkstart;
775 
776  if (empty($this->showphoto_on_popup)) {
777  if ($withpicto) $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);
778  } else {
779  if ($withpicto) {
780  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
781 
782  list($class, $module) = explode('@', $this->picto);
783  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
784  $filearray = dol_dir_list($upload_dir, "files");
785  $filename = $filearray[0]['name'];
786  if (!empty($filename)) {
787  $pospoint = strpos($filearray[0]['name'], '.');
788 
789  $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
790  if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) {
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>';
792  } else {
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>';
794  }
795 
796  $result .= '</div>';
797  } else {
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);
799  }
800  }
801  }
802 
803  if ($withpicto != 2) $result .= $this->ref;
804 
805  $result .= $linkend;
806  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
807 
808  global $action, $hookmanager;
809  $hookmanager->initHooks(array('stocktransferdao'));
810  $parameters = array('id'=>$this->id, 'getnomurl'=>$result);
811  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
812  if ($reshook > 0) $result = $hookmanager->resPrint;
813  else $result .= $hookmanager->resPrint;
814 
815  return $result;
816  }
817 
824  public function getLibStatut($mode = 0)
825  {
826  return $this->LibStatut($this->status, $mode);
827  }
828 
829  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
837  public function LibStatut($status, $mode = 0)
838  {
839  // phpcs:enable
840  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
841  global $langs;
842  //$langs->load("stocktransfer@stocktransfer");
843  $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft');
844  $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated');
845  $this->labelStatus[self::STATUS_TRANSFERED] = $langs->trans('StockStransferDecremented');
846  $this->labelStatus[self::STATUS_CLOSED] = $langs->trans('StockStransferIncremented');
847  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft');
848  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Validated');
849  $this->labelStatusShort[self::STATUS_TRANSFERED] = $langs->trans('StockStransferDecremented');
850  $this->labelStatusShort[self::STATUS_CLOSED] = $langs->trans('StockStransferIncremented');
851  }
852 
853  $statusType = 'status'.$status;
854  //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
855  if ($status == self::STATUS_CLOSED) $statusType = 'status6';
856 
857  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
858  }
859 
866  public function info($id)
867  {
868  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
869  $sql .= ' fk_user_creat, fk_user_modif';
870  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
871  $sql .= ' WHERE t.rowid = '.((int) $id);
872  $result = $this->db->query($sql);
873  if ($result) {
874  if ($this->db->num_rows($result)) {
875  $obj = $this->db->fetch_object($result);
876  $this->id = $obj->rowid;
877 
878  $this->user_creation_id = $obj->fk_user_creat;
879  $this->user_modification_id = $obj->fk_user_modif;
880  $this->date_creation = $this->db->jdate($obj->datec);
881  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
882  }
883 
884  $this->db->free($result);
885  } else {
886  dol_print_error($this->db);
887  }
888  }
889 
896  public function initAsSpecimen()
897  {
898  $this->initAsSpecimenCommon();
899  }
900 
906  public function getLinesArray()
907  {
908  $this->lines = array();
909 
910  $objectline = new StockTransferLine($this->db);
911  $result = $objectline->fetchAll('ASC', 'rang', 0, 0, array('customsql'=>'fk_stocktransfer = '.$this->id));
912 
913  if (is_numeric($result)) {
914  $this->error = $objectline->error;
915  $this->errors = $objectline->errors;
916  return $result;
917  } else {
918  $this->lines = $result;
919  return $this->lines;
920  }
921  }
922 
928  public function getNextNumRef()
929  {
930  global $langs, $conf;
931  $langs->load("stocks");
932 
933  if (empty($conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON)) {
934  $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON = 'mod_stocktransfer_standard';
935  }
936 
937  if (!empty($conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON)) {
938  $mybool = false;
939 
940  $file = $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON.".php";
941  $classname = $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON;
942 
943  // Include file with class
944  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
945  foreach ($dirmodels as $reldir) {
946  $dir = dol_buildpath($reldir."core/modules/stocktransfer/");
947 
948  // Load file with numbering class (if found)
949  $mybool |= @include_once $dir.$file;
950  }
951 
952  if ($mybool === false) {
953  dol_print_error('', "Failed to include file ".$file);
954  return '';
955  }
956 
957  if (class_exists($classname)) {
958  $obj = new $classname();
959  $numref = $obj->getNextValue($this);
960 
961  if ($numref != '' && $numref != '-1') {
962  return $numref;
963  } else {
964  $this->error = $obj->error;
965  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
966  return "";
967  }
968  } else {
969  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
970  return "";
971  }
972  } else {
973  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
974  return "";
975  }
976  }
977 
989  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
990  {
991  global $conf, $langs;
992 
993  $result = 0;
994  $includedocgeneration = 1;
995 
996  $langs->load("stocks");
997 
998  if (!dol_strlen($modele)) {
999  $modele = 'eagle';
1000 
1001  if ($this->modelpdf) {
1002  $modele = $this->modelpdf;
1003  } elseif (!empty($conf->global->STOCKTRANSFER_ADDON_PDF)) {
1004  $modele = $conf->global->STOCKTRANSFER_ADDON_PDF;
1005  }
1006  }
1007 
1008  $modelpath = "core/modules/stocktransfer/doc/";
1009 
1010  if ($includedocgeneration) {
1011  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1012  }
1013 
1014  return $result;
1015  }
1016 
1024  public function doScheduledJob()
1025  {
1026  global $conf, $langs;
1027 
1028  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1029 
1030  $error = 0;
1031  $this->output = '';
1032  $this->error = '';
1033 
1034  dol_syslog(__METHOD__, LOG_DEBUG);
1035 
1036  $now = dol_now();
1037 
1038  $this->db->begin();
1039 
1040  // ...
1041 
1042  $this->db->commit();
1043 
1044  return $error;
1045  }
1046 }
1047 
1051 //class StockTransferLine
1052 //{
1053 // // To complete with content of an object StockTransferLine
1054 // // We should have a field rowid, fk_stocktransfer and position
1055 //
1056 // /**
1057 // * @var int Does object support extrafields ? 0=No, 1=Yes
1058 // */
1059 // public $isextrafieldmanaged = 0;
1060 //
1061 // /**
1062 // * Constructor
1063 // *
1064 // * @param DoliDb $db Database handler
1065 // */
1066 // public function __construct(DoliDB $db)
1067 // {
1068 // $this->db = $db;
1069 // }
1070 //}
$object ref
Definition: info.php:78
Parent class of all other business classes (invoices, contracts, proposals, orders,...
line_order($renum=false, $rowidorder='ASC', $fk_parent_line=true)
Save a new position (field rang) for details lines.
fetch_thirdparty($force_thirdparty_id=0)
Load the third party of object, from id $this->socid or $this->fk_soc, into this->thirdparty.
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
getFieldList($alias='')
Function to concat keys of fields.
fetchCommon($id, $ref=null, $morewhere='')
Load object in memory from the database.
createCommon(User $user, $notrigger=false)
Create object into database.
deleteCommon(User $user, $notrigger=false, $forcechilddeletion=0)
Delete object in database.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
updateCommon(User $user, $notrigger=false)
Update object into database.
fetchLinesCommon($morewhere='')
Load object in memory from the database.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Class to manage Dolibarr database access.
Class for StockTransfer.
getValorisationTotale()
Used to get total PMP amount of all quantities of products of Stock Transfer.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter=array(), $filtermode='AND')
Load list of objects in memory from the database.
cmp($a, $b)
Used to sort lines by rank.
fetch($id, $ref=null)
Load object in memory from the database.
LibStatut($status, $mode=0)
Return the status.
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
fetchLines()
Load object lines in memory from the database.
validate($user, $notrigger=0)
Validate object.
create(User $user, $notrigger=false)
Create object into database.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
setDraft($user, $notrigger=0)
Set draft status.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
reopen($user, $notrigger=0)
Set back to validated status.
getLibStatut($mode=0)
Return label of the status.
info($id)
Load the info information in the object.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module.
__construct(DoliDB $db)
Constructor.
createFromClone(User $user, $fromid)
Clone an object into another one.
getLinesArray()
Create an array of lines.
cancel($user, $notrigger=0)
Set cancel status.
update(User $user, $notrigger=false)
Update object into database.
Class for StockTransferLine.
Class to manage Dolibarr users.
Definition: user.class.php:47
trait CommonIncoterm
Superclass for incoterm classes.
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:745
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.
Definition: files.lib.php:61
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.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
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.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
$conf db
API class for accounts.
Definition: inc.php:41