dolibarr 20.0.0
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
29require_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:636
$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.
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.