dolibarr 18.0.6
stocktransfer.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
4 * Copyright (C) 2022 Frédéric France <frederic.france@netlogic.fr>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
26// Put here all includes required by your class file
27require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
28require_once DOL_DOCUMENT_ROOT.'/core/class/commonincoterm.class.php';
29
30//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
31//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
32
37{
42 public $element = 'stocktransfer';
43
47 public $table_element = 'stocktransfer_stocktransfer';
48
53 public $ismultientitymanaged = 0;
54
58 public $isextrafieldmanaged = 1;
59
63 public $table_element_line = 'stocktransfer_stocktransferline';
64
68 public $fk_element = 'fk_stocktransfer';
69
75 protected $childtablesoncascade = array('stocktransfer_stocktransferline');
76
82 public $ref_client;
83
87 public $ref_customer;
88
89
93 public $picto = 'stock';
94
95 public $date_prevue_depart;
96 public $date_prevue_arrivee;
97 public $date_reelle_depart;
98 public $date_reelle_arrivee;
99
100
101 const STATUS_DRAFT = 0;
102 const STATUS_VALIDATED = 1;
103 const STATUS_TRANSFERED = 2;
104 const STATUS_CLOSED = 3;
105
106
132 // BEGIN MODULEBUILDER PROPERTIES
136 public $fields=array(
137 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"),
138 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>'1', 'position'=>1, 'default'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"),
139 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>4, 'noteditable'=>'1', 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object"),
140 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>0, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth200'/*, 'help'=>"Help text"*/, 'showoncombobox'=>'1',),
141 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>31, 'notnull'=>0, 'visible'=>3,),
142 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'enabled'=>'$conf->project->enabled', 'position'=>32, 'notnull'=>-1, 'visible'=>-1, 'index'=>1,),
143 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'label'=>'ThirdParty', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1/*, 'help'=>"LinkToThirdparty"*/,),
144 'fk_warehouse_source' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Entrepôt source', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1, 'help'=>'HelpWarehouseStockTransferSource',),
145 'fk_warehouse_destination' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Entrepôt de destination', 'enabled'=>'1', 'position'=>51, 'notnull'=>0, 'visible'=>1, 'help'=>'HelpWarehouseStockTransferDestination'),
146 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,),
147 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0,),
148 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,),
149 'date_prevue_depart' => array('type'=>'date', 'label'=>'DatePrevueDepart', 'enabled'=>'1', 'position'=>100, 'notnull'=>0, 'visible'=>1,),
150 'date_reelle_depart' => array('type'=>'date', 'label'=>'DateReelleDepart', 'enabled'=>'1', 'position'=>101, 'notnull'=>0, 'visible'=>5,),
151 'date_prevue_arrivee' => array('type'=>'date', 'label'=>'DatePrevueArrivee', 'enabled'=>'1', 'position'=>102, 'notnull'=>0, 'visible'=>1,),
152 'date_reelle_arrivee' => array('type'=>'date', 'label'=>'DateReelleArrivee', 'enabled'=>'1', 'position'=>103, 'notnull'=>0, 'visible'=>5,),
153 'lead_time_for_warning' => array('type'=>'integer', 'label'=>'LeadTimeForWarning', 'enabled'=>'1', 'position'=>200, 'default'=>0, 'notnull'=>0, 'visible'=>1),
154 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2,),
155 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>'1', 'position'=>510, 'notnull'=>1, 'visible'=>-2, 'foreignkey'=>'user.rowid',),
156 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ChangedBy', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,),
157 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,),
158 'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,),
159 'fk_incoterms' => array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-2, 'position'=>220),
160 'location_incoterms' => array('type'=>'varchar(255)', 'label'=>'IncotermLabel', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-2, 'position'=>225),
161 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'visible'=>5, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '2'=>'StockStransferDecremented', '3'=>'StockStransferIncremented'),),
162 );
163 public $rowid;
164 public $ref;
165 public $label;
166 public $fk_soc;
167 public $fk_project;
168 public $description;
169 public $note_public;
170 public $note_private;
171 public $date_creation;
172 public $tms;
173 public $lead_time_for_warning;
174 public $fk_user_creat;
175 public $fk_user_modif;
176 public $import_key;
177 public $model_pdf;
178 public $status;
179 // END MODULEBUILDER PROPERTIES
180
181
187 public function __construct(DoliDB $db)
188 {
189 global $conf, $langs;
190
191 $this->db = $db;
192 $this->origin_type = 'StockTransfer@product/stock/stocktransfer';
193
194 if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) $this->fields['rowid']['visible'] = 0;
195 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) $this->fields['entity']['enabled'] = 0;
196
197 // Example to show how to set values of fields definition dynamically
198 /*if ($user->rights->stocktransfer->stocktransfer->read) {
199 $this->fields['myfield']['visible'] = 1;
200 $this->fields['myfield']['noteditable'] = 0;
201 }*/
202
203 // Unset fields that are disabled
204 foreach ($this->fields as $key => $val) {
205 if (isset($val['enabled']) && empty($val['enabled'])) {
206 unset($this->fields[$key]);
207 }
208 }
209
210 // Translate some data of arrayofkeyval
211 if (is_object($langs)) {
212 foreach ($this->fields as $key => $val) {
213 if (isset($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
214 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
215 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
216 }
217 }
218 }
219 }
220 }
221
229 public function create(User $user, $notrigger = false)
230 {
231 $model_pdf = GETPOST('model');
232 if (!empty($model_pdf)) $this->model_pdf = $model_pdf;
233 $this->status = (int) $this->status;
234 if ($this->fk_warehouse_source <= 0) $this->fk_warehouse_source = 0;
235 if ($this->fk_warehouse_destination <= 0) $this->fk_warehouse_destination = 0;
236 return $this->createCommon($user, $notrigger);
237 }
238
246 public function createFromClone(User $user, $fromid)
247 {
248 global $langs, $extrafields;
249 $error = 0;
250
251 dol_syslog(__METHOD__, LOG_DEBUG);
252
253 $object = new self($this->db);
254
255 $this->db->begin();
256
257 // Load source object
258 $result = $object->fetchCommon($fromid);
259 if ($result > 0 && !empty($object->table_element_line)) $object->fetchLines();
260
261 // get lines so they will be clone
262 //foreach($this->lines as $line)
263 // $line->fetch_optionals();
264
265 // Reset some properties
266 unset($object->id);
267 unset($object->fk_user_creat);
268 unset($object->import_key);
269 unset($object->date_prevue_depart);
270 unset($object->date_prevue_arrivee);
271 unset($object->date_reelle_depart);
272 unset($object->date_reelle_arrivee);
273
274
275 // Clear fields
276 $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default'];
277 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
278 $object->status = self::STATUS_DRAFT;
279 // ...
280 // Clear extrafields that are unique
281 if (is_array($object->array_options) && count($object->array_options) > 0) {
282 $extrafields->fetch_name_optionals_label($this->table_element);
283 foreach ($object->array_options as $key => $option) {
284 $shortkey = preg_replace('/options_/', '', $key);
285 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
286 //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
287 unset($object->array_options[$key]);
288 }
289 }
290 }
291
292 // Create clone
293 $object->context['createfromclone'] = 'createfromclone';
294 $result = $object->createCommon($user);
295 if ($result < 0) {
296 $error++;
297 $this->error = $object->error;
298 $this->errors = $object->errors;
299 }
300
301 if (!$error) {
302 // copy internal contacts
303 if ($this->copy_linked_contact($object, 'internal') < 0) {
304 $error++;
305 }
306 }
307
308 if (!$error) {
309 // copy external contacts if same company
310 if (property_exists($this, 'socid') && $this->socid == $object->socid) {
311 if ($this->copy_linked_contact($object, 'external') < 0)
312 $error++;
313 }
314 }
315
316 unset($object->context['createfromclone']);
317
318 // End
319 if (!$error) {
320 $this->db->commit();
321 return $object;
322 } else {
323 $this->db->rollback();
324 return -1;
325 }
326 }
327
335 public function fetch($id, $ref = null)
336 {
337 $result = $this->fetchCommon($id, $ref);
338 if ($result > 0 && !empty($this->table_element_line)) $this->fetchLines();
339 return $result;
340 }
341
347 public function fetchLines()
348 {
349 require_once DOL_DOCUMENT_ROOT . '/product/stock/stocktransfer/class/stocktransferline.class.php';
350 $this->lines = array();
351
352 $result = $this->fetchLinesCommon();
353 usort($this->lines, array('stocktransfer', 'cmp'));
354 return $result;
355 }
356
364 public function cmp($a, $b)
365 {
366 if ($a->rang == $b->rang) {
367 return 0;
368 }
369 return ($a->rang < $b->rang) ? -1 : 1;
370 }
371
377 public function getValorisationTotale()
378 {
379
380 $total_pmp = 0;
381
382 if (empty($this->lines)) $this->fetchLines();
383 if (!empty($this->lines)) {
384 foreach ($this->lines as $l) $total_pmp+= ($l->pmp * $l->qty);
385 }
386
387 return $total_pmp;
388 }
389
401 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
402 {
403 global $conf;
404
405 dol_syslog(__METHOD__, LOG_DEBUG);
406
407 $records = array();
408
409 $sql = 'SELECT ';
410 $sql .= $this->getFieldList();
411 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
412 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
413 else $sql .= ' WHERE 1 = 1';
414 // Manage filter
415 $sqlwhere = array();
416 if (count($filter) > 0) {
417 foreach ($filter as $key => $value) {
418 if ($key == 't.rowid') {
419 $sqlwhere[] = $key.'='.$value;
420 } elseif (strpos($key, 'date') !== false) {
421 $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\'';
422 } elseif ($key == 'customsql') {
423 $sqlwhere[] = $value;
424 } else {
425 $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\'';
426 }
427 }
428 }
429 if (count($sqlwhere) > 0) {
430 $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")";
431 }
432
433 if (!empty($sortfield)) {
434 $sql .= $this->db->order($sortfield, $sortorder);
435 }
436 if (!empty($limit)) {
437 $sql .= ' '.$this->db->plimit($limit, $offset);
438 }
439
440 $resql = $this->db->query($sql);
441 if ($resql) {
442 $num = $this->db->num_rows($resql);
443 $i = 0;
444 while ($i < ($limit ? min($limit, $num) : $num)) {
445 $obj = $this->db->fetch_object($resql);
446
447 $record = new self($this->db);
448 $record->setVarsFromFetchObj($obj);
449
450 $records[$record->id] = $record;
451
452 $i++;
453 }
454 $this->db->free($resql);
455
456 return $records;
457 } else {
458 $this->errors[] = 'Error '.$this->db->lasterror();
459 dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
460
461 return -1;
462 }
463 }
464
472 public function update(User $user, $notrigger = false)
473 {
474 $this->tms = ''; // Will be done automatically because tms field is on update cascade
475 $res = $this->updateCommon($user, $notrigger);
476 if ($this->socid > 0 || $this->fk_soc > 0 && empty($this->thirdparty)) $this->fetch_thirdparty();
477 if (empty($this->socid) && empty($this->fk_soc)) unset($this->thirdparty);
478 return $res;
479 }
480
488 public function delete(User $user, $notrigger = false)
489 {
490 if ($this->status > self::STATUS_VALIDATED) {
491 return 0;
492 } else {
493 return $this->deleteCommon($user, $notrigger);
494 }
495 }
496
505 public function deleteLine(User $user, $idline, $notrigger = false)
506 {
507 if ($this->status < 0) {
508 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
509 return -2;
510 }
511
512 $res = $this->deleteLineCommon($user, $idline, $notrigger);
513 $this->line_order(true);
514 return $res;
515 }
516
517
525 public function validate($user, $notrigger = 0)
526 {
527 global $conf, $langs;
528
529 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
530
531 $error = 0;
532
533 // Protection
534 if ($this->status == self::STATUS_VALIDATED) {
535 dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
536 return 0;
537 }
538
539 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer->write))
540 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer->stocktransfer_advance->validate))))
541 {
542 $this->error='NotEnoughPermissions';
543 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
544 return -1;
545 }*/
546
547 $now = dol_now();
548
549 $this->db->begin();
550
551 // Define new ref
552 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
553 $num = $this->getNextNumRef();
554 } else {
555 $num = $this->ref;
556 }
557 $this->newref = $num;
558
559 if (!empty($num)) {
560 // Validate
561 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
562 $sql .= " SET ref = '".$this->db->escape($num)."',";
563 $sql .= " status = ".self::STATUS_VALIDATED;
564 if (!empty($this->fields['date_validation'])) $sql .= ", date_validation = '".$this->db->idate($now)."',";
565 if (!empty($this->fields['fk_user_valid'])) $sql .= ", fk_user_valid = ".((int) $user->id);
566 $sql .= " WHERE rowid = ".((int) $this->id);
567
568 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
569 $resql = $this->db->query($sql);
570 if (!$resql) {
571 dol_print_error($this->db);
572 $this->error = $this->db->lasterror();
573 $error++;
574 }
575
576 if (!$error && !$notrigger) {
577 // Call trigger
578 $result = $this->call_trigger('STOCKTRANSFER_VALIDATE', $user);
579 if ($result < 0) $error++;
580 // End call triggers
581 }
582 }
583
584 if (!$error) {
585 $this->oldref = $this->ref;
586
587 // Rename directory if dir was a temporary ref
588 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
589 // Now we rename also files into index
590 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'stocktransfer/".$this->db->escape($this->newref)."'";
591 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransfer/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity);
592 $resql = $this->db->query($sql);
593 if (!$resql) {
594 $error++; $this->error = $this->db->lasterror();
595 }
596 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'stocktransfer/".$this->db->escape($this->newref)."'";
597 $sql .= " WHERE filepath = 'stocktransfer/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
598 $resql = $this->db->query($sql);
599 if (!$resql) {
600 $error++; $this->error = $this->db->lasterror();
601 }
602
603 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
604 $oldref = dol_sanitizeFileName($this->ref);
605 $newref = dol_sanitizeFileName($num);
606 $dirsource = $conf->stocktransfer->dir_output.'/stocktransfer/'.$oldref;
607 $dirdest = $conf->stocktransfer->dir_output.'/stocktransfer/'.$newref;
608 if (!$error && file_exists($dirsource)) {
609 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
610
611 if (@rename($dirsource, $dirdest)) {
612 dol_syslog("Rename ok");
613 // Rename docs starting with $oldref with $newref
614 $listoffiles = dol_dir_list($conf->stocktransfer->dir_output.'/stocktransfer/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
615 foreach ($listoffiles as $fileentry) {
616 $dirsource = $fileentry['name'];
617 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
618 $dirsource = $fileentry['path'].'/'.$dirsource;
619 $dirdest = $fileentry['path'].'/'.$dirdest;
620 @rename($dirsource, $dirdest);
621 }
622 }
623 }
624 }
625 }
626
627 // Set new ref and current status
628 if (!$error) {
629 $this->ref = $num;
630 $this->status = self::STATUS_VALIDATED;
631 }
632
633 if (!$error) {
634 $this->db->commit();
635 return 1;
636 } else {
637 $this->db->rollback();
638 return -1;
639 }
640 }
641
642
650 public function setDraft($user, $notrigger = 0)
651 {
652 // Protection
653 if ($this->status <= self::STATUS_DRAFT) {
654 return 0;
655 }
656
657 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
658 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
659 {
660 $this->error='Permission denied';
661 return -1;
662 }*/
663
664 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'STOCKTRANSFER_UNVALIDATE');
665 }
666
674 public function cancel($user, $notrigger = 0)
675 {
676 // Protection
677 if ($this->status != self::STATUS_VALIDATED) {
678 return 0;
679 }
680
681 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
682 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
683 {
684 $this->error='Permission denied';
685 return -1;
686 }*/
687
688 return $this->setStatusCommon($user, self::STATUS_CLOSED, $notrigger, 'STOCKTRANSFER_CLOSE');
689 }
690
698 public function reopen($user, $notrigger = 0)
699 {
700 // Protection
701 if ($this->status != self::STATUS_CLOSED) {
702 return 0;
703 }
704
705 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
706 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
707 {
708 $this->error='Permission denied';
709 return -1;
710 }*/
711
712 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'STOCKTRANSFER_REOPEN');
713 }
714
725 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
726 {
727 global $conf, $langs, $hookmanager;
728
729 if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips
730
731 $result = '';
732
733 $label = '<u>'.$langs->trans("StockTransfer").'</u>';
734 $label .= '<br>';
735 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
736 if (isset($this->status)) {
737 $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
738 }
739
740 $url = dol_buildpath('/product/stock/stocktransfer/stocktransfer_card.php', 1).'?id='.$this->id;
741
742 if ($option != 'nolink') {
743 // Add param to save lastsearch_values or not
744 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
745 if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1;
746 if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1';
747 }
748
749 $linkclose = '';
750 if (empty($notooltip)) {
751 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
752 $label = $langs->trans("ShowStockTransfer");
753 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
754 }
755 $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
756 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
757 } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
758
759 $linkstart = '<a href="'.$url.'"';
760 $linkstart .= $linkclose.'>';
761 $linkend = '</a>';
762
763 $result .= $linkstart;
764
765 if (empty($this->showphoto_on_popup)) {
766 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);
767 } else {
768 if ($withpicto) {
769 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
770
771 list($class, $module) = explode('@', $this->picto);
772 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
773 $filearray = dol_dir_list($upload_dir, "files");
774 $filename = $filearray[0]['name'];
775 if (!empty($filename)) {
776 $pospoint = strpos($filearray[0]['name'], '.');
777
778 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
779 if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) {
780 $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>';
781 } else {
782 $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>';
783 }
784
785 $result .= '</div>';
786 } else {
787 $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);
788 }
789 }
790 }
791
792 if ($withpicto != 2) $result .= $this->ref;
793
794 $result .= $linkend;
795 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
796
797 global $action, $hookmanager;
798 $hookmanager->initHooks(array('stocktransferdao'));
799 $parameters = array('id'=>$this->id, 'getnomurl'=>$result);
800 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
801 if ($reshook > 0) $result = $hookmanager->resPrint;
802 else $result .= $hookmanager->resPrint;
803
804 return $result;
805 }
806
813 public function getLibStatut($mode = 0)
814 {
815 return $this->LibStatut($this->status, $mode);
816 }
817
818 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
826 public function LibStatut($status, $mode = 0)
827 {
828 // phpcs:enable
829 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
830 global $langs;
831 //$langs->load("stocktransfer@stocktransfer");
832 $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft');
833 $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated');
834 $this->labelStatus[self::STATUS_TRANSFERED] = $langs->trans('StockStransferDecremented');
835 $this->labelStatus[self::STATUS_CLOSED] = $langs->trans('StockStransferIncremented');
836 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft');
837 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Validated');
838 $this->labelStatusShort[self::STATUS_TRANSFERED] = $langs->trans('StockStransferDecremented');
839 $this->labelStatusShort[self::STATUS_CLOSED] = $langs->trans('StockStransferIncremented');
840 }
841
842 $statusType = 'status'.$status;
843 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
844 if ($status == self::STATUS_CLOSED) $statusType = 'status6';
845
846 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
847 }
848
855 public function info($id)
856 {
857 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
858 $sql .= ' fk_user_creat, fk_user_modif';
859 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
860 $sql .= ' WHERE t.rowid = '.((int) $id);
861 $result = $this->db->query($sql);
862 if ($result) {
863 if ($this->db->num_rows($result)) {
864 $obj = $this->db->fetch_object($result);
865 $this->id = $obj->rowid;
866
867 $this->user_creation_id = $obj->fk_user_creat;
868 $this->user_modification_id = $obj->fk_user_modif;
869 $this->date_creation = $this->db->jdate($obj->datec);
870 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
871 }
872
873 $this->db->free($result);
874 } else {
875 dol_print_error($this->db);
876 }
877 }
878
885 public function initAsSpecimen()
886 {
887 $this->initAsSpecimenCommon();
888 }
889
895 public function getLinesArray()
896 {
897 $this->lines = array();
898
899 $objectline = new StockTransferLine($this->db);
900 $result = $objectline->fetchAll('ASC', 'rang', 0, 0, array('customsql'=>'fk_stocktransfer = '.$this->id));
901
902 if (is_numeric($result)) {
903 $this->error = $objectline->error;
904 $this->errors = $objectline->errors;
905 return $result;
906 } else {
907 $this->lines = $result;
908 return $this->lines;
909 }
910 }
911
917 public function getNextNumRef()
918 {
919 global $langs, $conf;
920 $langs->load("stocks");
921
922 if (empty($conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON)) {
923 $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON = 'mod_stocktransfer_standard';
924 }
925
926 if (!empty($conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON)) {
927 $mybool = false;
928
929 $file = $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON.".php";
930 $classname = $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON;
931
932 // Include file with class
933 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
934 foreach ($dirmodels as $reldir) {
935 $dir = dol_buildpath($reldir."core/modules/stocktransfer/");
936
937 // Load file with numbering class (if found)
938 $mybool |= @include_once $dir.$file;
939 }
940
941 if ($mybool === false) {
942 dol_print_error('', "Failed to include file ".$file);
943 return '';
944 }
945
946 if (class_exists($classname)) {
947 $obj = new $classname();
948 $numref = $obj->getNextValue($this);
949
950 if ($numref != '' && $numref != '-1') {
951 return $numref;
952 } else {
953 $this->error = $obj->error;
954 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
955 return "";
956 }
957 } else {
958 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
959 return "";
960 }
961 } else {
962 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
963 return "";
964 }
965 }
966
978 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
979 {
980 global $conf, $langs;
981
982 $result = 0;
983 $includedocgeneration = 1;
984
985 $langs->load("stocks");
986
987 if (!dol_strlen($modele)) {
988 $modele = 'eagle';
989
990 if ($this->modelpdf) {
991 $modele = $this->modelpdf;
992 } elseif (!empty($conf->global->STOCKTRANSFER_ADDON_PDF)) {
993 $modele = $conf->global->STOCKTRANSFER_ADDON_PDF;
994 }
995 }
996
997 $modelpath = "core/modules/stocktransfer/doc/";
998
999 if ($includedocgeneration) {
1000 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1001 }
1002
1003 return $result;
1004 }
1005
1013 public function doScheduledJob()
1014 {
1015 global $conf, $langs;
1016
1017 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1018
1019 $error = 0;
1020 $this->output = '';
1021 $this->error = '';
1022
1023 dol_syslog(__METHOD__, LOG_DEBUG);
1024
1025 $now = dol_now();
1026
1027 $this->db->begin();
1028
1029 // ...
1030
1031 $this->db->commit();
1032
1033 return $error;
1034 }
1035}
1036
1040//class StockTransferLine
1041//{
1042// // To complete with content of an object StockTransferLine
1043// // We should have a field rowid, fk_stocktransfer and position
1044//
1045// /**
1046// * @var int Does object support extrafields ? 0=No, 1=Yes
1047// */
1048// public $isextrafieldmanaged = 0;
1049//
1050// /**
1051// * Constructor
1052// *
1053// * @param DoliDb $db Database handler
1054// */
1055// public function __construct(DoliDB $db)
1056// {
1057// $this->db = $db;
1058// }
1059//}
$object ref
Definition info.php:78
Parent class of all other business classes (invoices, contracts, proposals, orders,...
line_order($renum=false, $rowidorder='ASC', $fk_parent_line=true)
Save a new position (field rang) for details lines.
fetch_thirdparty($force_thirdparty_id=0)
Load the third party of object, from id $this->socid or $this->fk_soc, into this->thirdparty.
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
fetchCommon($id, $ref=null, $morewhere='')
Load object in memory from the database.
createCommon(User $user, $notrigger=false)
Create object into database.
deleteCommon(User $user, $notrigger=false, $forcechilddeletion=0)
Delete object in database.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
updateCommon(User $user, $notrigger=false)
Update object into database.
fetchLinesCommon($morewhere='')
Load object in memory from the database.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Class to manage Dolibarr database access.
Class for StockTransfer.
getValorisationTotale()
Used to get total PMP amount of all quantities of products of Stock Transfer.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter=array(), $filtermode='AND')
Load list of objects in memory from the database.
cmp($a, $b)
Used to sort lines by rank.
fetch($id, $ref=null)
Load object in memory from the database.
LibStatut($status, $mode=0)
Return the status.
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
fetchLines()
Load object lines in memory from the database.
validate($user, $notrigger=0)
Validate object.
create(User $user, $notrigger=false)
Create object into database.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
setDraft($user, $notrigger=0)
Set draft status.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
reopen($user, $notrigger=0)
Set back to validated status.
getLibStatut($mode=0)
Return label of the status.
info($id)
Load the info information in the object.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module.
__construct(DoliDB $db)
Constructor.
createFromClone(User $user, $fromid)
Clone an object into another one.
getLinesArray()
Create an array of lines.
cancel($user, $notrigger=0)
Set cancel status.
update(User $user, $notrigger=false)
Update object into database.
Class for StockTransferLine.
Class to manage Dolibarr users.
trait CommonIncoterm
Superclass for incoterm classes.
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.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.