dolibarr  19.0.0-dev
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 
60 
66  protected $childtablesoncascade = array('stocktransfer_stocktransferline');
67 
73  public $ref_client;
74 
78  public $ref_customer;
79 
80 
84  public $picto = 'stock';
85 
86  public $date_prevue_depart;
87  public $date_prevue_arrivee;
88  public $date_reelle_depart;
89  public $date_reelle_arrivee;
90 
91 
92  const STATUS_DRAFT = 0;
93  const STATUS_VALIDATED = 1;
94  const STATUS_TRANSFERED = 2;
95  const STATUS_CLOSED = 3;
96 
97 
123  // BEGIN MODULEBUILDER PROPERTIES
127  public $fields=array(
128  'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"),
129  'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>'1', 'position'=>1, 'default'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"),
130  '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"),
131  'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>0, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth200'/*, 'help'=>"Help text"*/, 'showoncombobox'=>'1',),
132  'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>31, 'notnull'=>0, 'visible'=>3,),
133  '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,),
134  '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"*/,),
135  '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',),
136  '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'),
137  'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,),
138  'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0,),
139  'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,),
140  'date_prevue_depart' => array('type'=>'date', 'label'=>'DatePrevueDepart', 'enabled'=>'1', 'position'=>100, 'notnull'=>0, 'visible'=>1,),
141  'date_reelle_depart' => array('type'=>'date', 'label'=>'DateReelleDepart', 'enabled'=>'1', 'position'=>101, 'notnull'=>0, 'visible'=>5,),
142  'date_prevue_arrivee' => array('type'=>'date', 'label'=>'DatePrevueArrivee', 'enabled'=>'1', 'position'=>102, 'notnull'=>0, 'visible'=>1,),
143  'date_reelle_arrivee' => array('type'=>'date', 'label'=>'DateReelleArrivee', 'enabled'=>'1', 'position'=>103, 'notnull'=>0, 'visible'=>5,),
144  'lead_time_for_warning' => array('type'=>'integer', 'label'=>'LeadTimeForWarning', 'enabled'=>'1', 'position'=>200, 'default'=>0, 'notnull'=>0, 'visible'=>1),
145  'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2,),
146  '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',),
147  'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ChangedBy', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,),
148  'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,),
149  'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,),
150  'fk_incoterms' => array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-2, 'position'=>220),
151  'location_incoterms' => array('type'=>'varchar(255)', 'label'=>'IncotermLabel', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-2, 'position'=>225),
152  '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'),),
153  );
154  public $rowid;
155  public $ref;
156  public $label;
157  public $fk_soc;
158  public $fk_project;
159  public $description;
160  public $note_public;
161  public $note_private;
162  public $date_creation;
163  public $tms;
164  public $lead_time_for_warning;
165  public $fk_user_creat;
166  public $fk_user_modif;
167  public $import_key;
168  public $model_pdf;
169  public $status;
170  // END MODULEBUILDER PROPERTIES
171 
172 
178  public function __construct(DoliDB $db)
179  {
180  global $conf, $langs;
181 
182  $this->db = $db;
183  $this->origin_type = 'StockTransfer@product/stock/stocktransfer';
184 
185  if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) $this->fields['rowid']['visible'] = 0;
186  if (!isModEnabled('multicompany') && isset($this->fields['entity'])) $this->fields['entity']['enabled'] = 0;
187 
188  // Example to show how to set values of fields definition dynamically
189  /*if ($user->rights->stocktransfer->stocktransfer->read) {
190  $this->fields['myfield']['visible'] = 1;
191  $this->fields['myfield']['noteditable'] = 0;
192  }*/
193 
194  // Unset fields that are disabled
195  foreach ($this->fields as $key => $val) {
196  if (isset($val['enabled']) && empty($val['enabled'])) {
197  unset($this->fields[$key]);
198  }
199  }
200 
201  // Translate some data of arrayofkeyval
202  if (is_object($langs)) {
203  foreach ($this->fields as $key => $val) {
204  if (isset($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
205  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
206  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
207  }
208  }
209  }
210  }
211  }
212 
220  public function create(User $user, $notrigger = false)
221  {
222  $model_pdf = GETPOST('model');
223  if (!empty($model_pdf)) $this->model_pdf = $model_pdf;
224  $this->status = (int) $this->status;
225  if ($this->fk_warehouse_source <= 0) $this->fk_warehouse_source = 0;
226  if ($this->fk_warehouse_destination <= 0) $this->fk_warehouse_destination = 0;
227  return $this->createCommon($user, $notrigger);
228  }
229 
237  public function createFromClone(User $user, $fromid)
238  {
239  global $langs, $extrafields;
240  $error = 0;
241 
242  dol_syslog(__METHOD__, LOG_DEBUG);
243 
244  $object = new self($this->db);
245 
246  $this->db->begin();
247 
248  // Load source object
249  $result = $object->fetchCommon($fromid);
250  if ($result > 0 && !empty($object->table_element_line)) $object->fetchLines();
251 
252  // get lines so they will be clone
253  //foreach($this->lines as $line)
254  // $line->fetch_optionals();
255 
256  // Reset some properties
257  unset($object->id);
258  unset($object->fk_user_creat);
259  unset($object->import_key);
260  unset($object->date_prevue_depart);
261  unset($object->date_prevue_arrivee);
262  unset($object->date_reelle_depart);
263  unset($object->date_reelle_arrivee);
264 
265 
266  // Clear fields
267  $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default'];
268  $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
269  $object->status = self::STATUS_DRAFT;
270  // ...
271  // Clear extrafields that are unique
272  if (is_array($object->array_options) && count($object->array_options) > 0) {
273  $extrafields->fetch_name_optionals_label($this->table_element);
274  foreach ($object->array_options as $key => $option) {
275  $shortkey = preg_replace('/options_/', '', $key);
276  if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
277  //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
278  unset($object->array_options[$key]);
279  }
280  }
281  }
282 
283  // Create clone
284  $object->context['createfromclone'] = 'createfromclone';
285  $result = $object->createCommon($user);
286  if ($result < 0) {
287  $error++;
288  $this->error = $object->error;
289  $this->errors = $object->errors;
290  }
291 
292  if (!$error) {
293  // copy internal contacts
294  if ($this->copy_linked_contact($object, 'internal') < 0) {
295  $error++;
296  }
297  }
298 
299  if (!$error) {
300  // copy external contacts if same company
301  if (property_exists($this, 'socid') && $this->socid == $object->socid) {
302  if ($this->copy_linked_contact($object, 'external') < 0)
303  $error++;
304  }
305  }
306 
307  unset($object->context['createfromclone']);
308 
309  // End
310  if (!$error) {
311  $this->db->commit();
312  return $object;
313  } else {
314  $this->db->rollback();
315  return -1;
316  }
317  }
318 
326  public function fetch($id, $ref = null)
327  {
328  $result = $this->fetchCommon($id, $ref);
329  if ($result > 0 && !empty($this->table_element_line)) $this->fetchLines();
330  return $result;
331  }
332 
338  public function fetchLines()
339  {
340  require_once DOL_DOCUMENT_ROOT . '/product/stock/stocktransfer/class/stocktransferline.class.php';
341  $this->lines = array();
342 
343  $result = $this->fetchLinesCommon();
344  usort($this->lines, array('stocktransfer', 'cmp'));
345  return $result;
346  }
347 
355  public function cmp($a, $b)
356  {
357  if ($a->rang == $b->rang) {
358  return 0;
359  }
360  return ($a->rang < $b->rang) ? -1 : 1;
361  }
362 
368  public function getValorisationTotale()
369  {
370 
371  $total_pmp = 0;
372 
373  if (empty($this->lines)) $this->fetchLines();
374  if (!empty($this->lines)) {
375  foreach ($this->lines as $l) $total_pmp+= ($l->pmp * $l->qty);
376  }
377 
378  return $total_pmp;
379  }
380 
392  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
393  {
394  global $conf;
395 
396  dol_syslog(__METHOD__, LOG_DEBUG);
397 
398  $records = array();
399 
400  $sql = 'SELECT ';
401  $sql .= $this->getFieldList();
402  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
403  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
404  else $sql .= ' WHERE 1 = 1';
405  // Manage filter
406  $sqlwhere = array();
407  if (count($filter) > 0) {
408  foreach ($filter as $key => $value) {
409  if ($key == 't.rowid') {
410  $sqlwhere[] = $key.'='.$value;
411  } elseif (strpos($key, 'date') !== false) {
412  $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\'';
413  } elseif ($key == 'customsql') {
414  $sqlwhere[] = $value;
415  } else {
416  $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\'';
417  }
418  }
419  }
420  if (count($sqlwhere) > 0) {
421  $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")";
422  }
423 
424  if (!empty($sortfield)) {
425  $sql .= $this->db->order($sortfield, $sortorder);
426  }
427  if (!empty($limit)) {
428  $sql .= ' '.$this->db->plimit($limit, $offset);
429  }
430 
431  $resql = $this->db->query($sql);
432  if ($resql) {
433  $num = $this->db->num_rows($resql);
434  $i = 0;
435  while ($i < ($limit ? min($limit, $num) : $num)) {
436  $obj = $this->db->fetch_object($resql);
437 
438  $record = new self($this->db);
439  $record->setVarsFromFetchObj($obj);
440 
441  $records[$record->id] = $record;
442 
443  $i++;
444  }
445  $this->db->free($resql);
446 
447  return $records;
448  } else {
449  $this->errors[] = 'Error '.$this->db->lasterror();
450  dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
451 
452  return -1;
453  }
454  }
455 
463  public function update(User $user, $notrigger = false)
464  {
465  $this->tms = ''; // Will be done automatically because tms field is on update cascade
466  $res = $this->updateCommon($user, $notrigger);
467  if ($this->socid > 0 || $this->fk_soc > 0 && empty($this->thirdparty)) $this->fetch_thirdparty();
468  if (empty($this->socid) && empty($this->fk_soc)) unset($this->thirdparty);
469  return $res;
470  }
471 
479  public function delete(User $user, $notrigger = false)
480  {
481  if ($this->status > self::STATUS_VALIDATED) {
482  return 0;
483  } else {
484  return $this->deleteCommon($user, $notrigger);
485  }
486  }
487 
496  public function deleteLine(User $user, $idline, $notrigger = false)
497  {
498  if ($this->status < 0) {
499  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
500  return -2;
501  }
502 
503  $res = $this->deleteLineCommon($user, $idline, $notrigger);
504  $this->line_order(true);
505  return $res;
506  }
507 
508 
516  public function validate($user, $notrigger = 0)
517  {
518  global $conf, $langs;
519 
520  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
521 
522  $error = 0;
523 
524  // Protection
525  if ($this->status == self::STATUS_VALIDATED) {
526  dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
527  return 0;
528  }
529 
530  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer->write))
531  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer->stocktransfer_advance->validate))))
532  {
533  $this->error='NotEnoughPermissions';
534  dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
535  return -1;
536  }*/
537 
538  $now = dol_now();
539 
540  $this->db->begin();
541 
542  // Define new ref
543  if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
544  $num = $this->getNextNumRef();
545  } else {
546  $num = $this->ref;
547  }
548  $this->newref = $num;
549 
550  if (!empty($num)) {
551  // Validate
552  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
553  $sql .= " SET ref = '".$this->db->escape($num)."',";
554  $sql .= " status = ".self::STATUS_VALIDATED;
555  if (!empty($this->fields['date_validation'])) $sql .= ", date_validation = '".$this->db->idate($now)."',";
556  if (!empty($this->fields['fk_user_valid'])) $sql .= ", fk_user_valid = ".((int) $user->id);
557  $sql .= " WHERE rowid = ".((int) $this->id);
558 
559  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
560  $resql = $this->db->query($sql);
561  if (!$resql) {
562  dol_print_error($this->db);
563  $this->error = $this->db->lasterror();
564  $error++;
565  }
566 
567  if (!$error && !$notrigger) {
568  // Call trigger
569  $result = $this->call_trigger('STOCKTRANSFER_VALIDATE', $user);
570  if ($result < 0) $error++;
571  // End call triggers
572  }
573  }
574 
575  if (!$error) {
576  $this->oldref = $this->ref;
577 
578  // Rename directory if dir was a temporary ref
579  if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
580  // Now we rename also files into index
581  $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)."'";
582  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransfer/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity);
583  $resql = $this->db->query($sql);
584  if (!$resql) { $error++; $this->error = $this->db->lasterror(); }
585 
586  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
587  $oldref = dol_sanitizeFileName($this->ref);
588  $newref = dol_sanitizeFileName($num);
589  $dirsource = $conf->stocktransfer->dir_output.'/stocktransfer/'.$oldref;
590  $dirdest = $conf->stocktransfer->dir_output.'/stocktransfer/'.$newref;
591  if (!$error && file_exists($dirsource)) {
592  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
593 
594  if (@rename($dirsource, $dirdest)) {
595  dol_syslog("Rename ok");
596  // Rename docs starting with $oldref with $newref
597  $listoffiles = dol_dir_list($conf->stocktransfer->dir_output.'/stocktransfer/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
598  foreach ($listoffiles as $fileentry) {
599  $dirsource = $fileentry['name'];
600  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
601  $dirsource = $fileentry['path'].'/'.$dirsource;
602  $dirdest = $fileentry['path'].'/'.$dirdest;
603  @rename($dirsource, $dirdest);
604  }
605  }
606  }
607  }
608  }
609 
610  // Set new ref and current status
611  if (!$error) {
612  $this->ref = $num;
613  $this->status = self::STATUS_VALIDATED;
614  }
615 
616  if (!$error) {
617  $this->db->commit();
618  return 1;
619  } else {
620  $this->db->rollback();
621  return -1;
622  }
623  }
624 
625 
633  public function setDraft($user, $notrigger = 0)
634  {
635  // Protection
636  if ($this->status <= self::STATUS_DRAFT) {
637  return 0;
638  }
639 
640  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
641  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
642  {
643  $this->error='Permission denied';
644  return -1;
645  }*/
646 
647  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'STOCKTRANSFER_UNVALIDATE');
648  }
649 
657  public function cancel($user, $notrigger = 0)
658  {
659  // Protection
660  if ($this->status != self::STATUS_VALIDATED) {
661  return 0;
662  }
663 
664  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
665  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
666  {
667  $this->error='Permission denied';
668  return -1;
669  }*/
670 
671  return $this->setStatusCommon($user, self::STATUS_CLOSED, $notrigger, 'STOCKTRANSFER_CLOSE');
672  }
673 
681  public function reopen($user, $notrigger = 0)
682  {
683  // Protection
684  if ($this->status != self::STATUS_CLOSED) {
685  return 0;
686  }
687 
688  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
689  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
690  {
691  $this->error='Permission denied';
692  return -1;
693  }*/
694 
695  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'STOCKTRANSFER_REOPEN');
696  }
697 
708  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
709  {
710  global $conf, $langs, $hookmanager;
711 
712  if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips
713 
714  $result = '';
715 
716  $label = '<u>'.$langs->trans("StockTransfer").'</u>';
717  $label .= '<br>';
718  $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
719  if (isset($this->status)) {
720  $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
721  }
722 
723  $url = dol_buildpath('/product/stock/stocktransfer/stocktransfer_card.php', 1).'?id='.$this->id;
724 
725  if ($option != 'nolink') {
726  // Add param to save lastsearch_values or not
727  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
728  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1;
729  if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1';
730  }
731 
732  $linkclose = '';
733  if (empty($notooltip)) {
734  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
735  $label = $langs->trans("ShowStockTransfer");
736  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
737  }
738  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
739  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
740  } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
741 
742  $linkstart = '<a href="'.$url.'"';
743  $linkstart .= $linkclose.'>';
744  $linkend = '</a>';
745 
746  $result .= $linkstart;
747 
748  if (empty($this->showphoto_on_popup)) {
749  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);
750  } else {
751  if ($withpicto) {
752  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
753 
754  list($class, $module) = explode('@', $this->picto);
755  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
756  $filearray = dol_dir_list($upload_dir, "files");
757  $filename = $filearray[0]['name'];
758  if (!empty($filename)) {
759  $pospoint = strpos($filearray[0]['name'], '.');
760 
761  $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
762  if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
763  $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>';
764  } else {
765  $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>';
766  }
767 
768  $result .= '</div>';
769  } else {
770  $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);
771  }
772  }
773  }
774 
775  if ($withpicto != 2) $result .= $this->ref;
776 
777  $result .= $linkend;
778  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
779 
780  global $action, $hookmanager;
781  $hookmanager->initHooks(array('stocktransferdao'));
782  $parameters = array('id'=>$this->id, 'getnomurl'=>$result);
783  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
784  if ($reshook > 0) $result = $hookmanager->resPrint;
785  else $result .= $hookmanager->resPrint;
786 
787  return $result;
788  }
789 
796  public function getLibStatut($mode = 0)
797  {
798  return $this->LibStatut($this->status, $mode);
799  }
800 
801  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
809  public function LibStatut($status, $mode = 0)
810  {
811  // phpcs:enable
812  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
813  global $langs;
814  //$langs->load("stocktransfer@stocktransfer");
815  $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft');
816  $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated');
817  $this->labelStatus[self::STATUS_TRANSFERED] = $langs->trans('StockStransferDecremented');
818  $this->labelStatus[self::STATUS_CLOSED] = $langs->trans('StockStransferIncremented');
819  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft');
820  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Validated');
821  $this->labelStatusShort[self::STATUS_TRANSFERED] = $langs->trans('StockStransferDecremented');
822  $this->labelStatusShort[self::STATUS_CLOSED] = $langs->trans('StockStransferIncremented');
823  }
824 
825  $statusType = 'status'.$status;
826  //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
827  if ($status == self::STATUS_CLOSED) $statusType = 'status6';
828 
829  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
830  }
831 
838  public function info($id)
839  {
840  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
841  $sql .= ' fk_user_creat, fk_user_modif';
842  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
843  $sql .= ' WHERE t.rowid = '.((int) $id);
844  $result = $this->db->query($sql);
845  if ($result) {
846  if ($this->db->num_rows($result)) {
847  $obj = $this->db->fetch_object($result);
848  $this->id = $obj->rowid;
849 
850  $this->user_creation_id = $obj->fk_user_creat;
851  $this->user_modification_id = $obj->fk_user_modif;
852  $this->date_creation = $this->db->jdate($obj->datec);
853  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
854  }
855 
856  $this->db->free($result);
857  } else {
858  dol_print_error($this->db);
859  }
860  }
861 
868  public function initAsSpecimen()
869  {
870  $this->initAsSpecimenCommon();
871  }
872 
878  public function getLinesArray()
879  {
880  $this->lines = array();
881 
882  $objectline = new StockTransferLine($this->db);
883  $result = $objectline->fetchAll('ASC', 'rang', 0, 0, array('customsql'=>'fk_stocktransfer = '.$this->id));
884 
885  if (is_numeric($result)) {
886  $this->error = $objectline->error;
887  $this->errors = $objectline->errors;
888  return $result;
889  } else {
890  $this->lines = $result;
891  return $this->lines;
892  }
893  }
894 
900  public function getNextNumRef()
901  {
902  global $langs, $conf;
903  $langs->load("stocks");
904 
905  if (empty($conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON)) {
906  $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON = 'mod_stocktransfer_standard';
907  }
908 
909  if (!empty($conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON)) {
910  $mybool = false;
911 
912  $file = $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON.".php";
913  $classname = $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON;
914 
915  // Include file with class
916  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
917  foreach ($dirmodels as $reldir) {
918  $dir = dol_buildpath($reldir."core/modules/stocktransfer/");
919 
920  // Load file with numbering class (if found)
921  $mybool |= @include_once $dir.$file;
922  }
923 
924  if ($mybool === false) {
925  dol_print_error('', "Failed to include file ".$file);
926  return '';
927  }
928 
929  if (class_exists($classname)) {
930  $obj = new $classname();
931  $numref = $obj->getNextValue($this);
932 
933  if ($numref != '' && $numref != '-1') {
934  return $numref;
935  } else {
936  $this->error = $obj->error;
937  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
938  return "";
939  }
940  } else {
941  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
942  return "";
943  }
944  } else {
945  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
946  return "";
947  }
948  }
949 
961  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
962  {
963  global $conf, $langs;
964 
965  $result = 0;
966  $includedocgeneration = 1;
967 
968  $langs->load("stocks");
969 
970  if (!dol_strlen($modele)) {
971  $modele = 'eagle';
972 
973  if ($this->modelpdf) {
974  $modele = $this->modelpdf;
975  } elseif (!empty($conf->global->STOCKTRANSFER_ADDON_PDF)) {
976  $modele = $conf->global->STOCKTRANSFER_ADDON_PDF;
977  }
978  }
979 
980  $modelpath = "core/modules/stocktransfer/doc/";
981 
982  if ($includedocgeneration) {
983  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
984  }
985 
986  return $result;
987  }
988 
996  public function doScheduledJob()
997  {
998  global $conf, $langs;
999 
1000  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1001 
1002  $error = 0;
1003  $this->output = '';
1004  $this->error = '';
1005 
1006  dol_syslog(__METHOD__, LOG_DEBUG);
1007 
1008  $now = dol_now();
1009 
1010  $this->db->begin();
1011 
1012  // ...
1013 
1014  $this->db->commit();
1015 
1016  return $error;
1017  }
1018 }
1019 
1023 //class StockTransferLine
1024 //{
1025 // // To complete with content of an object StockTransferLine
1026 // // We should have a field rowid, fk_stocktransfer and position
1027 //
1028 // /**
1029 // * @var int Does object support extrafields ? 0=No, 1=Yes
1030 // */
1031 // public $isextrafieldmanaged = 0;
1032 //
1033 // /**
1034 // * Constructor
1035 // *
1036 // * @param DoliDb $db Database handler
1037 // */
1038 // public function __construct(DoliDB $db)
1039 // {
1040 // $this->db = $db;
1041 // }
1042 //}
$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.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
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.
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='')
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:48
trait CommonIncoterm
Superclass for incoterm classes.
if(isModEnabled('facture') && $user->hasRight('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') && $user->hasRight('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)) $sql
Social contributions to pay.
Definition: index.php:746
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:62
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.
getDolGlobalString($key, $default='')
Return 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.