dolibarr  20.0.0-beta
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-2024 Frédéric France <frederic.france@free.fr>
5  * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <https://www.gnu.org/licenses/>.
19  */
20 
27 // Put here all includes required by your class file
28 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
29 require_once DOL_DOCUMENT_ROOT.'/core/class/commonincoterm.class.php';
30 
31 //require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
32 //require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
33 
38 {
39  use CommonIncoterm;
43  public $element = 'stocktransfer';
44 
48  public $table_element = 'stocktransfer_stocktransfer';
49 
53  public $table_element_line = 'stocktransfer_stocktransferline';
54 
60  protected $childtablesoncascade = array('stocktransfer_stocktransferline');
61 
67  public $ref_client;
68 
72  public $ref_customer;
73 
74 
78  public $picto = 'stock';
79 
80  public $date_prevue_depart;
81  public $date_prevue_arrivee;
82  public $date_reelle_depart;
83  public $date_reelle_arrivee;
84  public $origin_type;
85 
86 
87  const STATUS_DRAFT = 0;
88  const STATUS_VALIDATED = 1;
89  const STATUS_TRANSFERED = 2;
90  const STATUS_CLOSED = 3;
91 
92 
118  // BEGIN MODULEBUILDER PROPERTIES
122  public $fields = array(
123  'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'comment' => "Id"),
124  'entity' => array('type' => 'integer', 'label' => 'Entity', 'enabled' => 1, 'position' => 1, 'default' => '1', 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'comment' => "Id"),
125  '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"),
126  'label' => array('type' => 'varchar(255)', 'label' => 'Label', 'enabled' => 1, 'position' => 30, 'notnull' => 0, 'visible' => 1, 'searchall' => 1, 'showoncombobox' => 1, 'css' => 'minwidth100', 'csslist' => 'tdoverflowmax125', 'autofocusoncreate' => 1),
127  'description' => array('type' => 'text', 'label' => 'Description', 'enabled' => 1, 'position' => 31, 'notnull' => 0, 'visible' => 3,),
128  '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, 'picto' => 'project', 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax125'),
129  '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"*/, 'picto' => 'company', 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax125'),
130  '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', 'picto' => 'stock', 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax150'),
131  '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', 'picto' => 'stock', 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax150'),
132  'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 61, 'notnull' => 0, 'visible' => 0,),
133  'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 62, 'notnull' => 0, 'visible' => 0,),
134  'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 500, 'notnull' => 1, 'visible' => -2,),
135  'date_prevue_depart' => array('type' => 'date', 'label' => 'DatePrevueDepart', 'enabled' => 1, 'position' => 100, 'notnull' => 0, 'visible' => 1,),
136  'date_reelle_depart' => array('type' => 'date', 'label' => 'DateReelleDepart', 'enabled' => 1, 'position' => 101, 'notnull' => 0, 'visible' => 5,),
137  'date_prevue_arrivee' => array('type' => 'date', 'label' => 'DatePrevueArrivee', 'enabled' => 1, 'position' => 102, 'notnull' => 0, 'visible' => 1,),
138  'date_reelle_arrivee' => array('type' => 'date', 'label' => 'DateReelleArrivee', 'enabled' => 1, 'position' => 103, 'notnull' => 0, 'visible' => 5,),
139  'lead_time_for_warning' => array('type' => 'integer', 'label' => 'LeadTimeForWarning', 'enabled' => 1, 'position' => 200, 'default' => '0', 'notnull' => 0, 'visible' => 1),
140  'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'position' => 501, 'notnull' => 0, 'visible' => -2,),
141  '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',),
142  'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'ChangedBy', 'enabled' => 1, 'position' => 511, 'notnull' => -1, 'visible' => -2,),
143  'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'position' => 1000, 'notnull' => -1, 'visible' => -2,),
144  'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'position' => 1010, 'notnull' => -1, 'visible' => 0,),
145  'fk_incoterms' => array('type' => 'integer', 'label' => 'IncotermCode', 'enabled' => '$conf->incoterm->enabled', 'visible' => -2, 'position' => 220),
146  'location_incoterms' => array('type' => 'varchar(255)', 'label' => 'IncotermLabel', 'enabled' => '$conf->incoterm->enabled', 'visible' => -2, 'position' => 225),
147  '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'),),
148  );
149  public $rowid;
150  public $ref;
151  public $label;
152  public $socid;
153  public $fk_soc; // deprecated
154  public $fk_project;
155  public $description;
156  public $note_public;
157  public $note_private;
158  public $date_creation;
159  public $lead_time_for_warning;
160  public $fk_user_creat;
161  public $fk_user_modif;
162  public $import_key;
163  public $model_pdf;
164  public $status;
165 
169  public $lines;
170 
171  public $fk_warehouse_source;
172  public $fk_warehouse_destination;
173  // END MODULEBUILDER PROPERTIES
174 
175 
181  public function __construct(DoliDB $db)
182  {
183  global $conf, $langs;
184 
185  $this->db = $db;
186 
187  $this->ismultientitymanaged = 0;
188  $this->isextrafieldmanaged = 1;
189 
190  $this->origin_type = 'StockTransfer@product/stock/stocktransfer';
191 
192  if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
193  $this->fields['rowid']['visible'] = 0;
194  }
195  if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
196  $this->fields['entity']['enabled'] = 0;
197  }
198 
199  // Example to show how to set values of fields definition dynamically
200  /*if ($user->rights->stocktransfer->stocktransfer->read) {
201  $this->fields['myfield']['visible'] = 1;
202  $this->fields['myfield']['noteditable'] = 0;
203  }*/
204 
205  // Unset fields that are disabled
206  foreach ($this->fields as $key => $val) {
207  if (isset($val['enabled']) && empty($val['enabled'])) {
208  unset($this->fields[$key]);
209  }
210  }
211 
212  // Translate some data of arrayofkeyval
213  if (is_object($langs)) {
214  foreach ($this->fields as $key => $val) {
215  if (isset($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
216  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
217  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
218  }
219  }
220  }
221  }
222  }
223 
231  public function create(User $user, $notrigger = 0)
232  {
233  $this->status = (int) $this->status;
234  if ($this->fk_warehouse_source <= 0) {
235  $this->fk_warehouse_source = 0;
236  }
237  if ($this->fk_warehouse_destination <= 0) {
238  $this->fk_warehouse_destination = 0;
239  }
240  return $this->createCommon($user, $notrigger);
241  }
242 
250  public function createFromClone(User $user, $fromid)
251  {
252  global $langs, $extrafields;
253  $error = 0;
254 
255  dol_syslog(__METHOD__, LOG_DEBUG);
256 
257  $object = new self($this->db);
258 
259  $this->db->begin();
260 
261  // Load source object
262  $result = $object->fetchCommon($fromid);
263  if ($result > 0 && !empty($object->table_element_line)) {
264  $object->fetchLines();
265  }
266 
267  // get lines so they will be clone
268  //foreach($this->lines as $line)
269  // $line->fetch_optionals();
270 
271  // Reset some properties
272  unset($object->id);
273  unset($object->fk_user_creat);
274  unset($object->import_key);
275  unset($object->date_prevue_depart);
276  unset($object->date_prevue_arrivee);
277  unset($object->date_reelle_depart);
278  unset($object->date_reelle_arrivee);
279 
280 
281  // Clear fields
282  $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default'];
283  $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
284  $object->status = self::STATUS_DRAFT;
285  // ...
286  // Clear extrafields that are unique
287  if (is_array($object->array_options) && count($object->array_options) > 0) {
288  $extrafields->fetch_name_optionals_label($this->table_element);
289  foreach ($object->array_options as $key => $option) {
290  $shortkey = preg_replace('/options_/', '', $key);
291  if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
292  //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
293  unset($object->array_options[$key]);
294  }
295  }
296  }
297 
298  // Create clone
299  $object->context['createfromclone'] = 'createfromclone';
300  $result = $object->createCommon($user);
301  if ($result < 0) {
302  $error++;
303  $this->error = $object->error;
304  $this->errors = $object->errors;
305  }
306 
307  if (!$error) {
308  // copy internal contacts
309  if ($this->copy_linked_contact($object, 'internal') < 0) {
310  $error++;
311  }
312  }
313 
314  if (!$error) {
315  // copy external contacts if same company
316  if (property_exists($this, 'socid') && $this->socid == $object->socid) {
317  if ($this->copy_linked_contact($object, 'external') < 0) {
318  $error++;
319  }
320  }
321  }
322 
323  unset($object->context['createfromclone']);
324 
325  // End
326  if (!$error) {
327  $this->db->commit();
328  return $object;
329  } else {
330  $this->db->rollback();
331  return -1;
332  }
333  }
334 
342  public function fetch($id, $ref = null)
343  {
344  $result = $this->fetchCommon($id, $ref);
345 
346  $this->socid = $this->fk_soc;
347 
348  if ($result > 0 && !empty($this->table_element_line)) {
349  $this->fetchLines();
350  }
351  return $result;
352  }
353 
359  public function fetchLines()
360  {
361  require_once DOL_DOCUMENT_ROOT . '/product/stock/stocktransfer/class/stocktransferline.class.php';
362  $this->lines = array();
363 
364  $result = $this->fetchLinesCommon();
365  usort($this->lines, array('StockTransfer', 'stocktransferCmpRank'));
366  return $result;
367  }
368 
376  public static function stocktransferCmpRank($a, $b)
377  {
378  if ($a->rang == $b->rang) {
379  return 0;
380  }
381  return ($a->rang < $b->rang) ? -1 : 1;
382  }
383 
389  public function getValorisationTotale()
390  {
391  $total_pmp = 0;
392 
393  if (empty($this->lines)) {
394  $this->fetchLines();
395  }
396  if (!empty($this->lines)) {
397  foreach ($this->lines as $l) {
398  $total_pmp += ($l->pmp * $l->qty);
399  }
400  }
401 
402  return $total_pmp;
403  }
404 
417  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
418  {
419  dol_syslog(__METHOD__, LOG_DEBUG);
420 
421  $records = array();
422 
423  $sql = 'SELECT ';
424  $sql .= $this->getFieldList();
425  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
426  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
427  $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
428  } else {
429  $sql .= ' WHERE 1 = 1';
430  }
431 
432  // Manage filter
433  $errormessage = '';
434  $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
435  if ($errormessage) {
436  $this->errors[] = $errormessage;
437  dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
438  return -1;
439  }
440 
441  if (!empty($sortfield)) {
442  $sql .= $this->db->order($sortfield, $sortorder);
443  }
444  if (!empty($limit)) {
445  $sql .= ' '.$this->db->plimit($limit, $offset);
446  }
447 
448  $resql = $this->db->query($sql);
449  if ($resql) {
450  $num = $this->db->num_rows($resql);
451  $i = 0;
452  while ($i < ($limit ? min($limit, $num) : $num)) {
453  $obj = $this->db->fetch_object($resql);
454 
455  $record = new self($this->db);
456  $record->setVarsFromFetchObj($obj);
457 
458  $records[$record->id] = $record;
459 
460  $i++;
461  }
462  $this->db->free($resql);
463 
464  return $records;
465  } else {
466  $this->errors[] = 'Error '.$this->db->lasterror();
467  dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
468 
469  return -1;
470  }
471  }
472 
480  public function update(User $user, $notrigger = 0)
481  {
482  $this->tms = 0; // Will be done automatically because tms field is on update cascade
483  $res = $this->updateCommon($user, $notrigger);
484  if (($this->socid > 0 || $this->fk_soc > 0) && empty($this->thirdparty)) {
485  $this->fetch_thirdparty();
486  }
487  if (empty($this->socid) && empty($this->fk_soc)) {
488  unset($this->thirdparty);
489  }
490  return $res;
491  }
492 
500  public function delete(User $user, $notrigger = 0)
501  {
502  if ($this->status > self::STATUS_VALIDATED) {
503  return 0;
504  } else {
505  return $this->deleteCommon($user, $notrigger);
506  }
507  }
508 
517  public function deleteLine(User $user, $idline, $notrigger = 0)
518  {
519  if ($this->status < 0) {
520  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
521  return -2;
522  }
523 
524  $res = $this->deleteLineCommon($user, $idline, $notrigger);
525  $this->line_order(true);
526  return $res;
527  }
528 
529 
537  public function validate($user, $notrigger = 0)
538  {
539  global $conf, $langs;
540 
541  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
542 
543  $error = 0;
544 
545  // Protection
546  if ($this->status == self::STATUS_VALIDATED) {
547  dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
548  return 0;
549  }
550 
551  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer->write))
552  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer->stocktransfer_advance->validate))))
553  {
554  $this->error='NotEnoughPermissions';
555  dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
556  return -1;
557  }*/
558 
559  $now = dol_now();
560 
561  $this->db->begin();
562 
563  // Define new ref
564  if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
565  $num = $this->getNextNumRef();
566  } else {
567  $num = $this->ref;
568  }
569  $this->newref = $num;
570 
571  if (!empty($num)) {
572  // Validate
573  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
574  $sql .= " SET ref = '".$this->db->escape($num)."',";
575  $sql .= " status = ".self::STATUS_VALIDATED;
576  if (!empty($this->fields['date_validation'])) {
577  $sql .= ", date_validation = '".$this->db->idate($now)."',";
578  }
579  if (!empty($this->fields['fk_user_valid'])) {
580  $sql .= ", fk_user_valid = ".((int) $user->id);
581  }
582  $sql .= " WHERE rowid = ".((int) $this->id);
583 
584  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
585  $resql = $this->db->query($sql);
586  if (!$resql) {
587  dol_print_error($this->db);
588  $this->error = $this->db->lasterror();
589  $error++;
590  }
591 
592  if (!$error && !$notrigger) {
593  // Call trigger
594  $result = $this->call_trigger('STOCKTRANSFER_VALIDATE', $user);
595  if ($result < 0) {
596  $error++;
597  }
598  // End call triggers
599  }
600  }
601 
602  if (!$error) {
603  $this->oldref = $this->ref;
604 
605  // Rename directory if dir was a temporary ref
606  if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
607  // Now we rename also files into index
608  $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)."'";
609  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransfer/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity);
610  $resql = $this->db->query($sql);
611  if (!$resql) {
612  $error++;
613  $this->error = $this->db->lasterror();
614  }
615  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'stocktransfer/".$this->db->escape($this->newref)."'";
616  $sql .= " WHERE filepath = 'stocktransfer/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
617  $resql = $this->db->query($sql);
618  if (!$resql) {
619  $error++;
620  $this->error = $this->db->lasterror();
621  }
622 
623  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
624  $oldref = dol_sanitizeFileName($this->ref);
625  $newref = dol_sanitizeFileName($num);
626  $dirsource = $conf->stocktransfer->dir_output.'/stocktransfer/'.$oldref;
627  $dirdest = $conf->stocktransfer->dir_output.'/stocktransfer/'.$newref;
628  if (!$error && file_exists($dirsource)) {
629  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
630 
631  if (@rename($dirsource, $dirdest)) {
632  dol_syslog("Rename ok");
633  // Rename docs starting with $oldref with $newref
634  $listoffiles = dol_dir_list($conf->stocktransfer->dir_output.'/stocktransfer/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
635  foreach ($listoffiles as $fileentry) {
636  $dirsource = $fileentry['name'];
637  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
638  $dirsource = $fileentry['path'].'/'.$dirsource;
639  $dirdest = $fileentry['path'].'/'.$dirdest;
640  @rename($dirsource, $dirdest);
641  }
642  }
643  }
644  }
645  }
646 
647  // Set new ref and current status
648  if (!$error) {
649  $this->ref = $num;
650  $this->status = self::STATUS_VALIDATED;
651  }
652 
653  if (!$error) {
654  $this->db->commit();
655  return 1;
656  } else {
657  $this->db->rollback();
658  return -1;
659  }
660  }
661 
662 
670  public function setDraft($user, $notrigger = 0)
671  {
672  // Protection
673  if ($this->status <= self::STATUS_DRAFT) {
674  return 0;
675  }
676 
677  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
678  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
679  {
680  $this->error='Permission denied';
681  return -1;
682  }*/
683 
684  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'STOCKTRANSFER_UNVALIDATE');
685  }
686 
694  public function cancel($user, $notrigger = 0)
695  {
696  // Protection
697  if ($this->status != self::STATUS_VALIDATED) {
698  return 0;
699  }
700 
701  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
702  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
703  {
704  $this->error='Permission denied';
705  return -1;
706  }*/
707 
708  return $this->setStatusCommon($user, self::STATUS_CLOSED, $notrigger, 'STOCKTRANSFER_CLOSE');
709  }
710 
718  public function reopen($user, $notrigger = 0)
719  {
720  // Protection
721  if ($this->status != self::STATUS_CLOSED) {
722  return 0;
723  }
724 
725  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
726  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
727  {
728  $this->error='Permission denied';
729  return -1;
730  }*/
731 
732  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'STOCKTRANSFER_REOPEN');
733  }
734 
745  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
746  {
747  global $conf, $langs, $hookmanager;
748 
749  if (!empty($conf->dol_no_mouse_hover)) {
750  $notooltip = 1;
751  } // Force disable tooltips
752 
753  $result = '';
754 
755  $label = '<u>'.$langs->trans("StockTransfer").'</u>';
756  $label .= '<br>';
757  $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
758  if (isset($this->status)) {
759  $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
760  }
761 
762  $url = dol_buildpath('/product/stock/stocktransfer/stocktransfer_card.php', 1).'?id='.$this->id;
763 
764  if ($option != 'nolink') {
765  // Add param to save lastsearch_values or not
766  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
767  if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
768  $add_save_lastsearch_values = 1;
769  }
770  if ($add_save_lastsearch_values) {
771  $url .= '&save_lastsearch_values=1';
772  }
773  }
774 
775  $linkclose = '';
776  if (empty($notooltip)) {
777  if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
778  $label = $langs->trans("ShowStockTransfer");
779  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
780  }
781  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
782  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
783  } else {
784  $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
785  }
786 
787  $linkstart = '<a href="'.$url.'"';
788  $linkstart .= $linkclose.'>';
789  $linkend = '</a>';
790 
791  $result .= $linkstart;
792 
793  if (empty($this->showphoto_on_popup)) {
794  if ($withpicto) {
795  $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);
796  }
797  } else {
798  if ($withpicto) {
799  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
800 
801  list($class, $module) = explode('@', $this->picto);
802  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
803  $filearray = dol_dir_list($upload_dir, "files");
804  $filename = $filearray[0]['name'];
805  if (!empty($filename)) {
806  $pospoint = strpos($filearray[0]['name'], '.');
807 
808  $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
809  if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
810  $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>';
811  } else {
812  $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><img class="photouserphoto userphoto" alt="No photo" border="0" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$module.'&entity='.$conf->entity.'&file='.urlencode($pathtophoto).'"></div>';
813  }
814 
815  $result .= '</div>';
816  } else {
817  $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
818  }
819  }
820  }
821 
822  if ($withpicto != 2) {
823  $result .= $this->ref;
824  }
825 
826  $result .= $linkend;
827  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
828 
829  global $action, $hookmanager;
830  $hookmanager->initHooks(array('stocktransferdao'));
831  $parameters = array('id' => $this->id, 'getnomurl' => $result);
832  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
833  if ($reshook > 0) {
834  $result = $hookmanager->resPrint;
835  } else {
836  $result .= $hookmanager->resPrint;
837  }
838 
839  return $result;
840  }
841 
848  public function getLibStatut($mode = 0)
849  {
850  return $this->LibStatut($this->status, $mode);
851  }
852 
853  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
861  public function LibStatut($status, $mode = 0)
862  {
863  // phpcs:enable
864  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
865  global $langs;
866  //$langs->load("stocktransfer@stocktransfer");
867  $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft');
868  $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated');
869  $this->labelStatus[self::STATUS_TRANSFERED] = $langs->trans('StockStransferDecremented');
870  $this->labelStatus[self::STATUS_CLOSED] = $langs->trans('StockStransferIncremented');
871  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft');
872  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Validated');
873  $this->labelStatusShort[self::STATUS_TRANSFERED] = $langs->trans('StockStransferDecremented');
874  $this->labelStatusShort[self::STATUS_CLOSED] = $langs->trans('StockStransferIncremented');
875  }
876 
877  $statusType = 'status'.$status;
878  //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
879  if ($status == self::STATUS_CLOSED) {
880  $statusType = 'status6';
881  }
882 
883  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
884  }
885 
892  public function info($id)
893  {
894  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
895  $sql .= ' fk_user_creat, fk_user_modif';
896  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
897  $sql .= ' WHERE t.rowid = '.((int) $id);
898  $result = $this->db->query($sql);
899  if ($result) {
900  if ($this->db->num_rows($result)) {
901  $obj = $this->db->fetch_object($result);
902  $this->id = $obj->rowid;
903 
904  $this->user_creation_id = $obj->fk_user_creat;
905  $this->user_modification_id = $obj->fk_user_modif;
906  $this->date_creation = $this->db->jdate($obj->datec);
907  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
908  }
909 
910  $this->db->free($result);
911  } else {
912  dol_print_error($this->db);
913  }
914  }
915 
922  public function initAsSpecimen()
923  {
924  return $this->initAsSpecimenCommon();
925  }
926 
932  public function getLinesArray()
933  {
934  $this->lines = array();
935 
936  $objectline = new StockTransferLine($this->db);
937  $result = $objectline->fetchAll('ASC', 'rang', 0, 0, "(fk_stocktransfer:=:".((int) $this->id).")");
938 
939  if (is_numeric($result)) {
940  $this->error = $objectline->error;
941  $this->errors = $objectline->errors;
942  return $result;
943  } else {
944  $this->lines = $result;
945  return $this->lines;
946  }
947  }
948 
954  public function getNextNumRef()
955  {
956  global $langs, $conf;
957  $langs->load("stocks");
958 
959  if (!getDolGlobalString('STOCKTRANSFER_STOCKTRANSFER_ADDON')) {
960  $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON = 'mod_stocktransfer_standard';
961  }
962 
963  if (getDolGlobalString('STOCKTRANSFER_STOCKTRANSFER_ADDON')) {
964  $mybool = false;
965 
966  $file = getDolGlobalString('STOCKTRANSFER_STOCKTRANSFER_ADDON') . ".php";
967  $classname = getDolGlobalString('STOCKTRANSFER_STOCKTRANSFER_ADDON');
968 
969  // Include file with class
970  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
971  foreach ($dirmodels as $reldir) {
972  $dir = dol_buildpath($reldir."core/modules/stocktransfer/");
973 
974  // Load file with numbering class (if found)
975  $mybool = ((bool) @include_once $dir.$file) || $mybool;
976  }
977 
978  if ($mybool === false) {
979  dol_print_error(null, "Failed to include file ".$file);
980  return '';
981  }
982 
983  if (class_exists($classname)) {
984  $obj = new $classname();
985  $numref = $obj->getNextValue($this);
986 
987  if ($numref != '' && $numref != '-1') {
988  return $numref;
989  } else {
990  $this->error = $obj->error;
991  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
992  return "";
993  }
994  } else {
995  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
996  return "";
997  }
998  } else {
999  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1000  return "";
1001  }
1002  }
1003 
1015  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1016  {
1017  global $conf, $langs;
1018 
1019  $result = 0;
1020  $includedocgeneration = 1;
1021 
1022  $langs->load("stocks");
1023 
1024  if (!dol_strlen($modele)) {
1025  $modele = 'eagle';
1026 
1027  if ($this->model_pdf) {
1028  $modele = $this->model_pdf;
1029  } elseif (getDolGlobalString('STOCKTRANSFER_ADDON_PDF')) {
1030  $modele = getDolGlobalString('STOCKTRANSFER_ADDON_PDF');
1031  }
1032  }
1033 
1034  $modelpath = "core/modules/stocktransfer/doc/";
1035 
1036  if ($includedocgeneration) {
1037  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1038  }
1039 
1040  return $result;
1041  }
1042 
1050  public function doScheduledJob()
1051  {
1052  global $conf, $langs;
1053 
1054  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1055 
1056  $error = 0;
1057  $this->output = '';
1058  $this->error = '';
1059 
1060  dol_syslog(__METHOD__, LOG_DEBUG);
1061 
1062  $now = dol_now();
1063 
1064  $this->db->begin();
1065 
1066  // ...
1067 
1068  $this->db->commit();
1069 
1070  return $error;
1071  }
1072 }
if($user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition: card.php:58
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition: security.php:607
$object ref
Definition: info.php:79
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.
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.
fetch_thirdparty($force_thirdparty_id=0)
Load the third party of object, from id $this->socid or $this->fk_soc, into this->thirdparty.
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.
Class to manage Dolibarr database access.
Class for StockTransfer.
getValorisationTotale()
Used to get total PMP amount of all quantities of products of Stock Transfer.
update(User $user, $notrigger=0)
Update object into database.
static stocktransferCmpRank($a, $b)
Used to sort lines by rank.
fetch($id, $ref=null)
Load object in memory from the database.
deleteLine(User $user, $idline, $notrigger=0)
Delete a line of object in database.
LibStatut($status, $mode=0)
Return the status.
fetchLines()
Load object lines in memory from the database.
validate($user, $notrigger=0)
Validate object.
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.
create(User $user, $notrigger=0)
Create object into database.
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.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter='', $filtermode='AND')
Load list of objects in memory from the database.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionally 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.
Class for StockTransferLine.
Class to manage Dolibarr users.
Definition: user.class.php:50
trait CommonIncoterm
Superclass for incoterm classes.
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('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') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:745
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.
Definition: files.lib.php:63
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
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_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return 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.