dolibarr  17.0.4
stocktransferline.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) ---Put here your own copyright and developer email---
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/commonobjectline.class.php';
28 //require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
29 //require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
30 
35 {
39  public $element = 'stocktransferline';
40 
44  public $table_element = 'stocktransfer_stocktransferline';
45 
50  public $ismultientitymanaged = 0;
51 
55  public $isextrafieldmanaged = 1;
56 
60  public $picto = 'stocktransferline@stocktransfer';
61 
62 
63  const STATUS_DRAFT = 0;
64  const STATUS_VALIDATED = 1;
65  const STATUS_CANCELED = 9;
66 
67 
93  // BEGIN MODULEBUILDER PROPERTIES
97  public $fields=array(
98  'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"),
99  'amount' => array('type'=>'price', 'label'=>'Amount', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1, 'default'=>'null', 'isameasure'=>'1', 'help'=>"Help text for amount",),
100  'qty' => array('type'=>'real', 'label'=>'Qty', 'enabled'=>'1', 'position'=>45, 'notnull'=>0, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'css'=>'maxwidth75imp', 'help'=>"Help text for quantity",),
101  'fk_warehouse_destination' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Entrepôt de destination', 'enabled'=>'1', 'position'=>50, 'notnull'=>1, 'visible'=>1,),
102  'fk_warehouse_source' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Entrepôt source', 'enabled'=>'1', 'position'=>50, 'notnull'=>1, 'visible'=>1,),
103  'fk_stocktransfer' => array('type'=>'integer:StockTransfer:stocktransfer/stock/class/stocktransfer.class.php', 'label'=>'StockTransfer', 'enabled'=>'1', 'position'=>50, 'notnull'=>1, 'visible'=>0,),
104  'fk_product' => array('type'=>'integer:Product:product/class/product.class.php', 'label'=>'Product', 'enabled'=>'1', 'position'=>50, 'notnull'=>1, 'visible'=>1,),
105  'batch' => array('type'=>'varchar(128)', 'label'=>'Batch', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>1,),
106  'pmp' => array('type'=>'double'/*, 'help'=>'THMEstimatedHelp'*/, 'label'=>'PMP', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1,),
107  'rang' => array('type'=>'integer', 'label'=>'Qty', 'enabled'=>'1', 'position'=>45, 'notnull'=>0, 'visible'=>0, 'default'=>'0', 'isameasure'=>'1', 'css'=>'maxwidth75imp', 'help'=>"Help text for quantity",),
108  );
109  public $rowid;
110  public $amount;
111  public $qty;
112  public $fk_warehouse_destination;
113  public $fk_warehouse_source;
114  public $fk_stocktransfer;
115  public $fk_product;
116  public $batch;
117  // END MODULEBUILDER PROPERTIES
118 
119 
120  // If this object has a subtable with lines
121 
125  //public $table_element_line = 'stocktransfer_stocktransferlineline';
126 
130  //public $fk_element = 'fk_stocktransferline';
131 
135  //public $class_element_line = 'StockTransferLineline';
136 
140  //protected $childtables = array();
141 
147  //protected $childtablesoncascade = array('stocktransfer_stocktransferlinedet');
148 
152  //public $lines = array();
153 
154 
155 
161  public function __construct(DoliDB $db)
162  {
163  global $conf, $langs;
164 
165  $this->db = $db;
166 
167  if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) $this->fields['rowid']['visible'] = 0;
168  if (!isModEnabled('multicompany') && isset($this->fields['entity'])) $this->fields['entity']['enabled'] = 0;
169 
170  // Example to show how to set values of fields definition dynamically
171  /*if ($user->rights->stocktransfer->stocktransferline->read) {
172  $this->fields['myfield']['visible'] = 1;
173  $this->fields['myfield']['noteditable'] = 0;
174  }*/
175 
176  // Unset fields that are disabled
177  foreach ($this->fields as $key => $val) {
178  if (isset($val['enabled']) && empty($val['enabled'])) {
179  unset($this->fields[$key]);
180  }
181  }
182 
183  // Translate some data of arrayofkeyval
184  if (is_object($langs)) {
185  foreach ($this->fields as $key => $val) {
186  if (is_array($val['arrayofkeyval'])) {
187  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
188  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
189  }
190  }
191  }
192  }
193  }
194 
202  public function create(User $user, $notrigger = false)
203  {
204  return $this->createCommon($user, $notrigger);
205  }
206 
214  public function createFromClone(User $user, $fromid)
215  {
216  global $langs, $extrafields;
217  $error = 0;
218 
219  dol_syslog(__METHOD__, LOG_DEBUG);
220 
221  $object = new self($this->db);
222 
223  $this->db->begin();
224 
225  // Load source object
226  $result = $object->fetchCommon($fromid);
227  if ($result > 0 && !empty($object->table_element_line)) $object->fetchLines();
228 
229  // get lines so they will be clone
230  //foreach($this->lines as $line)
231  // $line->fetch_optionals();
232 
233  // Reset some properties
234  unset($object->id);
235  unset($object->import_key);
236 
237 
238  // Clear fields
239  $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default'];
240  $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
241  $object->status = self::STATUS_DRAFT;
242  // ...
243  // Clear extrafields that are unique
244  if (is_array($object->array_options) && count($object->array_options) > 0) {
245  $extrafields->fetch_name_optionals_label($this->table_element);
246  foreach ($object->array_options as $key => $option) {
247  $shortkey = preg_replace('/options_/', '', $key);
248  if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
249  //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
250  unset($object->array_options[$key]);
251  }
252  }
253  }
254 
255  // Create clone
256  $object->context['createfromclone'] = 'createfromclone';
257  $result = $object->createCommon($user);
258  if ($result < 0) {
259  $error++;
260  $this->error = $object->error;
261  $this->errors = $object->errors;
262  }
263 
264  if (!$error) {
265  // copy internal contacts
266  if ($this->copy_linked_contact($object, 'internal') < 0) {
267  $error++;
268  }
269  }
270 
271  if (!$error) {
272  // copy external contacts if same company
273  if (property_exists($this, 'socid') && $this->socid == $object->socid) {
274  if ($this->copy_linked_contact($object, 'external') < 0)
275  $error++;
276  }
277  }
278 
279  unset($object->context['createfromclone']);
280 
281  // End
282  if (!$error) {
283  $this->db->commit();
284  return $object;
285  } else {
286  $this->db->rollback();
287  return -1;
288  }
289  }
290 
298  public function fetch($id, $ref = null)
299  {
300  $result = $this->fetchCommon($id, $ref);
301  if ($result > 0 && !empty($this->table_element_line)) $this->fetchLines();
302  return $result;
303  }
304 
310  public function fetchLines()
311  {
312  $this->lines = array();
313 
314  $result = $this->fetchLinesCommon();
315  return $result;
316  }
317 
318 
330  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
331  {
332  global $conf;
333 
334  dol_syslog(__METHOD__, LOG_DEBUG);
335 
336  $records = array();
337 
338  $sql = 'SELECT ';
339  $sql .= $this->getFieldList();
340  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
341  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
342  else $sql .= ' WHERE 1 = 1';
343  // Manage filter
344  $sqlwhere = array();
345  if (count($filter) > 0) {
346  foreach ($filter as $key => $value) {
347  if ($key == 't.rowid') {
348  $sqlwhere[] = $key.'='.$value;
349  } elseif (strpos($key, 'date') !== false) {
350  $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\'';
351  } elseif ($key == 'customsql') {
352  $sqlwhere[] = $value;
353  } else {
354  $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\'';
355  }
356  }
357  }
358  if (count($sqlwhere) > 0) {
359  $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")";
360  }
361 
362  if (!empty($sortfield)) {
363  $sql .= $this->db->order($sortfield, $sortorder);
364  }
365  if (!empty($limit)) {
366  $sql .= ' '.$this->db->plimit($limit, $offset);
367  }
368 
369  $resql = $this->db->query($sql);
370  if ($resql) {
371  $num = $this->db->num_rows($resql);
372  $i = 0;
373  while ($i < ($limit ? min($limit, $num) : $num)) {
374  $obj = $this->db->fetch_object($resql);
375 
376  $record = new self($this->db);
377  $record->setVarsFromFetchObj($obj);
378 
379  $records[$record->id] = $record;
380 
381  $i++;
382  }
383  $this->db->free($resql);
384 
385  return $records;
386  } else {
387  $this->errors[] = 'Error '.$this->db->lasterror();
388  dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
389 
390  return -1;
391  }
392  }
393 
401  public function update(User $user, $notrigger = false)
402  {
403  return $this->updateCommon($user, $notrigger);
404  }
405 
413  public function delete(User $user, $notrigger = false)
414  {
415  return $this->deleteCommon($user, $notrigger);
416  //return $this->deleteCommon($user, $notrigger, 1);
417  }
418 
427  public function deleteLine(User $user, $idline, $notrigger = false)
428  {
429  if ($this->status < 0) {
430  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
431  return -2;
432  }
433 
434  return $this->deleteLineCommon($user, $idline, $notrigger);
435  }
436 
446  public function doStockMovement($label, $code_inv, $fk_entrepot, $direction = 1)
447  {
448 
449  global $conf, $user, $langs;
450 
451  require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
452  include_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php';
453  include_once DOL_DOCUMENT_ROOT . '/product/stock/stocktransfer/class/stocktransfer.class.php';
454 
455  $p = new Product($this->db);
456  $p->fetch($this->fk_product);
457 
458  $op[0] = "+".trim($this->qty);
459  $op[1] = "-".trim($this->qty);
460  $movementstock = new MouvementStock($this->db);
461  $st = new StockTransfer($this->db);
462  $movementstock->origin_type = $st->origin_type;
463  $movementstock->origin_id = $this->fk_stocktransfer;
464 
465  if (empty($this->batch)) { // no batch for line
466  /*$result = $p->correct_stock(
467  $user,
468  $fk_entrepot,
469  $this->qty,
470  $direction, // 1=décrémentation
471  $label,
472  empty($direction) ? $this->pmp : 0,
473  GETPOST('inventorycode', 'alphanohtml'),
474  'stocktransfer',
475  $this->fk_stocktransfer
476  );*/
477 
478  $result = $movementstock->_create($user,
479  $p->id,
480  $fk_entrepot,
481  $op[$direction],
482  $direction,
483  empty($direction) ? $this->pmp : 0,
484  $label,
485  $code_inv);
486 
487  if ($result < 0) {
488  setEventMessages($p->errors, $p->errorss, 'errors');
489  return 0;
490  }
491  } else {
492  if ($p->hasbatch()) {
493  $arraybatchinfo = $p->loadBatchInfo($this->batch);
494  if (count($arraybatchinfo) > 0) {
495  $firstrecord = array_shift($arraybatchinfo);
496  $dlc = $firstrecord['eatby'];
497  $dluo = $firstrecord['sellby'];
498  //var_dump($batch); var_dump($arraybatchinfo); var_dump($firstrecord); var_dump($dlc); var_dump($dluo); exit;
499  } else {
500  $dlc = '';
501  $dluo = '';
502  }
503 
504  /*$result = $p->correct_stock_batch(
505  $user,
506  $fk_entrepot,
507  $this->qty,
508  $direction,
509  $label,
510  empty($direction) ? $this->pmp : 0,
511  $dlc,
512  $dluo,
513  $this->batch,
514  GETPOST("codemove")
515  );*/
516 
517  $result = $movementstock->_create($user,
518  $p->id,
519  $fk_entrepot,
520  $op[$direction],
521  $direction,
522  empty($direction) ? $this->pmp : 0,
523  $label,
524  $code_inv,
525  '',
526  $dlc,
527  $dluo,
528  $this->batch);
529 
530  if ($result < 0) {
531  setEventMessages($p->errors, $p->errorss, 'errors');
532  return 0;
533  }
534  } else {
535  setEventMessages($langs->trans('StockTransferNoBatchForProduct', $p->getNomUrl()), '', 'errors');
536  return -1;
537  }
538  }
539 
540  return 1;
541  }
542 
550  public function validate($user, $notrigger = 0)
551  {
552  global $conf, $langs;
553 
554  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
555 
556  $error = 0;
557 
558  // Protection
559  if ($this->status == self::STATUS_VALIDATED) {
560  dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
561  return 0;
562  }
563 
564  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransferline->write))
565  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransferline->stocktransferline_advance->validate))))
566  {
567  $this->error='NotEnoughPermissions';
568  dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
569  return -1;
570  }*/
571 
572  $now = dol_now();
573 
574  $this->db->begin();
575 
576  // Define new ref
577  if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
578  $num = $this->getNextNumRef();
579  } else {
580  $num = $this->ref;
581  }
582  $this->newref = $num;
583 
584  if (!empty($num)) {
585  // Validate
586  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
587  $sql .= " SET ref = '".$this->db->escape($num)."',";
588  $sql .= " status = ".self::STATUS_VALIDATED;
589  if (!empty($this->fields['date_validation'])) $sql .= ", date_validation = '".$this->db->idate($now)."',";
590  if (!empty($this->fields['fk_user_valid'])) $sql .= ", fk_user_valid = ".((int) $user->id);
591  $sql .= " WHERE rowid = ".((int) $this->id);
592 
593  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
594  $resql = $this->db->query($sql);
595  if (!$resql) {
596  dol_print_error($this->db);
597  $this->error = $this->db->lasterror();
598  $error++;
599  }
600 
601  if (!$error && !$notrigger) {
602  // Call trigger
603  $result = $this->call_trigger('STOCKTRANSFERLINE_VALIDATE', $user);
604  if ($result < 0) $error++;
605  // End call triggers
606  }
607  }
608 
609  if (!$error) {
610  $this->oldref = $this->ref;
611 
612  // Rename directory if dir was a temporary ref
613  if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
614  // Now we rename also files into index
615  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'stocktransferline/".$this->db->escape($this->newref)."'";
616  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransferline/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity);
617  $resql = $this->db->query($sql);
618  if (!$resql) { $error++; $this->error = $this->db->lasterror(); }
619 
620  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
621  $oldref = dol_sanitizeFileName($this->ref);
622  $newref = dol_sanitizeFileName($num);
623  $dirsource = $conf->stocktransfer->dir_output.'/stocktransferline/'.$oldref;
624  $dirdest = $conf->stocktransfer->dir_output.'/stocktransferline/'.$newref;
625  if (!$error && file_exists($dirsource)) {
626  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
627 
628  if (@rename($dirsource, $dirdest)) {
629  dol_syslog("Rename ok");
630  // Rename docs starting with $oldref with $newref
631  $listoffiles = dol_dir_list($conf->stocktransfer->dir_output.'/stocktransferline/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
632  foreach ($listoffiles as $fileentry) {
633  $dirsource = $fileentry['name'];
634  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
635  $dirsource = $fileentry['path'].'/'.$dirsource;
636  $dirdest = $fileentry['path'].'/'.$dirdest;
637  @rename($dirsource, $dirdest);
638  }
639  }
640  }
641  }
642  }
643 
644  // Set new ref and current status
645  if (!$error) {
646  $this->ref = $num;
647  $this->status = self::STATUS_VALIDATED;
648  }
649 
650  if (!$error) {
651  $this->db->commit();
652  return 1;
653  } else {
654  $this->db->rollback();
655  return -1;
656  }
657  }
658 
659 
667  public function setDraft($user, $notrigger = 0)
668  {
669  // Protection
670  if ($this->status <= self::STATUS_DRAFT) {
671  return 0;
672  }
673 
674  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
675  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
676  {
677  $this->error='Permission denied';
678  return -1;
679  }*/
680 
681  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'STOCKTRANSFERLINE_UNVALIDATE');
682  }
683 
691  public function cancel($user, $notrigger = 0)
692  {
693  // Protection
694  if ($this->status != self::STATUS_VALIDATED) {
695  return 0;
696  }
697 
698  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
699  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
700  {
701  $this->error='Permission denied';
702  return -1;
703  }*/
704 
705  return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'STOCKTRANSFERLINE_CLOSE');
706  }
707 
715  public function reopen($user, $notrigger = 0)
716  {
717  // Protection
718  if ($this->status != self::STATUS_CANCELED) {
719  return 0;
720  }
721 
722  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
723  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
724  {
725  $this->error='Permission denied';
726  return -1;
727  }*/
728 
729  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'STOCKTRANSFERLINE_REOPEN');
730  }
731 
742  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
743  {
744  global $conf, $langs, $hookmanager;
745 
746  if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips
747 
748  $result = '';
749 
750  $label = '<u>'.$langs->trans("StockTransferLine").'</u>';
751  $label .= '<br>';
752  $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
753  if (isset($this->status)) {
754  $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
755  }
756 
757  $url = dol_buildpath('/stocktransfer/stocktransferline_card.php', 1).'?id='.$this->id;
758 
759  if ($option != 'nolink') {
760  // Add param to save lastsearch_values or not
761  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
762  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1;
763  if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1';
764  }
765 
766  $linkclose = '';
767  if (empty($notooltip)) {
768  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
769  $label = $langs->trans("ShowStockTransferLine");
770  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
771  }
772  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
773  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
774  } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
775 
776  $linkstart = '<a href="'.$url.'"';
777  $linkstart .= $linkclose.'>';
778  $linkend = '</a>';
779 
780  $result .= $linkstart;
781 
782  if (empty($this->showphoto_on_popup)) {
783  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);
784  } else {
785  if ($withpicto) {
786  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
787 
788  list($class, $module) = explode('@', $this->picto);
789  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
790  $filearray = dol_dir_list($upload_dir, "files");
791  $filename = $filearray[0]['name'];
792  if (!empty($filename)) {
793  $pospoint = strpos($filearray[0]['name'], '.');
794 
795  $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
796  if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) {
797  $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>';
798  } else {
799  $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>';
800  }
801 
802  $result .= '</div>';
803  } else {
804  $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);
805  }
806  }
807  }
808 
809  if ($withpicto != 2) $result .= $this->ref;
810 
811  $result .= $linkend;
812  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
813 
814  global $action, $hookmanager;
815  $hookmanager->initHooks(array('stocktransferlinedao'));
816  $parameters = array('id'=>$this->id, 'getnomurl'=>$result);
817  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
818  if ($reshook > 0) $result = $hookmanager->resPrint;
819  else $result .= $hookmanager->resPrint;
820 
821  return $result;
822  }
823 
830  public function getLibStatut($mode = 0)
831  {
832  return $this->LibStatut($this->status, $mode);
833  }
834 
835  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
843  public function LibStatut($status, $mode = 0)
844  {
845  // phpcs:enable
846  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
847  global $langs;
848  //$langs->load("stocktransfer@stocktransfer");
849  $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft');
850  $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Enabled');
851  $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled');
852  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft');
853  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Enabled');
854  $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled');
855  }
856 
857  $statusType = 'status'.$status;
858  //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
859  if ($status == self::STATUS_CANCELED) $statusType = 'status6';
860 
861  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
862  }
863 
870  public function info($id)
871  {
872  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
873  $sql .= ' fk_user_creat, fk_user_modif';
874  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
875  $sql .= ' WHERE t.rowid = '.((int) $id);
876  $result = $this->db->query($sql);
877  if ($result) {
878  if ($this->db->num_rows($result)) {
879  $obj = $this->db->fetch_object($result);
880  $this->id = $obj->rowid;
881 
882  $this->user_creation_id = $obj->fk_user_creat;
883  $this->user_modification_id = $obj->fk_user_modif;
884  $this->date_creation = $this->db->jdate($obj->datec);
885  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
886  }
887 
888  $this->db->free($result);
889  } else {
890  dol_print_error($this->db);
891  }
892  }
893 
900  public function initAsSpecimen()
901  {
902  $this->initAsSpecimenCommon();
903  }
904 
910  public function getLinesArray()
911  {
912  $this->lines = array();
913 
914  $objectline = new StockTransferLineLine($this->db);
915  $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_stocktransferline = '.((int) $this->id)));
916 
917  if (is_numeric($result)) {
918  $this->error = $objectline->error;
919  $this->errors = $objectline->errors;
920  return $result;
921  } else {
922  $this->lines = $result;
923  return $this->lines;
924  }
925  }
926 
932  public function getNextNumRef()
933  {
934  global $langs, $conf;
935  $langs->load("stocks");
936 
937  if (empty($conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON)) {
938  $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON = 'mod_stocktransferline_standard';
939  }
940 
941  if (!empty($conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON)) {
942  $mybool = false;
943 
944  $file = $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON.".php";
945  $classname = $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON;
946 
947  // Include file with class
948  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
949  foreach ($dirmodels as $reldir) {
950  $dir = dol_buildpath($reldir."core/modules/stocktransfer/");
951 
952  // Load file with numbering class (if found)
953  $mybool |= @include_once $dir.$file;
954  }
955 
956  if ($mybool === false) {
957  dol_print_error('', "Failed to include file ".$file);
958  return '';
959  }
960 
961  if (class_exists($classname)) {
962  $obj = new $classname();
963  $numref = $obj->getNextValue($this);
964 
965  if ($numref != '' && $numref != '-1') {
966  return $numref;
967  } else {
968  $this->error = $obj->error;
969  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
970  return "";
971  }
972  } else {
973  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
974  return "";
975  }
976  } else {
977  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
978  return "";
979  }
980  }
981 
993  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
994  {
995  global $conf, $langs;
996 
997  $result = 0;
998  $includedocgeneration = 0;
999 
1000  $langs->load("stocks");
1001 
1002  if (!dol_strlen($modele)) {
1003  $modele = 'standard_stocktransferline';
1004 
1005  if ($this->modelpdf) {
1006  $modele = $this->modelpdf;
1007  } elseif (!empty($conf->global->STOCKTRANSFERLINE_ADDON_PDF)) {
1008  $modele = $conf->global->STOCKTRANSFERLINE_ADDON_PDF;
1009  }
1010  }
1011 
1012  $modelpath = "core/modules/stocktransfer/doc/";
1013 
1014  if ($includedocgeneration) {
1015  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1016  }
1017 
1018  return $result;
1019  }
1020 
1028  public function doScheduledJob()
1029  {
1030  global $conf, $langs;
1031 
1032  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1033 
1034  $error = 0;
1035  $this->output = '';
1036  $this->error = '';
1037 
1038  dol_syslog(__METHOD__, LOG_DEBUG);
1039 
1040  $now = dol_now();
1041 
1042  $this->db->begin();
1043 
1044  // ...
1045 
1046  $this->db->commit();
1047 
1048  return $error;
1049  }
1050 }
1051 
1056 {
1057  // To complete with content of an object StockTransferLineLine
1058  // We should have a field rowid, fk_stocktransferline and position
1059 
1063  public $isextrafieldmanaged = 0;
1064 
1070  public function __construct(DoliDB $db)
1071  {
1072  $this->db = $db;
1073  }
1074 }
$object ref
Definition: info.php:78
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
getFieldList($alias='')
Function to concat keys of fields.
fetchCommon($id, $ref=null, $morewhere='')
Load object in memory from the database.
createCommon(User $user, $notrigger=false)
Create object into database.
deleteCommon(User $user, $notrigger=false, $forcechilddeletion=0)
Delete object in database.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
updateCommon(User $user, $notrigger=false)
Update object into database.
fetchLinesCommon($morewhere='')
Load object in memory from the database.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Dolibarr database access.
Class to manage stock movements.
Class to manage products or services.
Class for StockTransfer.
Class for StockTransferLine.
reopen($user, $notrigger=0)
Set back to validated status.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
getLibStatut($mode=0)
Return label of the status.
setDraft($user, $notrigger=0)
Set draft status.
fetch($id, $ref=null)
Load object in memory from the database.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
__construct(DoliDB $db)
Constructor.
fetchLines()
Load object lines in memory from the database.
create(User $user, $notrigger=false)
Create object into database.
validate($user, $notrigger=0)
Validate object.
update(User $user, $notrigger=false)
Update object into database.
getLinesArray()
Create an array of lines.
cancel($user, $notrigger=0)
Set cancel status.
doStockMovement($label, $code_inv, $fk_entrepot, $direction=1)
Makes all stock movements (add quantity, remove quantity or cancel all actions)
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter=array(), $filtermode='AND')
Load list of objects in memory from the database.
createFromClone(User $user, $fromid)
Clone an object into another one.
LibStatut($status, $mode=0)
Return the status.
info($id)
Load the info information in the object.
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
Class StockTransferLineLine.
__construct(DoliDB $db)
Constructor.
Class to manage Dolibarr users.
Definition: user.class.php:47
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:745
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:61
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
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.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
$conf db
API class for accounts.
Definition: inc.php:41