dolibarr 21.0.0-alpha
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-2024 Frédéric France <frederic.france@free.fr>
5 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
27// Put here all includes required by your class file
28require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
29require_once DOL_DOCUMENT_ROOT.'/core/class/commonincoterm.class.php';
30
31//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
32//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
33
38{
43 public $element = 'stocktransfer';
44
48 public $table_element = 'stocktransfer_stocktransfer';
49
53 public $table_element_line = 'stocktransfer_stocktransferline';
54
58 public $fk_element = 'fk_stocktransfer';
59
65 protected $childtablesoncascade = array('stocktransfer_stocktransferline');
66
72 public $ref_client;
73
77 public $ref_customer;
78
82 public $picto = 'stock';
83
87 public $date_prevue_depart;
88
92 public $date_prevue_arrivee;
93
97 public $date_reelle_depart;
98
102 public $date_reelle_arrivee;
103
107 public $origin_type;
108
109
110 const STATUS_DRAFT = 0;
111 const STATUS_VALIDATED = 1;
112 const STATUS_TRANSFERED = 2;
113 const STATUS_CLOSED = 3;
114
115
141 // BEGIN MODULEBUILDER PROPERTIES
145 public $fields = array(
146 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'comment' => "Id"),
147 'entity' => array('type' => 'integer', 'label' => 'Entity', 'enabled' => 1, 'position' => 1, 'default' => '1', 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'comment' => "Id"),
148 '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"),
149 'label' => array('type' => 'varchar(255)', 'label' => 'Label', 'enabled' => 1, 'position' => 30, 'notnull' => 0, 'visible' => 1, 'searchall' => 1, 'showoncombobox' => 1, 'css' => 'minwidth100', 'csslist' => 'tdoverflowmax125', 'autofocusoncreate' => 1),
150 'description' => array('type' => 'text', 'label' => 'Description', 'enabled' => 1, 'position' => 31, 'notnull' => 0, 'visible' => 3,),
151 '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, 'picto' => 'project', 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax125'),
152 '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"*/, 'picto' => 'company', 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax125'),
153 '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', 'picto' => 'stock', 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax150'),
154 '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', 'picto' => 'stock', 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax150'),
155 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 61, 'notnull' => 0, 'visible' => 0,),
156 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 62, 'notnull' => 0, 'visible' => 0,),
157 'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 500, 'notnull' => 1, 'visible' => -2,),
158 'date_prevue_depart' => array('type' => 'date', 'label' => 'DatePrevueDepart', 'enabled' => 1, 'position' => 100, 'notnull' => 0, 'visible' => 1,),
159 'date_reelle_depart' => array('type' => 'date', 'label' => 'DateReelleDepart', 'enabled' => 1, 'position' => 101, 'notnull' => 0, 'visible' => 5,),
160 'date_prevue_arrivee' => array('type' => 'date', 'label' => 'DatePrevueArrivee', 'enabled' => 1, 'position' => 102, 'notnull' => 0, 'visible' => 1,),
161 'date_reelle_arrivee' => array('type' => 'date', 'label' => 'DateReelleArrivee', 'enabled' => 1, 'position' => 103, 'notnull' => 0, 'visible' => 5,),
162 'lead_time_for_warning' => array('type' => 'integer', 'label' => 'LeadTimeForWarning', 'enabled' => 1, 'position' => 200, 'default' => '0', 'notnull' => 0, 'visible' => 1),
163 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'position' => 501, 'notnull' => 0, 'visible' => -2,),
164 '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',),
165 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'ChangedBy', 'enabled' => 1, 'position' => 511, 'notnull' => -1, 'visible' => -2,),
166 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'position' => 1000, 'notnull' => -1, 'visible' => -2,),
167 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'position' => 1010, 'notnull' => -1, 'visible' => 0,),
168 'fk_incoterms' => array('type' => 'integer', 'label' => 'IncotermCode', 'enabled' => '$conf->incoterm->enabled', 'visible' => -2, 'position' => 220),
169 'location_incoterms' => array('type' => 'varchar(255)', 'label' => 'IncotermLabel', 'enabled' => '$conf->incoterm->enabled', 'visible' => -2, 'position' => 225),
170 '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'),),
171 );
172 public $rowid;
173 public $ref;
174 public $label;
175 public $description;
176
180 public $socid;
181
186 public $fk_soc;
187 public $lead_time_for_warning;
188 public $status;
189
193 public $lines;
194
198 public $fk_warehouse_source;
199
203 public $fk_warehouse_destination;
204 // END MODULEBUILDER PROPERTIES
205
206
212 public function __construct(DoliDB $db)
213 {
214 global $conf, $langs;
215
216 $this->db = $db;
217
218 $this->ismultientitymanaged = 0;
219 $this->isextrafieldmanaged = 1;
220
221 $this->origin_type = 'StockTransfer@product/stock/stocktransfer';
222
223 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
224 $this->fields['rowid']['visible'] = 0;
225 }
226 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
227 $this->fields['entity']['enabled'] = 0;
228 }
229
230 // Example to show how to set values of fields definition dynamically
231 /*if ($user->rights->stocktransfer->stocktransfer->read) {
232 $this->fields['myfield']['visible'] = 1;
233 $this->fields['myfield']['noteditable'] = 0;
234 }*/
235
236 // Unset fields that are disabled
237 foreach ($this->fields as $key => $val) {
238 if (isset($val['enabled']) && empty($val['enabled'])) {
239 unset($this->fields[$key]);
240 }
241 }
242
243 // Translate some data of arrayofkeyval
244 if (is_object($langs)) {
245 foreach ($this->fields as $key => $val) {
246 if (isset($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
247 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
248 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
249 }
250 }
251 }
252 }
253 }
254
262 public function create(User $user, $notrigger = 0)
263 {
264 $this->status = (int) $this->status;
265 if ($this->fk_warehouse_source <= 0) {
266 $this->fk_warehouse_source = 0;
267 }
268 if ($this->fk_warehouse_destination <= 0) {
269 $this->fk_warehouse_destination = 0;
270 }
271 return $this->createCommon($user, $notrigger);
272 }
273
281 public function createFromClone(User $user, $fromid)
282 {
283 global $langs, $extrafields;
284 $error = 0;
285
286 dol_syslog(__METHOD__, LOG_DEBUG);
287
288 $object = new self($this->db);
289
290 $this->db->begin();
291
292 // Load source object
293 $result = $object->fetchCommon($fromid);
294 if ($result > 0 && !empty($object->table_element_line)) {
295 $object->fetchLines();
296 }
297
298 // get lines so they will be clone
299 //foreach($this->lines as $line)
300 // $line->fetch_optionals();
301
302 // Reset some properties
303 unset($object->id);
304 unset($object->fk_user_creat);
305 unset($object->import_key);
306 unset($object->date_prevue_depart);
307 unset($object->date_prevue_arrivee);
308 unset($object->date_reelle_depart);
309 unset($object->date_reelle_arrivee);
310
311
312 // Clear fields
313 $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default'];
314 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
315 $object->status = self::STATUS_DRAFT;
316 // ...
317 // Clear extrafields that are unique
318 if (is_array($object->array_options) && count($object->array_options) > 0) {
319 $extrafields->fetch_name_optionals_label($this->table_element);
320 foreach ($object->array_options as $key => $option) {
321 $shortkey = preg_replace('/options_/', '', $key);
322 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
323 //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
324 unset($object->array_options[$key]);
325 }
326 }
327 }
328
329 // Create clone
330 $object->context['createfromclone'] = 'createfromclone';
331 $result = $object->createCommon($user);
332 if ($result < 0) {
333 $error++;
335 }
336
337 if (!$error) {
338 // copy internal contacts
339 if ($this->copy_linked_contact($object, 'internal') < 0) {
340 $error++;
341 }
342 }
343
344 if (!$error) {
345 // copy external contacts if same company
346 if (property_exists($this, 'socid') && $this->socid == $object->socid) {
347 if ($this->copy_linked_contact($object, 'external') < 0) {
348 $error++;
349 }
350 }
351 }
352
353 unset($object->context['createfromclone']);
354
355 // End
356 if (!$error) {
357 $this->db->commit();
358 return $object;
359 } else {
360 $this->db->rollback();
361 return -1;
362 }
363 }
364
372 public function fetch($id, $ref = null)
373 {
374 $result = $this->fetchCommon($id, $ref);
375
376 $this->socid = $this->fk_soc;
377
378 if ($result > 0 && !empty($this->table_element_line)) {
379 $this->fetchLines();
380 }
381 return $result;
382 }
383
389 public function fetchLines()
390 {
391 require_once DOL_DOCUMENT_ROOT . '/product/stock/stocktransfer/class/stocktransferline.class.php';
392 $this->lines = array();
393
394 $result = $this->fetchLinesCommon();
395 usort($this->lines, array('StockTransfer', 'stocktransferCmpRank'));
396 return $result;
397 }
398
406 public static function stocktransferCmpRank($a, $b)
407 {
408 if ($a->rang == $b->rang) {
409 return 0;
410 }
411 return ($a->rang < $b->rang) ? -1 : 1;
412 }
413
419 public function getValorisationTotale()
420 {
421 $total_pmp = 0;
422
423 if (empty($this->lines)) {
424 $this->fetchLines();
425 }
426 if (!empty($this->lines)) {
427 foreach ($this->lines as $l) {
428 $total_pmp += ($l->pmp * $l->qty);
429 }
430 }
431
432 return $total_pmp;
433 }
434
447 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
448 {
449 dol_syslog(__METHOD__, LOG_DEBUG);
450
451 $records = array();
452
453 $sql = 'SELECT ';
454 $sql .= $this->getFieldList();
455 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
456 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
457 $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
458 } else {
459 $sql .= ' WHERE 1 = 1';
460 }
461
462 // Manage filter
463 $errormessage = '';
464 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
465 if ($errormessage) {
466 $this->errors[] = $errormessage;
467 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
468 return -1;
469 }
470
471 if (!empty($sortfield)) {
472 $sql .= $this->db->order($sortfield, $sortorder);
473 }
474 if (!empty($limit)) {
475 $sql .= ' '.$this->db->plimit($limit, $offset);
476 }
477
478 $resql = $this->db->query($sql);
479 if ($resql) {
480 $num = $this->db->num_rows($resql);
481 $i = 0;
482 while ($i < ($limit ? min($limit, $num) : $num)) {
483 $obj = $this->db->fetch_object($resql);
484
485 $record = new self($this->db);
486 $record->setVarsFromFetchObj($obj);
487
488 $records[$record->id] = $record;
489
490 $i++;
491 }
492 $this->db->free($resql);
493
494 return $records;
495 } else {
496 $this->errors[] = 'Error '.$this->db->lasterror();
497 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
498
499 return -1;
500 }
501 }
502
510 public function update(User $user, $notrigger = 0)
511 {
512 $this->tms = 0; // Will be done automatically because tms field is on update cascade
513 $res = $this->updateCommon($user, $notrigger);
514 if (($this->socid > 0 || $this->fk_soc > 0) && empty($this->thirdparty)) {
515 $this->fetch_thirdparty();
516 }
517 if (empty($this->socid) && empty($this->fk_soc)) {
518 unset($this->thirdparty);
519 }
520 return $res;
521 }
522
530 public function delete(User $user, $notrigger = 0)
531 {
532 if ($this->status > self::STATUS_VALIDATED) {
533 return 0;
534 } else {
535 return $this->deleteCommon($user, $notrigger);
536 }
537 }
538
547 public function deleteLine(User $user, $idline, $notrigger = 0)
548 {
549 if ($this->status < 0) {
550 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
551 return -2;
552 }
553
554 $res = $this->deleteLineCommon($user, $idline, $notrigger);
555 $this->line_order(true);
556 return $res;
557 }
558
559
567 public function validate($user, $notrigger = 0)
568 {
569 global $conf, $langs;
570
571 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
572
573 $error = 0;
574
575 // Protection
576 if ($this->status == self::STATUS_VALIDATED) {
577 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
578 return 0;
579 }
580
581 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer->write))
582 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer->stocktransfer_advance->validate))))
583 {
584 $this->error='NotEnoughPermissions';
585 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
586 return -1;
587 }*/
588
589 $now = dol_now();
590
591 $this->db->begin();
592
593 // Define new ref
594 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
595 $num = $this->getNextNumRef();
596 } else {
597 $num = $this->ref;
598 }
599 $this->newref = $num;
600
601 if (!empty($num)) {
602 // Validate
603 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
604 $sql .= " SET ref = '".$this->db->escape($num)."',";
605 $sql .= " status = ".self::STATUS_VALIDATED;
606 if (!empty($this->fields['date_validation'])) {
607 $sql .= ", date_validation = '".$this->db->idate($now)."',";
608 }
609 if (!empty($this->fields['fk_user_valid'])) {
610 $sql .= ", fk_user_valid = ".((int) $user->id);
611 }
612 $sql .= " WHERE rowid = ".((int) $this->id);
613
614 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
615 $resql = $this->db->query($sql);
616 if (!$resql) {
617 dol_print_error($this->db);
618 $this->error = $this->db->lasterror();
619 $error++;
620 }
621
622 if (!$error && !$notrigger) {
623 // Call trigger
624 $result = $this->call_trigger('STOCKTRANSFER_VALIDATE', $user);
625 if ($result < 0) {
626 $error++;
627 }
628 // End call triggers
629 }
630 }
631
632 if (!$error) {
633 $this->oldref = $this->ref;
634
635 // Rename directory if dir was a temporary ref
636 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
637 // Now we rename also files into index
638 $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)."'";
639 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransfer/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity);
640 $resql = $this->db->query($sql);
641 if (!$resql) {
642 $error++;
643 $this->error = $this->db->lasterror();
644 }
645 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'stocktransfer/".$this->db->escape($this->newref)."'";
646 $sql .= " WHERE filepath = 'stocktransfer/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
647 $resql = $this->db->query($sql);
648 if (!$resql) {
649 $error++;
650 $this->error = $this->db->lasterror();
651 }
652
653 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
654 $oldref = dol_sanitizeFileName($this->ref);
655 $newref = dol_sanitizeFileName($num);
656 $dirsource = $conf->stocktransfer->dir_output.'/stocktransfer/'.$oldref;
657 $dirdest = $conf->stocktransfer->dir_output.'/stocktransfer/'.$newref;
658 if (!$error && file_exists($dirsource)) {
659 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
660
661 if (@rename($dirsource, $dirdest)) {
662 dol_syslog("Rename ok");
663 // Rename docs starting with $oldref with $newref
664 $listoffiles = dol_dir_list($conf->stocktransfer->dir_output.'/stocktransfer/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
665 foreach ($listoffiles as $fileentry) {
666 $dirsource = $fileentry['name'];
667 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
668 $dirsource = $fileentry['path'].'/'.$dirsource;
669 $dirdest = $fileentry['path'].'/'.$dirdest;
670 @rename($dirsource, $dirdest);
671 }
672 }
673 }
674 }
675 }
676
677 // Set new ref and current status
678 if (!$error) {
679 $this->ref = $num;
680 $this->status = self::STATUS_VALIDATED;
681 }
682
683 if (!$error) {
684 $this->db->commit();
685 return 1;
686 } else {
687 $this->db->rollback();
688 return -1;
689 }
690 }
691
692
700 public function setDraft($user, $notrigger = 0)
701 {
702 // Protection
703 if ($this->status <= self::STATUS_DRAFT) {
704 return 0;
705 }
706
707 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
708 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
709 {
710 $this->error='Permission denied';
711 return -1;
712 }*/
713
714 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'STOCKTRANSFER_UNVALIDATE');
715 }
716
724 public function cancel($user, $notrigger = 0)
725 {
726 // Protection
727 if ($this->status != self::STATUS_VALIDATED) {
728 return 0;
729 }
730
731 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
732 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
733 {
734 $this->error='Permission denied';
735 return -1;
736 }*/
737
738 return $this->setStatusCommon($user, self::STATUS_CLOSED, $notrigger, 'STOCKTRANSFER_CLOSE');
739 }
740
748 public function reopen($user, $notrigger = 0)
749 {
750 // Protection
751 if ($this->status != self::STATUS_CLOSED) {
752 return 0;
753 }
754
755 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
756 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
757 {
758 $this->error='Permission denied';
759 return -1;
760 }*/
761
762 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'STOCKTRANSFER_REOPEN');
763 }
764
775 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
776 {
777 global $conf, $langs, $hookmanager;
778
779 if (!empty($conf->dol_no_mouse_hover)) {
780 $notooltip = 1;
781 } // Force disable tooltips
782
783 $result = '';
784
785 $label = '<u>'.$langs->trans("StockTransfer").'</u>';
786 $label .= '<br>';
787 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
788 if (isset($this->status)) {
789 $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
790 }
791
792 $url = dol_buildpath('/product/stock/stocktransfer/stocktransfer_card.php', 1).'?id='.$this->id;
793
794 if ($option != 'nolink') {
795 // Add param to save lastsearch_values or not
796 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
797 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
798 $add_save_lastsearch_values = 1;
799 }
800 if ($add_save_lastsearch_values) {
801 $url .= '&save_lastsearch_values=1';
802 }
803 }
804
805 $linkclose = '';
806 if (empty($notooltip)) {
807 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
808 $label = $langs->trans("ShowStockTransfer");
809 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
810 }
811 $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
812 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
813 } else {
814 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
815 }
816
817 $linkstart = '<a href="'.$url.'"';
818 $linkstart .= $linkclose.'>';
819 $linkend = '</a>';
820
821 $result .= $linkstart;
822
823 if (empty($this->showphoto_on_popup)) {
824 if ($withpicto) {
825 $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);
826 }
827 } else {
828 if ($withpicto) {
829 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
830
831 list($class, $module) = explode('@', $this->picto);
832 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
833 $filearray = dol_dir_list($upload_dir, "files");
834 $filename = $filearray[0]['name'];
835 if (!empty($filename)) {
836 $pospoint = strpos($filearray[0]['name'], '.');
837
838 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
839 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
840 $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>';
841 } else {
842 $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>';
843 }
844
845 $result .= '</div>';
846 } else {
847 $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);
848 }
849 }
850 }
851
852 if ($withpicto != 2) {
853 $result .= $this->ref;
854 }
855
856 $result .= $linkend;
857 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
858
859 global $action, $hookmanager;
860 $hookmanager->initHooks(array('stocktransferdao'));
861 $parameters = array('id' => $this->id, 'getnomurl' => $result);
862 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
863 if ($reshook > 0) {
864 $result = $hookmanager->resPrint;
865 } else {
866 $result .= $hookmanager->resPrint;
867 }
868
869 return $result;
870 }
871
878 public function getLibStatut($mode = 0)
879 {
880 return $this->LibStatut($this->status, $mode);
881 }
882
883 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
891 public function LibStatut($status, $mode = 0)
892 {
893 // phpcs:enable
894 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
895 global $langs;
896 //$langs->load("stocktransfer@stocktransfer");
897 $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft');
898 $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated');
899 $this->labelStatus[self::STATUS_TRANSFERED] = $langs->trans('StockStransferDecremented');
900 $this->labelStatus[self::STATUS_CLOSED] = $langs->trans('StockStransferIncremented');
901 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft');
902 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Validated');
903 $this->labelStatusShort[self::STATUS_TRANSFERED] = $langs->trans('StockStransferDecremented');
904 $this->labelStatusShort[self::STATUS_CLOSED] = $langs->trans('StockStransferIncremented');
905 }
906
907 $statusType = 'status'.$status;
908 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
909 if ($status == self::STATUS_CLOSED) {
910 $statusType = 'status6';
911 }
912
913 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
914 }
915
922 public function info($id)
923 {
924 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
925 $sql .= ' fk_user_creat, fk_user_modif';
926 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
927 $sql .= ' WHERE t.rowid = '.((int) $id);
928 $result = $this->db->query($sql);
929 if ($result) {
930 if ($this->db->num_rows($result)) {
931 $obj = $this->db->fetch_object($result);
932 $this->id = $obj->rowid;
933
934 $this->user_creation_id = $obj->fk_user_creat;
935 $this->user_modification_id = $obj->fk_user_modif;
936 $this->date_creation = $this->db->jdate($obj->datec);
937 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
938 }
939
940 $this->db->free($result);
941 } else {
942 dol_print_error($this->db);
943 }
944 }
945
952 public function initAsSpecimen()
953 {
954 return $this->initAsSpecimenCommon();
955 }
956
962 public function getLinesArray()
963 {
964 $this->lines = array();
965
966 $objectline = new StockTransferLine($this->db);
967 $result = $objectline->fetchAll('ASC', 'rang', 0, 0, "(fk_stocktransfer:=:".((int) $this->id).")");
968
969 if (is_numeric($result)) {
970 $this->error = $objectline->error;
971 $this->errors = $objectline->errors;
972 return $result;
973 } else {
974 $this->lines = $result;
975 return $this->lines;
976 }
977 }
978
984 public function getNextNumRef()
985 {
986 global $langs, $conf;
987 $langs->load("stocks");
988
989 if (!getDolGlobalString('STOCKTRANSFER_STOCKTRANSFER_ADDON')) {
990 $conf->global->STOCKTRANSFER_STOCKTRANSFER_ADDON = 'mod_stocktransfer_standard';
991 }
992
993 if (getDolGlobalString('STOCKTRANSFER_STOCKTRANSFER_ADDON')) {
994 $mybool = false;
995
996 $file = getDolGlobalString('STOCKTRANSFER_STOCKTRANSFER_ADDON') . ".php";
997 $classname = getDolGlobalString('STOCKTRANSFER_STOCKTRANSFER_ADDON');
998
999 // Include file with class
1000 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1001 foreach ($dirmodels as $reldir) {
1002 $dir = dol_buildpath($reldir."core/modules/stocktransfer/");
1003
1004 // Load file with numbering class (if found)
1005 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1006 }
1007
1008 if ($mybool === false) {
1009 dol_print_error(null, "Failed to include file ".$file);
1010 return '';
1011 }
1012
1013 if (class_exists($classname)) {
1014 $obj = new $classname();
1015 $numref = $obj->getNextValue($this);
1016
1017 if ($numref != '' && $numref != '-1') {
1018 return $numref;
1019 } else {
1020 $this->error = $obj->error;
1021 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1022 return "";
1023 }
1024 } else {
1025 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
1026 return "";
1027 }
1028 } else {
1029 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1030 return "";
1031 }
1032 }
1033
1045 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1046 {
1047 global $conf, $langs;
1048
1049 $result = 0;
1050 $includedocgeneration = 1;
1051
1052 $langs->load("stocks");
1053
1054 if (!dol_strlen($modele)) {
1055 $modele = 'eagle';
1056
1057 if ($this->model_pdf) {
1058 $modele = $this->model_pdf;
1059 } elseif (getDolGlobalString('STOCKTRANSFER_ADDON_PDF')) {
1060 $modele = getDolGlobalString('STOCKTRANSFER_ADDON_PDF');
1061 }
1062 }
1063
1064 $modelpath = "core/modules/stocktransfer/doc/";
1065
1066 if ($includedocgeneration) {
1067 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1068 }
1069
1070 return $result;
1071 }
1072
1080 public function doScheduledJob()
1081 {
1082 global $conf, $langs;
1083
1084 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1085
1086 $error = 0;
1087 $this->output = '';
1088 $this->error = '';
1089
1090 dol_syslog(__METHOD__, LOG_DEBUG);
1091
1092 $now = dol_now();
1093
1094 $this->db->begin();
1095
1096 // ...
1097
1098 $this->db->commit();
1099
1100 return $error;
1101 }
1102}
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:626
$object ref
Definition info.php:79
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.
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.
fetch_thirdparty($force_thirdparty_id=0)
Load the third party of object, from id $this->socid or $this->fk_soc, into this->thirdparty.
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.
Class to manage Dolibarr database access.
Class for StockTransfer.
getValorisationTotale()
Used to get total PMP amount of all quantities of products of Stock Transfer.
update(User $user, $notrigger=0)
Update object into database.
static stocktransferCmpRank($a, $b)
Used to sort lines by rank.
fetch($id, $ref=null)
Load object in memory from the database.
deleteLine(User $user, $idline, $notrigger=0)
Delete a line of object in database.
LibStatut($status, $mode=0)
Return the status.
fetchLines()
Load object lines in memory from the database.
validate($user, $notrigger=0)
Validate object.
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.
create(User $user, $notrigger=0)
Create object into database.
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.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter='', $filtermode='AND')
Load list of objects in memory from the database.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionally 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.
Class for StockTransferLine.
Class to manage Dolibarr users.
trait CommonIncoterm
Superclass for incoterm classes.
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.
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.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.