dolibarr  19.0.0-dev
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) { $error++; $this->error = $this->db->lasterror(); }
583 
584  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
585  $oldref = dol_sanitizeFileName($this->ref);
586  $newref = dol_sanitizeFileName($num);
587  $dirsource = $conf->stocktransfer->dir_output.'/stocktransferline/'.$oldref;
588  $dirdest = $conf->stocktransfer->dir_output.'/stocktransferline/'.$newref;
589  if (!$error && file_exists($dirsource)) {
590  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
591 
592  if (@rename($dirsource, $dirdest)) {
593  dol_syslog("Rename ok");
594  // Rename docs starting with $oldref with $newref
595  $listoffiles = dol_dir_list($conf->stocktransfer->dir_output.'/stocktransferline/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
596  foreach ($listoffiles as $fileentry) {
597  $dirsource = $fileentry['name'];
598  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
599  $dirsource = $fileentry['path'].'/'.$dirsource;
600  $dirdest = $fileentry['path'].'/'.$dirdest;
601  @rename($dirsource, $dirdest);
602  }
603  }
604  }
605  }
606  }
607 
608  // Set new ref and current status
609  if (!$error) {
610  $this->ref = $num;
611  $this->status = self::STATUS_VALIDATED;
612  }
613 
614  if (!$error) {
615  $this->db->commit();
616  return 1;
617  } else {
618  $this->db->rollback();
619  return -1;
620  }
621  }
622 
623 
631  public function setDraft($user, $notrigger = 0)
632  {
633  // Protection
634  if ($this->status <= self::STATUS_DRAFT) {
635  return 0;
636  }
637 
638  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
639  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
640  {
641  $this->error='Permission denied';
642  return -1;
643  }*/
644 
645  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'STOCKTRANSFERLINE_UNVALIDATE');
646  }
647 
655  public function cancel($user, $notrigger = 0)
656  {
657  // Protection
658  if ($this->status != self::STATUS_VALIDATED) {
659  return 0;
660  }
661 
662  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
663  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
664  {
665  $this->error='Permission denied';
666  return -1;
667  }*/
668 
669  return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'STOCKTRANSFERLINE_CLOSE');
670  }
671 
679  public function reopen($user, $notrigger = 0)
680  {
681  // Protection
682  if ($this->status != self::STATUS_CANCELED) {
683  return 0;
684  }
685 
686  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
687  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
688  {
689  $this->error='Permission denied';
690  return -1;
691  }*/
692 
693  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'STOCKTRANSFERLINE_REOPEN');
694  }
695 
706  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
707  {
708  global $conf, $langs, $hookmanager;
709 
710  if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips
711 
712  $result = '';
713 
714  $label = '<u>'.$langs->trans("StockTransferLine").'</u>';
715  $label .= '<br>';
716  $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
717  if (isset($this->status)) {
718  $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
719  }
720 
721  $url = dol_buildpath('/stocktransfer/stocktransferline_card.php', 1).'?id='.$this->id;
722 
723  if ($option != 'nolink') {
724  // Add param to save lastsearch_values or not
725  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
726  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1;
727  if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1';
728  }
729 
730  $linkclose = '';
731  if (empty($notooltip)) {
732  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
733  $label = $langs->trans("ShowStockTransferLine");
734  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
735  }
736  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
737  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
738  } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
739 
740  $linkstart = '<a href="'.$url.'"';
741  $linkstart .= $linkclose.'>';
742  $linkend = '</a>';
743 
744  $result .= $linkstart;
745 
746  if (empty($this->showphoto_on_popup)) {
747  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);
748  } else {
749  if ($withpicto) {
750  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
751 
752  list($class, $module) = explode('@', $this->picto);
753  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
754  $filearray = dol_dir_list($upload_dir, "files");
755  $filename = $filearray[0]['name'];
756  if (!empty($filename)) {
757  $pospoint = strpos($filearray[0]['name'], '.');
758 
759  $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
760  if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
761  $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>';
762  } else {
763  $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>';
764  }
765 
766  $result .= '</div>';
767  } else {
768  $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);
769  }
770  }
771  }
772 
773  if ($withpicto != 2) $result .= $this->ref;
774 
775  $result .= $linkend;
776  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
777 
778  global $action, $hookmanager;
779  $hookmanager->initHooks(array('stocktransferlinedao'));
780  $parameters = array('id'=>$this->id, 'getnomurl'=>$result);
781  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
782  if ($reshook > 0) $result = $hookmanager->resPrint;
783  else $result .= $hookmanager->resPrint;
784 
785  return $result;
786  }
787 
794  public function getLibStatut($mode = 0)
795  {
796  return $this->LibStatut($this->status, $mode);
797  }
798 
799  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
807  public function LibStatut($status, $mode = 0)
808  {
809  // phpcs:enable
810  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
811  global $langs;
812  //$langs->load("stocktransfer@stocktransfer");
813  $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft');
814  $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Enabled');
815  $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled');
816  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft');
817  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Enabled');
818  $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled');
819  }
820 
821  $statusType = 'status'.$status;
822  //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
823  if ($status == self::STATUS_CANCELED) $statusType = 'status6';
824 
825  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
826  }
827 
834  public function info($id)
835  {
836  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
837  $sql .= ' fk_user_creat, fk_user_modif';
838  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
839  $sql .= ' WHERE t.rowid = '.((int) $id);
840  $result = $this->db->query($sql);
841  if ($result) {
842  if ($this->db->num_rows($result)) {
843  $obj = $this->db->fetch_object($result);
844  $this->id = $obj->rowid;
845 
846  $this->user_creation_id = $obj->fk_user_creat;
847  $this->user_modification_id = $obj->fk_user_modif;
848  $this->date_creation = $this->db->jdate($obj->datec);
849  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
850  }
851 
852  $this->db->free($result);
853  } else {
854  dol_print_error($this->db);
855  }
856  }
857 
864  public function initAsSpecimen()
865  {
866  $this->initAsSpecimenCommon();
867  }
868 
874  public function getLinesArray()
875  {
876  $this->lines = array();
877 
878  $objectline = new StockTransferLineLine($this->db);
879  $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_stocktransferline = '.((int) $this->id)));
880 
881  if (is_numeric($result)) {
882  $this->error = $objectline->error;
883  $this->errors = $objectline->errors;
884  return $result;
885  } else {
886  $this->lines = $result;
887  return $this->lines;
888  }
889  }
890 
896  public function getNextNumRef()
897  {
898  global $langs, $conf;
899  $langs->load("stocks");
900 
901  if (empty($conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON)) {
902  $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON = 'mod_stocktransferline_standard';
903  }
904 
905  if (!empty($conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON)) {
906  $mybool = false;
907 
908  $file = $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON.".php";
909  $classname = $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON;
910 
911  // Include file with class
912  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
913  foreach ($dirmodels as $reldir) {
914  $dir = dol_buildpath($reldir."core/modules/stocktransfer/");
915 
916  // Load file with numbering class (if found)
917  $mybool |= @include_once $dir.$file;
918  }
919 
920  if ($mybool === false) {
921  dol_print_error('', "Failed to include file ".$file);
922  return '';
923  }
924 
925  if (class_exists($classname)) {
926  $obj = new $classname();
927  $numref = $obj->getNextValue($this);
928 
929  if ($numref != '' && $numref != '-1') {
930  return $numref;
931  } else {
932  $this->error = $obj->error;
933  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
934  return "";
935  }
936  } else {
937  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
938  return "";
939  }
940  } else {
941  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
942  return "";
943  }
944  }
945 
957  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
958  {
959  global $conf, $langs;
960 
961  $result = 0;
962  $includedocgeneration = 0;
963 
964  $langs->load("stocks");
965 
966  if (!dol_strlen($modele)) {
967  $modele = 'standard_stocktransferline';
968 
969  if ($this->modelpdf) {
970  $modele = $this->modelpdf;
971  } elseif (!empty($conf->global->STOCKTRANSFERLINE_ADDON_PDF)) {
972  $modele = $conf->global->STOCKTRANSFERLINE_ADDON_PDF;
973  }
974  }
975 
976  $modelpath = "core/modules/stocktransfer/doc/";
977 
978  if ($includedocgeneration) {
979  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
980  }
981 
982  return $result;
983  }
984 
992  public function doScheduledJob()
993  {
994  global $conf, $langs;
995 
996  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
997 
998  $error = 0;
999  $this->output = '';
1000  $this->error = '';
1001 
1002  dol_syslog(__METHOD__, LOG_DEBUG);
1003 
1004  $now = dol_now();
1005 
1006  $this->db->begin();
1007 
1008  // ...
1009 
1010  $this->db->commit();
1011 
1012  return $error;
1013  }
1014 }
1015 
1020 {
1021  // To complete with content of an object StockTransferLineLine
1022  // We should have a field rowid, fk_stocktransferline and position
1023 
1027  public $isextrafieldmanaged = 0;
1028 
1034  public function __construct(DoliDB $db)
1035  {
1036  $this->db = $db;
1037  }
1038 }
$object ref
Definition: info.php:78
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
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.
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
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.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.