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 
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) {
585  $error++; $this->error = $this->db->lasterror();
586  }
587  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'stocktransfer/".$this->db->escape($this->newref)."'";
588  $sql .= " WHERE filepath = 'stocktransfer/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
589  $resql = $this->db->query($sql);
590  if (!$resql) {
591  $error++; $this->error = $this->db->lasterror();
592  }
593 
594  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
595  $oldref = dol_sanitizeFileName($this->ref);
596  $newref = dol_sanitizeFileName($num);
597  $dirsource = $conf->stocktransfer->dir_output.'/stocktransfer/'.$oldref;
598  $dirdest = $conf->stocktransfer->dir_output.'/stocktransfer/'.$newref;
599  if (!$error && file_exists($dirsource)) {
600  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
601 
602  if (@rename($dirsource, $dirdest)) {
603  dol_syslog("Rename ok");
604  // Rename docs starting with $oldref with $newref
605  $listoffiles = dol_dir_list($conf->stocktransfer->dir_output.'/stocktransfer/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
606  foreach ($listoffiles as $fileentry) {
607  $dirsource = $fileentry['name'];
608  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
609  $dirsource = $fileentry['path'].'/'.$dirsource;
610  $dirdest = $fileentry['path'].'/'.$dirdest;
611  @rename($dirsource, $dirdest);
612  }
613  }
614  }
615  }
616  }
617 
618  // Set new ref and current status
619  if (!$error) {
620  $this->ref = $num;
621  $this->status = self::STATUS_VALIDATED;
622  }
623 
624  if (!$error) {
625  $this->db->commit();
626  return 1;
627  } else {
628  $this->db->rollback();
629  return -1;
630  }
631  }
632 
633 
641  public function setDraft($user, $notrigger = 0)
642  {
643  // Protection
644  if ($this->status <= self::STATUS_DRAFT) {
645  return 0;
646  }
647 
648  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
649  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
650  {
651  $this->error='Permission denied';
652  return -1;
653  }*/
654 
655  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'STOCKTRANSFER_UNVALIDATE');
656  }
657 
665  public function cancel($user, $notrigger = 0)
666  {
667  // Protection
668  if ($this->status != self::STATUS_VALIDATED) {
669  return 0;
670  }
671 
672  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
673  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
674  {
675  $this->error='Permission denied';
676  return -1;
677  }*/
678 
679  return $this->setStatusCommon($user, self::STATUS_CLOSED, $notrigger, 'STOCKTRANSFER_CLOSE');
680  }
681 
689  public function reopen($user, $notrigger = 0)
690  {
691  // Protection
692  if ($this->status != self::STATUS_CLOSED) {
693  return 0;
694  }
695 
696  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
697  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
698  {
699  $this->error='Permission denied';
700  return -1;
701  }*/
702 
703  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'STOCKTRANSFER_REOPEN');
704  }
705 
716  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
717  {
718  global $conf, $langs, $hookmanager;
719 
720  if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips
721 
722  $result = '';
723 
724  $label = '<u>'.$langs->trans("StockTransfer").'</u>';
725  $label .= '<br>';
726  $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
727  if (isset($this->status)) {
728  $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
729  }
730 
731  $url = dol_buildpath('/product/stock/stocktransfer/stocktransfer_card.php', 1).'?id='.$this->id;
732 
733  if ($option != 'nolink') {
734  // Add param to save lastsearch_values or not
735  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
736  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1;
737  if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1';
738  }
739 
740  $linkclose = '';
741  if (empty($notooltip)) {
742  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
743  $label = $langs->trans("ShowStockTransfer");
744  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
745  }
746  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
747  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
748  } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
749 
750  $linkstart = '<a href="'.$url.'"';
751  $linkstart .= $linkclose.'>';
752  $linkend = '</a>';
753 
754  $result .= $linkstart;
755 
756  if (empty($this->showphoto_on_popup)) {
757  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);
758  } else {
759  if ($withpicto) {
760  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
761 
762  list($class, $module) = explode('@', $this->picto);
763  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
764  $filearray = dol_dir_list($upload_dir, "files");
765  $filename = $filearray[0]['name'];
766  if (!empty($filename)) {
767  $pospoint = strpos($filearray[0]['name'], '.');
768 
769  $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
770  if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) {
771  $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>';
772  } else {
773  $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>';
774  }
775 
776  $result .= '</div>';
777  } else {
778  $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);
779  }
780  }
781  }
782 
783  if ($withpicto != 2) $result .= $this->ref;
784 
785  $result .= $linkend;
786  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
787 
788  global $action, $hookmanager;
789  $hookmanager->initHooks(array('stocktransferdao'));
790  $parameters = array('id'=>$this->id, 'getnomurl'=>$result);
791  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
792  if ($reshook > 0) $result = $hookmanager->resPrint;
793  else $result .= $hookmanager->resPrint;
794 
795  return $result;
796  }
797 
804  public function getLibStatut($mode = 0)
805  {
806  return $this->LibStatut($this->status, $mode);
807  }
808 
809  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
817  public function LibStatut($status, $mode = 0)
818  {
819  // phpcs:enable
820  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
821  global $langs;
822  //$langs->load("stocktransfer@stocktransfer");
823  $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft');
824  $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated');
825  $this->labelStatus[self::STATUS_TRANSFERED] = $langs->trans('StockStransferDecremented');
826  $this->labelStatus[self::STATUS_CLOSED] = $langs->trans('StockStransferIncremented');
827  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft');
828  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Validated');
829  $this->labelStatusShort[self::STATUS_TRANSFERED] = $langs->trans('StockStransferDecremented');
830  $this->labelStatusShort[self::STATUS_CLOSED] = $langs->trans('StockStransferIncremented');
831  }
832 
833  $statusType = 'status'.$status;
834  //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
835  if ($status == self::STATUS_CLOSED) $statusType = 'status6';
836 
837  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
838  }
839 
846  public function info($id)
847  {
848  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
849  $sql .= ' fk_user_creat, fk_user_modif';
850  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
851  $sql .= ' WHERE t.rowid = '.((int) $id);
852  $result = $this->db->query($sql);
853  if ($result) {
854  if ($this->db->num_rows($result)) {
855  $obj = $this->db->fetch_object($result);
856  $this->id = $obj->rowid;
857 
858  $this->user_creation_id = $obj->fk_user_creat;
859  $this->user_modification_id = $obj->fk_user_modif;
860  $this->date_creation = $this->db->jdate($obj->datec);
861  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
862  }
863 
864  $this->db->free($result);
865  } else {
866  dol_print_error($this->db);
867  }
868  }
869 
876  public function initAsSpecimen()
877  {
878  $this->initAsSpecimenCommon();
879  }
880 
886  public function getLinesArray()
887  {
888  $this->lines = array();
889 
890  $objectline = new StockTransferLine($this->db);
891  $result = $objectline->fetchAll('ASC', 'rang', 0, 0, array('customsql'=>'fk_stocktransfer = '.$this->id));
892 
893  if (is_numeric($result)) {
894  $this->error = $objectline->error;
895  $this->errors = $objectline->errors;
896  return $result;
897  } else {
898  $this->lines = $result;
899  return $this->lines;
900  }
901  }
902 
908  public function getNextNumRef()
909  {
910  global $langs, $conf;
911  $langs->load("stocks");
912 
913  if (empty($conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON)) {
914  $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON = 'mod_stocktransfer_standard';
915  }
916 
917  if (!empty($conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON)) {
918  $mybool = false;
919 
920  $file = $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON.".php";
921  $classname = $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON;
922 
923  // Include file with class
924  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
925  foreach ($dirmodels as $reldir) {
926  $dir = dol_buildpath($reldir."core/modules/stocktransfer/");
927 
928  // Load file with numbering class (if found)
929  $mybool |= @include_once $dir.$file;
930  }
931 
932  if ($mybool === false) {
933  dol_print_error('', "Failed to include file ".$file);
934  return '';
935  }
936 
937  if (class_exists($classname)) {
938  $obj = new $classname();
939  $numref = $obj->getNextValue($this);
940 
941  if ($numref != '' && $numref != '-1') {
942  return $numref;
943  } else {
944  $this->error = $obj->error;
945  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
946  return "";
947  }
948  } else {
949  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
950  return "";
951  }
952  } else {
953  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
954  return "";
955  }
956  }
957 
969  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
970  {
971  global $conf, $langs;
972 
973  $result = 0;
974  $includedocgeneration = 1;
975 
976  $langs->load("stocks");
977 
978  if (!dol_strlen($modele)) {
979  $modele = 'eagle';
980 
981  if ($this->modelpdf) {
982  $modele = $this->modelpdf;
983  } elseif (!empty($conf->global->STOCKTRANSFER_ADDON_PDF)) {
984  $modele = $conf->global->STOCKTRANSFER_ADDON_PDF;
985  }
986  }
987 
988  $modelpath = "core/modules/stocktransfer/doc/";
989 
990  if ($includedocgeneration) {
991  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
992  }
993 
994  return $result;
995  }
996 
1004  public function doScheduledJob()
1005  {
1006  global $conf, $langs;
1007 
1008  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1009 
1010  $error = 0;
1011  $this->output = '';
1012  $this->error = '';
1013 
1014  dol_syslog(__METHOD__, LOG_DEBUG);
1015 
1016  $now = dol_now();
1017 
1018  $this->db->begin();
1019 
1020  // ...
1021 
1022  $this->db->commit();
1023 
1024  return $error;
1025  }
1026 }
1027 
1031 //class StockTransferLine
1032 //{
1033 // // To complete with content of an object StockTransferLine
1034 // // We should have a field rowid, fk_stocktransfer and position
1035 //
1036 // /**
1037 // * @var int Does object support extrafields ? 0=No, 1=Yes
1038 // */
1039 // public $isextrafieldmanaged = 0;
1040 //
1041 // /**
1042 // * Constructor
1043 // *
1044 // * @param DoliDb $db Database handler
1045 // */
1046 // public function __construct(DoliDB $db)
1047 // {
1048 // $this->db = $db;
1049 // }
1050 //}
$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.