dolibarr  18.0.6
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 
63  public $table_element_line = 'stocktransfer_stocktransferline';
64 
68  public $fk_element = 'fk_stocktransfer';
69 
75  protected $childtablesoncascade = array('stocktransfer_stocktransferline');
76 
82  public $ref_client;
83 
87  public $ref_customer;
88 
89 
93  public $picto = 'stock';
94 
95  public $date_prevue_depart;
96  public $date_prevue_arrivee;
97  public $date_reelle_depart;
98  public $date_reelle_arrivee;
99 
100 
101  const STATUS_DRAFT = 0;
102  const STATUS_VALIDATED = 1;
103  const STATUS_TRANSFERED = 2;
104  const STATUS_CLOSED = 3;
105 
106 
132  // BEGIN MODULEBUILDER PROPERTIES
136  public $fields=array(
137  'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"),
138  'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>'1', 'position'=>1, 'default'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"),
139  '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"),
140  'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>0, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth200'/*, 'help'=>"Help text"*/, 'showoncombobox'=>'1',),
141  'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>31, 'notnull'=>0, 'visible'=>3,),
142  '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,),
143  '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"*/,),
144  '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',),
145  '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'),
146  'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,),
147  'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0,),
148  'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,),
149  'date_prevue_depart' => array('type'=>'date', 'label'=>'DatePrevueDepart', 'enabled'=>'1', 'position'=>100, 'notnull'=>0, 'visible'=>1,),
150  'date_reelle_depart' => array('type'=>'date', 'label'=>'DateReelleDepart', 'enabled'=>'1', 'position'=>101, 'notnull'=>0, 'visible'=>5,),
151  'date_prevue_arrivee' => array('type'=>'date', 'label'=>'DatePrevueArrivee', 'enabled'=>'1', 'position'=>102, 'notnull'=>0, 'visible'=>1,),
152  'date_reelle_arrivee' => array('type'=>'date', 'label'=>'DateReelleArrivee', 'enabled'=>'1', 'position'=>103, 'notnull'=>0, 'visible'=>5,),
153  'lead_time_for_warning' => array('type'=>'integer', 'label'=>'LeadTimeForWarning', 'enabled'=>'1', 'position'=>200, 'default'=>0, 'notnull'=>0, 'visible'=>1),
154  'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2,),
155  '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',),
156  'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ChangedBy', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,),
157  'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,),
158  'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,),
159  'fk_incoterms' => array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-2, 'position'=>220),
160  'location_incoterms' => array('type'=>'varchar(255)', 'label'=>'IncotermLabel', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-2, 'position'=>225),
161  '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'),),
162  );
163  public $rowid;
164  public $ref;
165  public $label;
166  public $fk_soc;
167  public $fk_project;
168  public $description;
169  public $note_public;
170  public $note_private;
171  public $date_creation;
172  public $tms;
173  public $lead_time_for_warning;
174  public $fk_user_creat;
175  public $fk_user_modif;
176  public $import_key;
177  public $model_pdf;
178  public $status;
179  // END MODULEBUILDER PROPERTIES
180 
181 
187  public function __construct(DoliDB $db)
188  {
189  global $conf, $langs;
190 
191  $this->db = $db;
192  $this->origin_type = 'StockTransfer@product/stock/stocktransfer';
193 
194  if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) $this->fields['rowid']['visible'] = 0;
195  if (!isModEnabled('multicompany') && isset($this->fields['entity'])) $this->fields['entity']['enabled'] = 0;
196 
197  // Example to show how to set values of fields definition dynamically
198  /*if ($user->rights->stocktransfer->stocktransfer->read) {
199  $this->fields['myfield']['visible'] = 1;
200  $this->fields['myfield']['noteditable'] = 0;
201  }*/
202 
203  // Unset fields that are disabled
204  foreach ($this->fields as $key => $val) {
205  if (isset($val['enabled']) && empty($val['enabled'])) {
206  unset($this->fields[$key]);
207  }
208  }
209 
210  // Translate some data of arrayofkeyval
211  if (is_object($langs)) {
212  foreach ($this->fields as $key => $val) {
213  if (isset($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
214  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
215  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
216  }
217  }
218  }
219  }
220  }
221 
229  public function create(User $user, $notrigger = false)
230  {
231  $model_pdf = GETPOST('model');
232  if (!empty($model_pdf)) $this->model_pdf = $model_pdf;
233  $this->status = (int) $this->status;
234  if ($this->fk_warehouse_source <= 0) $this->fk_warehouse_source = 0;
235  if ($this->fk_warehouse_destination <= 0) $this->fk_warehouse_destination = 0;
236  return $this->createCommon($user, $notrigger);
237  }
238 
246  public function createFromClone(User $user, $fromid)
247  {
248  global $langs, $extrafields;
249  $error = 0;
250 
251  dol_syslog(__METHOD__, LOG_DEBUG);
252 
253  $object = new self($this->db);
254 
255  $this->db->begin();
256 
257  // Load source object
258  $result = $object->fetchCommon($fromid);
259  if ($result > 0 && !empty($object->table_element_line)) $object->fetchLines();
260 
261  // get lines so they will be clone
262  //foreach($this->lines as $line)
263  // $line->fetch_optionals();
264 
265  // Reset some properties
266  unset($object->id);
267  unset($object->fk_user_creat);
268  unset($object->import_key);
269  unset($object->date_prevue_depart);
270  unset($object->date_prevue_arrivee);
271  unset($object->date_reelle_depart);
272  unset($object->date_reelle_arrivee);
273 
274 
275  // Clear fields
276  $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default'];
277  $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
278  $object->status = self::STATUS_DRAFT;
279  // ...
280  // Clear extrafields that are unique
281  if (is_array($object->array_options) && count($object->array_options) > 0) {
282  $extrafields->fetch_name_optionals_label($this->table_element);
283  foreach ($object->array_options as $key => $option) {
284  $shortkey = preg_replace('/options_/', '', $key);
285  if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
286  //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
287  unset($object->array_options[$key]);
288  }
289  }
290  }
291 
292  // Create clone
293  $object->context['createfromclone'] = 'createfromclone';
294  $result = $object->createCommon($user);
295  if ($result < 0) {
296  $error++;
297  $this->error = $object->error;
298  $this->errors = $object->errors;
299  }
300 
301  if (!$error) {
302  // copy internal contacts
303  if ($this->copy_linked_contact($object, 'internal') < 0) {
304  $error++;
305  }
306  }
307 
308  if (!$error) {
309  // copy external contacts if same company
310  if (property_exists($this, 'socid') && $this->socid == $object->socid) {
311  if ($this->copy_linked_contact($object, 'external') < 0)
312  $error++;
313  }
314  }
315 
316  unset($object->context['createfromclone']);
317 
318  // End
319  if (!$error) {
320  $this->db->commit();
321  return $object;
322  } else {
323  $this->db->rollback();
324  return -1;
325  }
326  }
327 
335  public function fetch($id, $ref = null)
336  {
337  $result = $this->fetchCommon($id, $ref);
338  if ($result > 0 && !empty($this->table_element_line)) $this->fetchLines();
339  return $result;
340  }
341 
347  public function fetchLines()
348  {
349  require_once DOL_DOCUMENT_ROOT . '/product/stock/stocktransfer/class/stocktransferline.class.php';
350  $this->lines = array();
351 
352  $result = $this->fetchLinesCommon();
353  usort($this->lines, array('stocktransfer', 'cmp'));
354  return $result;
355  }
356 
364  public function cmp($a, $b)
365  {
366  if ($a->rang == $b->rang) {
367  return 0;
368  }
369  return ($a->rang < $b->rang) ? -1 : 1;
370  }
371 
377  public function getValorisationTotale()
378  {
379 
380  $total_pmp = 0;
381 
382  if (empty($this->lines)) $this->fetchLines();
383  if (!empty($this->lines)) {
384  foreach ($this->lines as $l) $total_pmp+= ($l->pmp * $l->qty);
385  }
386 
387  return $total_pmp;
388  }
389 
401  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
402  {
403  global $conf;
404 
405  dol_syslog(__METHOD__, LOG_DEBUG);
406 
407  $records = array();
408 
409  $sql = 'SELECT ';
410  $sql .= $this->getFieldList();
411  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
412  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
413  else $sql .= ' WHERE 1 = 1';
414  // Manage filter
415  $sqlwhere = array();
416  if (count($filter) > 0) {
417  foreach ($filter as $key => $value) {
418  if ($key == 't.rowid') {
419  $sqlwhere[] = $key.'='.$value;
420  } elseif (strpos($key, 'date') !== false) {
421  $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\'';
422  } elseif ($key == 'customsql') {
423  $sqlwhere[] = $value;
424  } else {
425  $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\'';
426  }
427  }
428  }
429  if (count($sqlwhere) > 0) {
430  $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")";
431  }
432 
433  if (!empty($sortfield)) {
434  $sql .= $this->db->order($sortfield, $sortorder);
435  }
436  if (!empty($limit)) {
437  $sql .= ' '.$this->db->plimit($limit, $offset);
438  }
439 
440  $resql = $this->db->query($sql);
441  if ($resql) {
442  $num = $this->db->num_rows($resql);
443  $i = 0;
444  while ($i < ($limit ? min($limit, $num) : $num)) {
445  $obj = $this->db->fetch_object($resql);
446 
447  $record = new self($this->db);
448  $record->setVarsFromFetchObj($obj);
449 
450  $records[$record->id] = $record;
451 
452  $i++;
453  }
454  $this->db->free($resql);
455 
456  return $records;
457  } else {
458  $this->errors[] = 'Error '.$this->db->lasterror();
459  dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
460 
461  return -1;
462  }
463  }
464 
472  public function update(User $user, $notrigger = false)
473  {
474  $this->tms = ''; // Will be done automatically because tms field is on update cascade
475  $res = $this->updateCommon($user, $notrigger);
476  if ($this->socid > 0 || $this->fk_soc > 0 && empty($this->thirdparty)) $this->fetch_thirdparty();
477  if (empty($this->socid) && empty($this->fk_soc)) unset($this->thirdparty);
478  return $res;
479  }
480 
488  public function delete(User $user, $notrigger = false)
489  {
490  if ($this->status > self::STATUS_VALIDATED) {
491  return 0;
492  } else {
493  return $this->deleteCommon($user, $notrigger);
494  }
495  }
496 
505  public function deleteLine(User $user, $idline, $notrigger = false)
506  {
507  if ($this->status < 0) {
508  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
509  return -2;
510  }
511 
512  $res = $this->deleteLineCommon($user, $idline, $notrigger);
513  $this->line_order(true);
514  return $res;
515  }
516 
517 
525  public function validate($user, $notrigger = 0)
526  {
527  global $conf, $langs;
528 
529  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
530 
531  $error = 0;
532 
533  // Protection
534  if ($this->status == self::STATUS_VALIDATED) {
535  dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
536  return 0;
537  }
538 
539  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer->write))
540  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer->stocktransfer_advance->validate))))
541  {
542  $this->error='NotEnoughPermissions';
543  dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
544  return -1;
545  }*/
546 
547  $now = dol_now();
548 
549  $this->db->begin();
550 
551  // Define new ref
552  if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
553  $num = $this->getNextNumRef();
554  } else {
555  $num = $this->ref;
556  }
557  $this->newref = $num;
558 
559  if (!empty($num)) {
560  // Validate
561  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
562  $sql .= " SET ref = '".$this->db->escape($num)."',";
563  $sql .= " status = ".self::STATUS_VALIDATED;
564  if (!empty($this->fields['date_validation'])) $sql .= ", date_validation = '".$this->db->idate($now)."',";
565  if (!empty($this->fields['fk_user_valid'])) $sql .= ", fk_user_valid = ".((int) $user->id);
566  $sql .= " WHERE rowid = ".((int) $this->id);
567 
568  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
569  $resql = $this->db->query($sql);
570  if (!$resql) {
571  dol_print_error($this->db);
572  $this->error = $this->db->lasterror();
573  $error++;
574  }
575 
576  if (!$error && !$notrigger) {
577  // Call trigger
578  $result = $this->call_trigger('STOCKTRANSFER_VALIDATE', $user);
579  if ($result < 0) $error++;
580  // End call triggers
581  }
582  }
583 
584  if (!$error) {
585  $this->oldref = $this->ref;
586 
587  // Rename directory if dir was a temporary ref
588  if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
589  // Now we rename also files into index
590  $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)."'";
591  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransfer/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity);
592  $resql = $this->db->query($sql);
593  if (!$resql) {
594  $error++; $this->error = $this->db->lasterror();
595  }
596  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'stocktransfer/".$this->db->escape($this->newref)."'";
597  $sql .= " WHERE filepath = 'stocktransfer/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
598  $resql = $this->db->query($sql);
599  if (!$resql) {
600  $error++; $this->error = $this->db->lasterror();
601  }
602 
603  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
604  $oldref = dol_sanitizeFileName($this->ref);
605  $newref = dol_sanitizeFileName($num);
606  $dirsource = $conf->stocktransfer->dir_output.'/stocktransfer/'.$oldref;
607  $dirdest = $conf->stocktransfer->dir_output.'/stocktransfer/'.$newref;
608  if (!$error && file_exists($dirsource)) {
609  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
610 
611  if (@rename($dirsource, $dirdest)) {
612  dol_syslog("Rename ok");
613  // Rename docs starting with $oldref with $newref
614  $listoffiles = dol_dir_list($conf->stocktransfer->dir_output.'/stocktransfer/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
615  foreach ($listoffiles as $fileentry) {
616  $dirsource = $fileentry['name'];
617  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
618  $dirsource = $fileentry['path'].'/'.$dirsource;
619  $dirdest = $fileentry['path'].'/'.$dirdest;
620  @rename($dirsource, $dirdest);
621  }
622  }
623  }
624  }
625  }
626 
627  // Set new ref and current status
628  if (!$error) {
629  $this->ref = $num;
630  $this->status = self::STATUS_VALIDATED;
631  }
632 
633  if (!$error) {
634  $this->db->commit();
635  return 1;
636  } else {
637  $this->db->rollback();
638  return -1;
639  }
640  }
641 
642 
650  public function setDraft($user, $notrigger = 0)
651  {
652  // Protection
653  if ($this->status <= self::STATUS_DRAFT) {
654  return 0;
655  }
656 
657  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
658  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
659  {
660  $this->error='Permission denied';
661  return -1;
662  }*/
663 
664  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'STOCKTRANSFER_UNVALIDATE');
665  }
666 
674  public function cancel($user, $notrigger = 0)
675  {
676  // Protection
677  if ($this->status != self::STATUS_VALIDATED) {
678  return 0;
679  }
680 
681  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
682  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
683  {
684  $this->error='Permission denied';
685  return -1;
686  }*/
687 
688  return $this->setStatusCommon($user, self::STATUS_CLOSED, $notrigger, 'STOCKTRANSFER_CLOSE');
689  }
690 
698  public function reopen($user, $notrigger = 0)
699  {
700  // Protection
701  if ($this->status != self::STATUS_CLOSED) {
702  return 0;
703  }
704 
705  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
706  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
707  {
708  $this->error='Permission denied';
709  return -1;
710  }*/
711 
712  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'STOCKTRANSFER_REOPEN');
713  }
714 
725  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
726  {
727  global $conf, $langs, $hookmanager;
728 
729  if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips
730 
731  $result = '';
732 
733  $label = '<u>'.$langs->trans("StockTransfer").'</u>';
734  $label .= '<br>';
735  $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
736  if (isset($this->status)) {
737  $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
738  }
739 
740  $url = dol_buildpath('/product/stock/stocktransfer/stocktransfer_card.php', 1).'?id='.$this->id;
741 
742  if ($option != 'nolink') {
743  // Add param to save lastsearch_values or not
744  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
745  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1;
746  if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1';
747  }
748 
749  $linkclose = '';
750  if (empty($notooltip)) {
751  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
752  $label = $langs->trans("ShowStockTransfer");
753  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
754  }
755  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
756  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
757  } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
758 
759  $linkstart = '<a href="'.$url.'"';
760  $linkstart .= $linkclose.'>';
761  $linkend = '</a>';
762 
763  $result .= $linkstart;
764 
765  if (empty($this->showphoto_on_popup)) {
766  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);
767  } else {
768  if ($withpicto) {
769  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
770 
771  list($class, $module) = explode('@', $this->picto);
772  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
773  $filearray = dol_dir_list($upload_dir, "files");
774  $filename = $filearray[0]['name'];
775  if (!empty($filename)) {
776  $pospoint = strpos($filearray[0]['name'], '.');
777 
778  $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
779  if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) {
780  $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>';
781  } else {
782  $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>';
783  }
784 
785  $result .= '</div>';
786  } else {
787  $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);
788  }
789  }
790  }
791 
792  if ($withpicto != 2) $result .= $this->ref;
793 
794  $result .= $linkend;
795  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
796 
797  global $action, $hookmanager;
798  $hookmanager->initHooks(array('stocktransferdao'));
799  $parameters = array('id'=>$this->id, 'getnomurl'=>$result);
800  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
801  if ($reshook > 0) $result = $hookmanager->resPrint;
802  else $result .= $hookmanager->resPrint;
803 
804  return $result;
805  }
806 
813  public function getLibStatut($mode = 0)
814  {
815  return $this->LibStatut($this->status, $mode);
816  }
817 
818  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
826  public function LibStatut($status, $mode = 0)
827  {
828  // phpcs:enable
829  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
830  global $langs;
831  //$langs->load("stocktransfer@stocktransfer");
832  $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft');
833  $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated');
834  $this->labelStatus[self::STATUS_TRANSFERED] = $langs->trans('StockStransferDecremented');
835  $this->labelStatus[self::STATUS_CLOSED] = $langs->trans('StockStransferIncremented');
836  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft');
837  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Validated');
838  $this->labelStatusShort[self::STATUS_TRANSFERED] = $langs->trans('StockStransferDecremented');
839  $this->labelStatusShort[self::STATUS_CLOSED] = $langs->trans('StockStransferIncremented');
840  }
841 
842  $statusType = 'status'.$status;
843  //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
844  if ($status == self::STATUS_CLOSED) $statusType = 'status6';
845 
846  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
847  }
848 
855  public function info($id)
856  {
857  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
858  $sql .= ' fk_user_creat, fk_user_modif';
859  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
860  $sql .= ' WHERE t.rowid = '.((int) $id);
861  $result = $this->db->query($sql);
862  if ($result) {
863  if ($this->db->num_rows($result)) {
864  $obj = $this->db->fetch_object($result);
865  $this->id = $obj->rowid;
866 
867  $this->user_creation_id = $obj->fk_user_creat;
868  $this->user_modification_id = $obj->fk_user_modif;
869  $this->date_creation = $this->db->jdate($obj->datec);
870  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
871  }
872 
873  $this->db->free($result);
874  } else {
875  dol_print_error($this->db);
876  }
877  }
878 
885  public function initAsSpecimen()
886  {
887  $this->initAsSpecimenCommon();
888  }
889 
895  public function getLinesArray()
896  {
897  $this->lines = array();
898 
899  $objectline = new StockTransferLine($this->db);
900  $result = $objectline->fetchAll('ASC', 'rang', 0, 0, array('customsql'=>'fk_stocktransfer = '.$this->id));
901 
902  if (is_numeric($result)) {
903  $this->error = $objectline->error;
904  $this->errors = $objectline->errors;
905  return $result;
906  } else {
907  $this->lines = $result;
908  return $this->lines;
909  }
910  }
911 
917  public function getNextNumRef()
918  {
919  global $langs, $conf;
920  $langs->load("stocks");
921 
922  if (empty($conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON)) {
923  $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON = 'mod_stocktransfer_standard';
924  }
925 
926  if (!empty($conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON)) {
927  $mybool = false;
928 
929  $file = $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON.".php";
930  $classname = $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON;
931 
932  // Include file with class
933  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
934  foreach ($dirmodels as $reldir) {
935  $dir = dol_buildpath($reldir."core/modules/stocktransfer/");
936 
937  // Load file with numbering class (if found)
938  $mybool |= @include_once $dir.$file;
939  }
940 
941  if ($mybool === false) {
942  dol_print_error('', "Failed to include file ".$file);
943  return '';
944  }
945 
946  if (class_exists($classname)) {
947  $obj = new $classname();
948  $numref = $obj->getNextValue($this);
949 
950  if ($numref != '' && $numref != '-1') {
951  return $numref;
952  } else {
953  $this->error = $obj->error;
954  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
955  return "";
956  }
957  } else {
958  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
959  return "";
960  }
961  } else {
962  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
963  return "";
964  }
965  }
966 
978  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
979  {
980  global $conf, $langs;
981 
982  $result = 0;
983  $includedocgeneration = 1;
984 
985  $langs->load("stocks");
986 
987  if (!dol_strlen($modele)) {
988  $modele = 'eagle';
989 
990  if ($this->modelpdf) {
991  $modele = $this->modelpdf;
992  } elseif (!empty($conf->global->STOCKTRANSFER_ADDON_PDF)) {
993  $modele = $conf->global->STOCKTRANSFER_ADDON_PDF;
994  }
995  }
996 
997  $modelpath = "core/modules/stocktransfer/doc/";
998 
999  if ($includedocgeneration) {
1000  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1001  }
1002 
1003  return $result;
1004  }
1005 
1013  public function doScheduledJob()
1014  {
1015  global $conf, $langs;
1016 
1017  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1018 
1019  $error = 0;
1020  $this->output = '';
1021  $this->error = '';
1022 
1023  dol_syslog(__METHOD__, LOG_DEBUG);
1024 
1025  $now = dol_now();
1026 
1027  $this->db->begin();
1028 
1029  // ...
1030 
1031  $this->db->commit();
1032 
1033  return $error;
1034  }
1035 }
1036 
1040 //class StockTransferLine
1041 //{
1042 // // To complete with content of an object StockTransferLine
1043 // // We should have a field rowid, fk_stocktransfer and position
1044 //
1045 // /**
1046 // * @var int Does object support extrafields ? 0=No, 1=Yes
1047 // */
1048 // public $isextrafieldmanaged = 0;
1049 //
1050 // /**
1051 // * Constructor
1052 // *
1053 // * @param DoliDb $db Database handler
1054 // */
1055 // public function __construct(DoliDB $db)
1056 // {
1057 // $this->db = $db;
1058 // }
1059 //}
$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.
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.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
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: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.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.