dolibarr  21.0.0-alpha
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  * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
6  * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
28 // Put here all includes required by your class file
29 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
30 //require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
31 //require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
32 
37 {
41  public $element = 'stocktransferline';
42 
46  public $table_element = 'stocktransfer_stocktransferline';
47 
51  public $picto = 'stocktransferline@stocktransfer';
52 
53  const STATUS_DRAFT = 0;
54  const STATUS_VALIDATED = 1;
55  const STATUS_CANCELED = 9;
56 
57 
83  // BEGIN MODULEBUILDER PROPERTIES
87  public $fields = array(
88  'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'comment' => "Id"),
89  'amount' => array('type' => 'price', 'label' => 'Amount', 'enabled' => 1, 'position' => 40, 'notnull' => 0, 'visible' => 1, 'default' => 'null', 'isameasure' => 1, 'help' => "Help text for amount",),
90  '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",),
91  '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,),
92  '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,),
93  'fk_stocktransfer' => array('type' => 'integer:StockTransfer:stocktransfer/stock/class/stocktransfer.class.php', 'label' => 'StockTransfer', 'enabled' => 1, 'position' => 50, 'notnull' => 1, 'visible' => 0,),
94  'fk_product' => array('type' => 'integer:Product:product/class/product.class.php', 'label' => 'Product', 'enabled' => 1, 'position' => 50, 'notnull' => 1, 'visible' => 1,),
95  'batch' => array('type' => 'varchar(128)', 'label' => 'Batch', 'enabled' => 1, 'position' => 1000, 'notnull' => -1, 'visible' => 1,),
96  'pmp' => array('type' => 'double'/*, 'help'=>'THMEstimatedHelp'*/, 'label' => 'PMP', 'enabled' => 1, 'position' => 50, 'notnull' => 0, 'visible' => 1,),
97  '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",),
98  );
99  public $rowid;
100  public $amount;
101 
105  public $qty;
106  public $fk_warehouse_destination;
107  public $fk_warehouse_source;
108  public $fk_stocktransfer;
109  public $fk_product;
110  public $batch;
111 
115  public $pmp;
116 
117  // END MODULEBUILDER PROPERTIES
118 
119 
125  public function __construct(DoliDB $db)
126  {
127  global $conf, $langs;
128 
129  $this->db = $db;
130 
131  $this->ismultientitymanaged = 0;
132  $this->isextrafieldmanaged = 1;
133 
134  if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
135  $this->fields['rowid']['visible'] = 0;
136  }
137  if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
138  $this->fields['entity']['enabled'] = 0;
139  }
140 
141  // Example to show how to set values of fields definition dynamically
142  /*if ($user->rights->stocktransfer->stocktransferline->read) {
143  $this->fields['myfield']['visible'] = 1;
144  $this->fields['myfield']['noteditable'] = 0;
145  }*/
146 
147  // Unset fields that are disabled
148  foreach ($this->fields as $key => $val) {
149  if (isset($val['enabled']) && empty($val['enabled'])) {
150  unset($this->fields[$key]);
151  }
152  }
153 
154  // Translate some data of arrayofkeyval
155  if (is_object($langs)) {
156  foreach ($this->fields as $key => $val) {
157  if (isset($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
158  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
159  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
160  }
161  }
162  }
163  }
164  }
165 
173  public function create(User $user, $notrigger = 0)
174  {
175  return $this->createCommon($user, $notrigger);
176  }
177 
185  public function createFromClone(User $user, $fromid)
186  {
187  global $langs, $extrafields;
188  $error = 0;
189 
190  dol_syslog(__METHOD__, LOG_DEBUG);
191 
192  $object = new self($this->db);
193 
194  $this->db->begin();
195 
196  // Load source object
197  $result = $object->fetchCommon($fromid);
198  if ($result > 0 && !empty($object->table_element_line)) {
199  $object->fetchLines();
200  }
201 
202  // get lines so they will be clone
203  //foreach($this->lines as $line)
204  // $line->fetch_optionals();
205 
206  // Reset some properties
207  unset($object->id);
208  unset($object->import_key);
209 
210 
211  // Clear fields
212  $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default'];
213  $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
214  $object->status = self::STATUS_DRAFT;
215  // ...
216  // Clear extrafields that are unique
217  if (is_array($object->array_options) && count($object->array_options) > 0) {
218  $extrafields->fetch_name_optionals_label($this->table_element);
219  foreach ($object->array_options as $key => $option) {
220  $shortkey = preg_replace('/options_/', '', $key);
221  if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
222  //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
223  unset($object->array_options[$key]);
224  }
225  }
226  }
227 
228  // Create clone
229  $object->context['createfromclone'] = 'createfromclone';
230  $result = $object->createCommon($user);
231  if ($result < 0) {
232  $error++;
233  $this->error = $object->error;
234  $this->errors = $object->errors;
235  }
236 
237  if (!$error) {
238  // copy internal contacts
239  if ($this->copy_linked_contact($object, 'internal') < 0) {
240  $error++;
241  }
242  }
243 
244  if (!$error) {
245  // copy external contacts if same company
246  if (property_exists($this, 'socid') && $this->socid == $object->socid) {
247  if ($this->copy_linked_contact($object, 'external') < 0) {
248  $error++;
249  }
250  }
251  }
252 
253  unset($object->context['createfromclone']);
254 
255  // End
256  if (!$error) {
257  $this->db->commit();
258  return $object;
259  } else {
260  $this->db->rollback();
261  return -1;
262  }
263  }
264 
272  public function fetch($id, $ref = null)
273  {
274  $result = $this->fetchCommon($id, $ref);
275  if ($result > 0 && !empty($this->table_element_line)) {
276  $this->fetchLines();
277  }
278  return $result;
279  }
280 
286  public function fetchLines()
287  {
288  $this->lines = array();
289 
290  $result = $this->fetchLinesCommon();
291  return $result;
292  }
293 
294 
307  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
308  {
309  dol_syslog(__METHOD__, LOG_DEBUG);
310 
311  $records = array();
312 
313  $sql = 'SELECT ';
314  $sql .= $this->getFieldList();
315  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
316  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
317  $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
318  } else {
319  $sql .= ' WHERE 1 = 1';
320  }
321 
322  // Manage filter
323  $errormessage = '';
324  $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
325  if ($errormessage) {
326  $this->errors[] = $errormessage;
327  dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
328  return -1;
329  }
330 
331  if (!empty($sortfield)) {
332  $sql .= $this->db->order($sortfield, $sortorder);
333  }
334  if (!empty($limit)) {
335  $sql .= ' '.$this->db->plimit($limit, $offset);
336  }
337 
338  $resql = $this->db->query($sql);
339  if ($resql) {
340  $num = $this->db->num_rows($resql);
341  $i = 0;
342  while ($i < ($limit ? min($limit, $num) : $num)) {
343  $obj = $this->db->fetch_object($resql);
344 
345  $record = new self($this->db);
346  $record->setVarsFromFetchObj($obj);
347 
348  $records[$record->id] = $record;
349 
350  $i++;
351  }
352  $this->db->free($resql);
353 
354  return $records;
355  } else {
356  $this->errors[] = 'Error '.$this->db->lasterror();
357  dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
358 
359  return -1;
360  }
361  }
362 
370  public function update(User $user, $notrigger = 0)
371  {
372  return $this->updateCommon($user, $notrigger);
373  }
374 
382  public function delete(User $user, $notrigger = 0)
383  {
384  return $this->deleteCommon($user, $notrigger);
385  //return $this->deleteCommon($user, $notrigger, 1);
386  }
387 
396  public function deleteLine(User $user, $idline, $notrigger = 0)
397  {
398  if ($this->status < 0) {
399  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
400  return -2;
401  }
402 
403  return $this->deleteLineCommon($user, $idline, $notrigger);
404  }
405 
415  public function doStockMovement($label, $code_inv, $fk_entrepot, $direction = 1)
416  {
417  global $user, $langs;
418 
419  require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
420  include_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php';
421  include_once DOL_DOCUMENT_ROOT . '/product/stock/stocktransfer/class/stocktransfer.class.php';
422 
423  $p = new Product($this->db);
424  $p->fetch($this->fk_product);
425 
426  $op = array();
427  $op[0] = "+".trim((string) $this->qty);
428  $op[1] = "-".trim((string) $this->qty);
429  $movementstock = new MouvementStock($this->db);
430  $st = new StockTransfer($this->db);
431  $movementstock->origin_type = $st->origin_type;
432  $movementstock->origin_id = $this->fk_stocktransfer;
433 
434  if (empty($this->batch)) { // no batch for line
435  $result = $movementstock->_create(
436  $user,
437  $p->id,
438  $fk_entrepot,
439  $op[$direction],
440  $direction,
441  empty($direction) ? $this->pmp : 0,
442  $label,
443  $code_inv
444  );
445 
446  if ($result < 0) {
447  $this->setErrorsFromObject($movementstock);
448  return -1;
449  }
450  } else {
451  if ($p->hasbatch()) {
452  $arraybatchinfo = $p->loadBatchInfo($this->batch);
453  if (count($arraybatchinfo) > 0) {
454  $firstrecord = array_shift($arraybatchinfo);
455  $dlc = $firstrecord['eatby'];
456  $dluo = $firstrecord['sellby'];
457  } else {
458  $dlc = '';
459  $dluo = '';
460  }
461 
462  $result = $movementstock->_create(
463  $user,
464  $p->id,
465  $fk_entrepot,
466  $op[$direction],
467  $direction,
468  empty($direction) ? $this->pmp : 0,
469  $label,
470  $code_inv,
471  '',
472  $dlc,
473  $dluo,
474  $this->batch
475  );
476 
477  if ($result < 0) {
478  $this->setErrorsFromObject($movementstock);
479  return $result;
480  }
481  } else {
482  $this->error=$langs->trans('StockTransferNoBatchForProduct', $p->getNomUrl());
483  $this->errors[]= $this->error;
484  return -1;
485  }
486  }
487 
488  return 1;
489  }
490 
498  public function validate($user, $notrigger = 0)
499  {
500  global $conf, $langs;
501 
502  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
503 
504  $error = 0;
505 
506  // Protection
507  if ($this->status == self::STATUS_VALIDATED) {
508  dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
509  return 0;
510  }
511 
512  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransferline->write))
513  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransferline->stocktransferline_advance->validate))))
514  {
515  $this->error='NotEnoughPermissions';
516  dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
517  return -1;
518  }*/
519 
520  $now = dol_now();
521 
522  $this->db->begin();
523 
524  // Define new ref
525  if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
526  $num = $this->getNextNumRef();
527  } else {
528  $num = $this->ref;
529  }
530  $this->newref = $num;
531 
532  if (!empty($num)) {
533  // Validate
534  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
535  $sql .= " SET ref = '".$this->db->escape($num)."',";
536  $sql .= " status = ".self::STATUS_VALIDATED;
537  if (!empty($this->fields['date_validation'])) {
538  $sql .= ", date_validation = '".$this->db->idate($now)."',";
539  }
540  if (!empty($this->fields['fk_user_valid'])) {
541  $sql .= ", fk_user_valid = ".((int) $user->id);
542  }
543  $sql .= " WHERE rowid = ".((int) $this->id);
544 
545  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
546  $resql = $this->db->query($sql);
547  if (!$resql) {
548  dol_print_error($this->db);
549  $this->error = $this->db->lasterror();
550  $error++;
551  }
552 
553  if (!$error && !$notrigger) {
554  // Call trigger
555  $result = $this->call_trigger('STOCKTRANSFERLINE_VALIDATE', $user);
556  if ($result < 0) {
557  $error++;
558  }
559  // End call triggers
560  }
561  }
562 
563  if (!$error) {
564  $this->oldref = $this->ref;
565 
566  // Rename directory if dir was a temporary ref
567  if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
568  // Now we rename also files into index
569  $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)."'";
570  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransferline/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity);
571  $resql = $this->db->query($sql);
572  if (!$resql) {
573  $error++;
574  $this->error = $this->db->lasterror();
575  }
576  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'stocktransferline/".$this->db->escape($this->newref)."'";
577  $sql .= " WHERE filepath = 'stocktransferline/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
578  $resql = $this->db->query($sql);
579  if (!$resql) {
580  $error++;
581  $this->error = $this->db->lasterror();
582  }
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)) {
711  $notooltip = 1;
712  } // Force disable tooltips
713 
714  $result = '';
715 
716  $label = '<u>'.$langs->trans("StockTransferLine").'</u>';
717  $label .= '<br>';
718  $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
719  if (isset($this->status)) {
720  $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
721  }
722 
723  $url = dol_buildpath('/stocktransfer/stocktransferline_card.php', 1).'?id='.$this->id;
724 
725  if ($option != 'nolink') {
726  // Add param to save lastsearch_values or not
727  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
728  if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
729  $add_save_lastsearch_values = 1;
730  }
731  if ($add_save_lastsearch_values) {
732  $url .= '&save_lastsearch_values=1';
733  }
734  }
735 
736  $linkclose = '';
737  if (empty($notooltip)) {
738  if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
739  $label = $langs->trans("ShowStockTransferLine");
740  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
741  }
742  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
743  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
744  } else {
745  $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
746  }
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) {
756  $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);
757  }
758  } else {
759  if ($withpicto) {
760  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
761 
762  list($class, $module) = explode('@', $this->picto);
763  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
764  $filearray = dol_dir_list($upload_dir, "files");
765  $filename = $filearray[0]['name'];
766  if (!empty($filename)) {
767  $pospoint = strpos($filearray[0]['name'], '.');
768 
769  $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
770  if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
771  $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><div class="photoref"><img class="photo'.$module.'" alt="No photo" border="0" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$module.'&entity='.$conf->entity.'&file='.urlencode($pathtophoto).'"></div></div>';
772  } else {
773  $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><img class="photouserphoto userphoto" alt="No photo" border="0" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$module.'&entity='.$conf->entity.'&file='.urlencode($pathtophoto).'"></div>';
774  }
775 
776  $result .= '</div>';
777  } else {
778  $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
779  }
780  }
781  }
782 
783  if ($withpicto != 2) {
784  $result .= $this->ref;
785  }
786 
787  $result .= $linkend;
788  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
789 
790  global $action, $hookmanager;
791  $hookmanager->initHooks(array('stocktransferlinedao'));
792  $parameters = array('id' => $this->id, 'getnomurl' => $result);
793  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
794  if ($reshook > 0) {
795  $result = $hookmanager->resPrint;
796  } else {
797  $result .= $hookmanager->resPrint;
798  }
799 
800  return $result;
801  }
802 
809  public function getLibStatut($mode = 0)
810  {
811  return $this->LibStatut($this->status, $mode);
812  }
813 
814  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
822  public function LibStatut($status, $mode = 0)
823  {
824  // phpcs:enable
825  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
826  global $langs;
827  //$langs->load("stocktransfer@stocktransfer");
828  $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft');
829  $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Enabled');
830  $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled');
831  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft');
832  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Enabled');
833  $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled');
834  }
835 
836  $statusType = 'status'.$status;
837  //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
838  if ($status == self::STATUS_CANCELED) {
839  $statusType = 'status6';
840  }
841 
842  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
843  }
844 
851  public function info($id)
852  {
853  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
854  $sql .= ' fk_user_creat, fk_user_modif';
855  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
856  $sql .= ' WHERE t.rowid = '.((int) $id);
857  $result = $this->db->query($sql);
858  if ($result) {
859  if ($this->db->num_rows($result)) {
860  $obj = $this->db->fetch_object($result);
861  $this->id = $obj->rowid;
862 
863  $this->user_creation_id = $obj->fk_user_creat;
864  $this->user_modification_id = $obj->fk_user_modif;
865  $this->date_creation = $this->db->jdate($obj->datec);
866  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
867  }
868 
869  $this->db->free($result);
870  } else {
871  dol_print_error($this->db);
872  }
873  }
874 
881  public function initAsSpecimen()
882  {
883  return $this->initAsSpecimenCommon();
884  }
885 
891  public function getNextNumRef()
892  {
893  global $langs, $conf;
894  $langs->load("stocks");
895 
896  if (!getDolGlobalString('STOCKTRANSFER_STOCKTRANSFERLINE_ADDON')) {
897  $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON = 'mod_stocktransferline_standard';
898  }
899 
900  if (getDolGlobalString('STOCKTRANSFER_STOCKTRANSFERLINE_ADDON')) {
901  $mybool = false;
902 
903  $file = getDolGlobalString('STOCKTRANSFER_STOCKTRANSFERLINE_ADDON') . ".php";
904  $classname = getDolGlobalString('STOCKTRANSFER_STOCKTRANSFERLINE_ADDON');
905 
906  // Include file with class
907  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
908  foreach ($dirmodels as $reldir) {
909  $dir = dol_buildpath($reldir."core/modules/stocktransfer/");
910 
911  // Load file with numbering class (if found)
912  $mybool = ((bool) @include_once $dir.$file) || $mybool;
913  }
914 
915  if ($mybool === false) {
916  dol_print_error(null, "Failed to include file ".$file);
917  return '';
918  }
919 
920  if (class_exists($classname)) {
921  $obj = new $classname();
922  $numref = $obj->getNextValue($this);
923 
924  if ($numref != '' && $numref != '-1') {
925  return $numref;
926  } else {
927  $this->error = $obj->error;
928  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
929  return "";
930  }
931  } else {
932  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
933  return "";
934  }
935  } else {
936  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
937  return "";
938  }
939  }
940 
952  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
953  {
954  global $conf, $langs;
955 
956  $result = 0;
957  $includedocgeneration = 0;
958 
959  $langs->load("stocks");
960 
961  if (!dol_strlen($modele)) {
962  $modele = 'standard_stocktransferline';
963 
964  if (!empty($this->model_pdf)) {
965  $modele = $this->model_pdf;
966  } elseif (getDolGlobalString('STOCKTRANSFERLINE_ADDON_PDF')) {
967  $modele = getDolGlobalString('STOCKTRANSFERLINE_ADDON_PDF');
968  }
969  }
970 
971  $modelpath = "core/modules/stocktransfer/doc/";
972 
973  if ($includedocgeneration) {
974  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
975  }
976 
977  return $result;
978  }
979 
987  public function doScheduledJob()
988  {
989  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
990 
991  $error = 0;
992  $this->output = '';
993  $this->error = '';
994 
995  dol_syslog(__METHOD__, LOG_DEBUG);
996 
997  $now = dol_now();
998 
999  $this->db->begin();
1000 
1001  // ...
1002 
1003  $this->db->commit();
1004 
1005  return $error;
1006  }
1007 }
if($user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition: card.php:58
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition: security.php:624
$object ref
Definition: info.php:79
deleteLineCommon(User $user, $idline, $notrigger=0)
Delete a line of object in database.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
setErrorsFromObject($object)
setErrorsFromObject
createCommon(User $user, $notrigger=0)
Create object in the database.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
updateCommon(User $user, $notrigger=0)
Update object into 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.
fetchLinesCommon($morewhere='', $noextrafields=0)
Load object in memory from the database.
fetchCommon($id, $ref=null, $morewhere='', $noextrafields=0)
Load object in memory from the database.
deleteCommon(User $user, $notrigger=0, $forcechilddeletion=0)
Delete object in 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.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter='', $filtermode='AND')
Load list of objects 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.
validate($user, $notrigger=0)
Validate object.
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.
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.
update(User $user, $notrigger=0)
Update object into database.
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 optionally the picto)
create(User $user, $notrigger=0)
Create object into database.
deleteLine(User $user, $idline, $notrigger=0)
Delete a line of object in database.
Class to manage Dolibarr users.
Definition: user.class.php:50
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('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') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:751
dol_dir_list($utf8_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:63
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
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.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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.