dolibarr  18.0.6
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 
125  public function __construct(DoliDB $db)
126  {
127  global $conf, $langs;
128 
129  $this->db = $db;
130 
131  if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) $this->fields['rowid']['visible'] = 0;
132  if (!isModEnabled('multicompany') && isset($this->fields['entity'])) $this->fields['entity']['enabled'] = 0;
133 
134  // Example to show how to set values of fields definition dynamically
135  /*if ($user->rights->stocktransfer->stocktransferline->read) {
136  $this->fields['myfield']['visible'] = 1;
137  $this->fields['myfield']['noteditable'] = 0;
138  }*/
139 
140  // Unset fields that are disabled
141  foreach ($this->fields as $key => $val) {
142  if (isset($val['enabled']) && empty($val['enabled'])) {
143  unset($this->fields[$key]);
144  }
145  }
146 
147  // Translate some data of arrayofkeyval
148  if (is_object($langs)) {
149  foreach ($this->fields as $key => $val) {
150  if (is_array($val['arrayofkeyval'])) {
151  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
152  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
153  }
154  }
155  }
156  }
157  }
158 
166  public function create(User $user, $notrigger = false)
167  {
168  return $this->createCommon($user, $notrigger);
169  }
170 
178  public function createFromClone(User $user, $fromid)
179  {
180  global $langs, $extrafields;
181  $error = 0;
182 
183  dol_syslog(__METHOD__, LOG_DEBUG);
184 
185  $object = new self($this->db);
186 
187  $this->db->begin();
188 
189  // Load source object
190  $result = $object->fetchCommon($fromid);
191  if ($result > 0 && !empty($object->table_element_line)) $object->fetchLines();
192 
193  // get lines so they will be clone
194  //foreach($this->lines as $line)
195  // $line->fetch_optionals();
196 
197  // Reset some properties
198  unset($object->id);
199  unset($object->import_key);
200 
201 
202  // Clear fields
203  $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default'];
204  $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
205  $object->status = self::STATUS_DRAFT;
206  // ...
207  // Clear extrafields that are unique
208  if (is_array($object->array_options) && count($object->array_options) > 0) {
209  $extrafields->fetch_name_optionals_label($this->table_element);
210  foreach ($object->array_options as $key => $option) {
211  $shortkey = preg_replace('/options_/', '', $key);
212  if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
213  //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
214  unset($object->array_options[$key]);
215  }
216  }
217  }
218 
219  // Create clone
220  $object->context['createfromclone'] = 'createfromclone';
221  $result = $object->createCommon($user);
222  if ($result < 0) {
223  $error++;
224  $this->error = $object->error;
225  $this->errors = $object->errors;
226  }
227 
228  if (!$error) {
229  // copy internal contacts
230  if ($this->copy_linked_contact($object, 'internal') < 0) {
231  $error++;
232  }
233  }
234 
235  if (!$error) {
236  // copy external contacts if same company
237  if (property_exists($this, 'socid') && $this->socid == $object->socid) {
238  if ($this->copy_linked_contact($object, 'external') < 0)
239  $error++;
240  }
241  }
242 
243  unset($object->context['createfromclone']);
244 
245  // End
246  if (!$error) {
247  $this->db->commit();
248  return $object;
249  } else {
250  $this->db->rollback();
251  return -1;
252  }
253  }
254 
262  public function fetch($id, $ref = null)
263  {
264  $result = $this->fetchCommon($id, $ref);
265  if ($result > 0 && !empty($this->table_element_line)) $this->fetchLines();
266  return $result;
267  }
268 
274  public function fetchLines()
275  {
276  $this->lines = array();
277 
278  $result = $this->fetchLinesCommon();
279  return $result;
280  }
281 
282 
294  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
295  {
296  global $conf;
297 
298  dol_syslog(__METHOD__, LOG_DEBUG);
299 
300  $records = array();
301 
302  $sql = 'SELECT ';
303  $sql .= $this->getFieldList();
304  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
305  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
306  else $sql .= ' WHERE 1 = 1';
307  // Manage filter
308  $sqlwhere = array();
309  if (count($filter) > 0) {
310  foreach ($filter as $key => $value) {
311  if ($key == 't.rowid') {
312  $sqlwhere[] = $key.'='.$value;
313  } elseif (strpos($key, 'date') !== false) {
314  $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\'';
315  } elseif ($key == 'customsql') {
316  $sqlwhere[] = $value;
317  } else {
318  $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\'';
319  }
320  }
321  }
322  if (count($sqlwhere) > 0) {
323  $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")";
324  }
325 
326  if (!empty($sortfield)) {
327  $sql .= $this->db->order($sortfield, $sortorder);
328  }
329  if (!empty($limit)) {
330  $sql .= ' '.$this->db->plimit($limit, $offset);
331  }
332 
333  $resql = $this->db->query($sql);
334  if ($resql) {
335  $num = $this->db->num_rows($resql);
336  $i = 0;
337  while ($i < ($limit ? min($limit, $num) : $num)) {
338  $obj = $this->db->fetch_object($resql);
339 
340  $record = new self($this->db);
341  $record->setVarsFromFetchObj($obj);
342 
343  $records[$record->id] = $record;
344 
345  $i++;
346  }
347  $this->db->free($resql);
348 
349  return $records;
350  } else {
351  $this->errors[] = 'Error '.$this->db->lasterror();
352  dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
353 
354  return -1;
355  }
356  }
357 
365  public function update(User $user, $notrigger = false)
366  {
367  return $this->updateCommon($user, $notrigger);
368  }
369 
377  public function delete(User $user, $notrigger = false)
378  {
379  return $this->deleteCommon($user, $notrigger);
380  //return $this->deleteCommon($user, $notrigger, 1);
381  }
382 
391  public function deleteLine(User $user, $idline, $notrigger = false)
392  {
393  if ($this->status < 0) {
394  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
395  return -2;
396  }
397 
398  return $this->deleteLineCommon($user, $idline, $notrigger);
399  }
400 
410  public function doStockMovement($label, $code_inv, $fk_entrepot, $direction = 1)
411  {
412 
413  global $conf, $user, $langs;
414 
415  require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
416  include_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php';
417  include_once DOL_DOCUMENT_ROOT . '/product/stock/stocktransfer/class/stocktransfer.class.php';
418 
419  $p = new Product($this->db);
420  $p->fetch($this->fk_product);
421 
422  $op[0] = "+".trim($this->qty);
423  $op[1] = "-".trim($this->qty);
424  $movementstock = new MouvementStock($this->db);
425  $st = new StockTransfer($this->db);
426  $movementstock->origin_type = $st->origin_type;
427  $movementstock->origin_id = $this->fk_stocktransfer;
428 
429  if (empty($this->batch)) { // no batch for line
430  /*$result = $p->correct_stock(
431  $user,
432  $fk_entrepot,
433  $this->qty,
434  $direction, // 1=décrémentation
435  $label,
436  empty($direction) ? $this->pmp : 0,
437  GETPOST('inventorycode', 'alphanohtml'),
438  'stocktransfer',
439  $this->fk_stocktransfer
440  );*/
441 
442  $result = $movementstock->_create($user,
443  $p->id,
444  $fk_entrepot,
445  $op[$direction],
446  $direction,
447  empty($direction) ? $this->pmp : 0,
448  $label,
449  $code_inv);
450 
451  if ($result < 0) {
452  setEventMessages($p->errors, $p->errorss, 'errors');
453  return 0;
454  }
455  } else {
456  if ($p->hasbatch()) {
457  $arraybatchinfo = $p->loadBatchInfo($this->batch);
458  if (count($arraybatchinfo) > 0) {
459  $firstrecord = array_shift($arraybatchinfo);
460  $dlc = $firstrecord['eatby'];
461  $dluo = $firstrecord['sellby'];
462  //var_dump($batch); var_dump($arraybatchinfo); var_dump($firstrecord); var_dump($dlc); var_dump($dluo); exit;
463  } else {
464  $dlc = '';
465  $dluo = '';
466  }
467 
468  /*$result = $p->correct_stock_batch(
469  $user,
470  $fk_entrepot,
471  $this->qty,
472  $direction,
473  $label,
474  empty($direction) ? $this->pmp : 0,
475  $dlc,
476  $dluo,
477  $this->batch,
478  GETPOST("codemove")
479  );*/
480 
481  $result = $movementstock->_create($user,
482  $p->id,
483  $fk_entrepot,
484  $op[$direction],
485  $direction,
486  empty($direction) ? $this->pmp : 0,
487  $label,
488  $code_inv,
489  '',
490  $dlc,
491  $dluo,
492  $this->batch);
493 
494  if ($result < 0) {
495  setEventMessages($p->errors, $p->errorss, 'errors');
496  return 0;
497  }
498  } else {
499  setEventMessages($langs->trans('StockTransferNoBatchForProduct', $p->getNomUrl()), '', 'errors');
500  return -1;
501  }
502  }
503 
504  return 1;
505  }
506 
514  public function validate($user, $notrigger = 0)
515  {
516  global $conf, $langs;
517 
518  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
519 
520  $error = 0;
521 
522  // Protection
523  if ($this->status == self::STATUS_VALIDATED) {
524  dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
525  return 0;
526  }
527 
528  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransferline->write))
529  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransferline->stocktransferline_advance->validate))))
530  {
531  $this->error='NotEnoughPermissions';
532  dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
533  return -1;
534  }*/
535 
536  $now = dol_now();
537 
538  $this->db->begin();
539 
540  // Define new ref
541  if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
542  $num = $this->getNextNumRef();
543  } else {
544  $num = $this->ref;
545  }
546  $this->newref = $num;
547 
548  if (!empty($num)) {
549  // Validate
550  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
551  $sql .= " SET ref = '".$this->db->escape($num)."',";
552  $sql .= " status = ".self::STATUS_VALIDATED;
553  if (!empty($this->fields['date_validation'])) $sql .= ", date_validation = '".$this->db->idate($now)."',";
554  if (!empty($this->fields['fk_user_valid'])) $sql .= ", fk_user_valid = ".((int) $user->id);
555  $sql .= " WHERE rowid = ".((int) $this->id);
556 
557  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
558  $resql = $this->db->query($sql);
559  if (!$resql) {
560  dol_print_error($this->db);
561  $this->error = $this->db->lasterror();
562  $error++;
563  }
564 
565  if (!$error && !$notrigger) {
566  // Call trigger
567  $result = $this->call_trigger('STOCKTRANSFERLINE_VALIDATE', $user);
568  if ($result < 0) $error++;
569  // End call triggers
570  }
571  }
572 
573  if (!$error) {
574  $this->oldref = $this->ref;
575 
576  // Rename directory if dir was a temporary ref
577  if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
578  // Now we rename also files into index
579  $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)."'";
580  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransferline/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity);
581  $resql = $this->db->query($sql);
582  if (!$resql) {
583  $error++; $this->error = $this->db->lasterror();
584  }
585  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'stocktransferline/".$this->db->escape($this->newref)."'";
586  $sql .= " WHERE filepath = 'stocktransferline/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
587  $resql = $this->db->query($sql);
588  if (!$resql) {
589  $error++; $this->error = $this->db->lasterror();
590  }
591 
592  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
593  $oldref = dol_sanitizeFileName($this->ref);
594  $newref = dol_sanitizeFileName($num);
595  $dirsource = $conf->stocktransfer->dir_output.'/stocktransferline/'.$oldref;
596  $dirdest = $conf->stocktransfer->dir_output.'/stocktransferline/'.$newref;
597  if (!$error && file_exists($dirsource)) {
598  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
599 
600  if (@rename($dirsource, $dirdest)) {
601  dol_syslog("Rename ok");
602  // Rename docs starting with $oldref with $newref
603  $listoffiles = dol_dir_list($conf->stocktransfer->dir_output.'/stocktransferline/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
604  foreach ($listoffiles as $fileentry) {
605  $dirsource = $fileentry['name'];
606  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
607  $dirsource = $fileentry['path'].'/'.$dirsource;
608  $dirdest = $fileentry['path'].'/'.$dirdest;
609  @rename($dirsource, $dirdest);
610  }
611  }
612  }
613  }
614  }
615 
616  // Set new ref and current status
617  if (!$error) {
618  $this->ref = $num;
619  $this->status = self::STATUS_VALIDATED;
620  }
621 
622  if (!$error) {
623  $this->db->commit();
624  return 1;
625  } else {
626  $this->db->rollback();
627  return -1;
628  }
629  }
630 
631 
639  public function setDraft($user, $notrigger = 0)
640  {
641  // Protection
642  if ($this->status <= self::STATUS_DRAFT) {
643  return 0;
644  }
645 
646  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
647  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
648  {
649  $this->error='Permission denied';
650  return -1;
651  }*/
652 
653  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'STOCKTRANSFERLINE_UNVALIDATE');
654  }
655 
663  public function cancel($user, $notrigger = 0)
664  {
665  // Protection
666  if ($this->status != self::STATUS_VALIDATED) {
667  return 0;
668  }
669 
670  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
671  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
672  {
673  $this->error='Permission denied';
674  return -1;
675  }*/
676 
677  return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'STOCKTRANSFERLINE_CLOSE');
678  }
679 
687  public function reopen($user, $notrigger = 0)
688  {
689  // Protection
690  if ($this->status != self::STATUS_CANCELED) {
691  return 0;
692  }
693 
694  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
695  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
696  {
697  $this->error='Permission denied';
698  return -1;
699  }*/
700 
701  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'STOCKTRANSFERLINE_REOPEN');
702  }
703 
714  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
715  {
716  global $conf, $langs, $hookmanager;
717 
718  if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips
719 
720  $result = '';
721 
722  $label = '<u>'.$langs->trans("StockTransferLine").'</u>';
723  $label .= '<br>';
724  $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
725  if (isset($this->status)) {
726  $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
727  }
728 
729  $url = dol_buildpath('/stocktransfer/stocktransferline_card.php', 1).'?id='.$this->id;
730 
731  if ($option != 'nolink') {
732  // Add param to save lastsearch_values or not
733  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
734  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1;
735  if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1';
736  }
737 
738  $linkclose = '';
739  if (empty($notooltip)) {
740  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
741  $label = $langs->trans("ShowStockTransferLine");
742  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
743  }
744  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
745  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
746  } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
747 
748  $linkstart = '<a href="'.$url.'"';
749  $linkstart .= $linkclose.'>';
750  $linkend = '</a>';
751 
752  $result .= $linkstart;
753 
754  if (empty($this->showphoto_on_popup)) {
755  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);
756  } else {
757  if ($withpicto) {
758  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
759 
760  list($class, $module) = explode('@', $this->picto);
761  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
762  $filearray = dol_dir_list($upload_dir, "files");
763  $filename = $filearray[0]['name'];
764  if (!empty($filename)) {
765  $pospoint = strpos($filearray[0]['name'], '.');
766 
767  $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
768  if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) {
769  $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>';
770  } else {
771  $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>';
772  }
773 
774  $result .= '</div>';
775  } else {
776  $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);
777  }
778  }
779  }
780 
781  if ($withpicto != 2) $result .= $this->ref;
782 
783  $result .= $linkend;
784  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
785 
786  global $action, $hookmanager;
787  $hookmanager->initHooks(array('stocktransferlinedao'));
788  $parameters = array('id'=>$this->id, 'getnomurl'=>$result);
789  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
790  if ($reshook > 0) $result = $hookmanager->resPrint;
791  else $result .= $hookmanager->resPrint;
792 
793  return $result;
794  }
795 
802  public function getLibStatut($mode = 0)
803  {
804  return $this->LibStatut($this->status, $mode);
805  }
806 
807  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
815  public function LibStatut($status, $mode = 0)
816  {
817  // phpcs:enable
818  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
819  global $langs;
820  //$langs->load("stocktransfer@stocktransfer");
821  $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft');
822  $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Enabled');
823  $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled');
824  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft');
825  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Enabled');
826  $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled');
827  }
828 
829  $statusType = 'status'.$status;
830  //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
831  if ($status == self::STATUS_CANCELED) $statusType = 'status6';
832 
833  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
834  }
835 
842  public function info($id)
843  {
844  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
845  $sql .= ' fk_user_creat, fk_user_modif';
846  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
847  $sql .= ' WHERE t.rowid = '.((int) $id);
848  $result = $this->db->query($sql);
849  if ($result) {
850  if ($this->db->num_rows($result)) {
851  $obj = $this->db->fetch_object($result);
852  $this->id = $obj->rowid;
853 
854  $this->user_creation_id = $obj->fk_user_creat;
855  $this->user_modification_id = $obj->fk_user_modif;
856  $this->date_creation = $this->db->jdate($obj->datec);
857  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
858  }
859 
860  $this->db->free($result);
861  } else {
862  dol_print_error($this->db);
863  }
864  }
865 
872  public function initAsSpecimen()
873  {
874  $this->initAsSpecimenCommon();
875  }
876 
882  public function getLinesArray()
883  {
884  $this->lines = array();
885 
886  $objectline = new StockTransferLineLine($this->db);
887  $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_stocktransferline = '.((int) $this->id)));
888 
889  if (is_numeric($result)) {
890  $this->error = $objectline->error;
891  $this->errors = $objectline->errors;
892  return $result;
893  } else {
894  $this->lines = $result;
895  return $this->lines;
896  }
897  }
898 
904  public function getNextNumRef()
905  {
906  global $langs, $conf;
907  $langs->load("stocks");
908 
909  if (empty($conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON)) {
910  $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON = 'mod_stocktransferline_standard';
911  }
912 
913  if (!empty($conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON)) {
914  $mybool = false;
915 
916  $file = $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON.".php";
917  $classname = $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON;
918 
919  // Include file with class
920  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
921  foreach ($dirmodels as $reldir) {
922  $dir = dol_buildpath($reldir."core/modules/stocktransfer/");
923 
924  // Load file with numbering class (if found)
925  $mybool |= @include_once $dir.$file;
926  }
927 
928  if ($mybool === false) {
929  dol_print_error('', "Failed to include file ".$file);
930  return '';
931  }
932 
933  if (class_exists($classname)) {
934  $obj = new $classname();
935  $numref = $obj->getNextValue($this);
936 
937  if ($numref != '' && $numref != '-1') {
938  return $numref;
939  } else {
940  $this->error = $obj->error;
941  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
942  return "";
943  }
944  } else {
945  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
946  return "";
947  }
948  } else {
949  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
950  return "";
951  }
952  }
953 
965  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
966  {
967  global $conf, $langs;
968 
969  $result = 0;
970  $includedocgeneration = 0;
971 
972  $langs->load("stocks");
973 
974  if (!dol_strlen($modele)) {
975  $modele = 'standard_stocktransferline';
976 
977  if ($this->modelpdf) {
978  $modele = $this->modelpdf;
979  } elseif (!empty($conf->global->STOCKTRANSFERLINE_ADDON_PDF)) {
980  $modele = $conf->global->STOCKTRANSFERLINE_ADDON_PDF;
981  }
982  }
983 
984  $modelpath = "core/modules/stocktransfer/doc/";
985 
986  if ($includedocgeneration) {
987  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
988  }
989 
990  return $result;
991  }
992 
1000  public function doScheduledJob()
1001  {
1002  global $conf, $langs;
1003 
1004  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1005 
1006  $error = 0;
1007  $this->output = '';
1008  $this->error = '';
1009 
1010  dol_syslog(__METHOD__, LOG_DEBUG);
1011 
1012  $now = dol_now();
1013 
1014  $this->db->begin();
1015 
1016  // ...
1017 
1018  $this->db->commit();
1019 
1020  return $error;
1021  }
1022 }
1023 
1028 {
1029  // To complete with content of an object StockTransferLineLine
1030  // We should have a field rowid, fk_stocktransferline and position
1031 
1035  public $isextrafieldmanaged = 0;
1036 
1042  public function __construct(DoliDB $db)
1043  {
1044  $this->db = $db;
1045  }
1046 }
$object ref
Definition: info.php:78
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.
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:48
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.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
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.