dolibarr 25.0.0-alpha
stocktransferline.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
4 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
5 * Copyright (C) 2024-2026 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/commonobjectline.class.php';
29//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
30//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
31
36{
40 public $element = 'stocktransferline';
41
45 public $table_element = 'stocktransfer_stocktransferline';
46
50 public $picto = 'stocktransferline@stocktransfer';
51
52 const STATUS_DRAFT = 0;
53 const STATUS_VALIDATED = 1;
54 const STATUS_CANCELED = 9;
55
56
82 // BEGIN MODULEBUILDER PROPERTIES
86 public $fields = array(
87 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'comment' => "Id"),
88 'amount' => array('type' => 'price', 'label' => 'Amount', 'enabled' => 1, 'position' => 40, 'notnull' => 0, 'visible' => 1, 'default' => 'null', 'isameasure' => 1, 'help' => "Help text for amount",),
89 '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",),
90 '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,),
91 '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,),
92 'fk_stocktransfer' => array('type' => 'integer:StockTransfer:stocktransfer/stock/class/stocktransfer.class.php', 'label' => 'StockTransfer', 'enabled' => 1, 'position' => 50, 'notnull' => 1, 'visible' => 0,),
93 'fk_product' => array('type' => 'integer:Product:product/class/product.class.php', 'label' => 'Product', 'enabled' => 1, 'position' => 50, 'notnull' => 1, 'visible' => 1,),
94 'batch' => array('type' => 'varchar(128)', 'label' => 'Batch', 'enabled' => 1, 'position' => 1000, 'notnull' => -1, 'visible' => 1,),
95 'pmp' => array('type' => 'double'/*, 'help'=>'THMEstimatedHelp'*/, 'label' => 'PMP', 'enabled' => 1, 'position' => 50, 'notnull' => 0, 'visible' => 1,),
96 '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",),
97 );
101 public $rowid;
105 public $amount;
106
110 public $qty;
114 public $fk_warehouse_destination;
118 public $fk_warehouse_source;
122 public $fk_stocktransfer;
126 public $fk_product;
130 public $batch;
131
135 public $pmp;
136
137 // END MODULEBUILDER PROPERTIES
138
139
145 public function __construct(DoliDB $db)
146 {
147 global $conf, $langs;
148
149 $this->db = $db;
150
151 $this->ismultientitymanaged = 0;
152 $this->isextrafieldmanaged = 1;
153
154 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
155 $this->fields['rowid']['visible'] = 0;
156 }
157 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
158 $this->fields['entity']['enabled'] = 0;
159 }
160
161 // Example to show how to set values of fields definition dynamically
162 /*if ($user->rights->stocktransfer->stocktransferline->read) {
163 $this->fields['myfield']['visible'] = 1;
164 $this->fields['myfield']['noteditable'] = 0;
165 }*/
166
167 // Unset fields that are disabled
168 foreach ($this->fields as $key => $val) {
169 if (isset($val['enabled']) && empty($val['enabled'])) {
170 unset($this->fields[$key]);
171 }
172 }
173
174 // Translate some data of arrayofkeyval
175 if (is_object($langs)) {
176 foreach ($this->fields as $key => $val) {
177 if (isset($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
178 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
179 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
180 }
181 }
182 }
183 }
184 }
185
193 public function create(User $user, $notrigger = 0)
194 {
195 return $this->createCommon($user, $notrigger);
196 }
197
205 public function createFromClone(User $user, $fromid)
206 {
207 global $langs, $extrafields;
208 $error = 0;
209
210 dol_syslog(__METHOD__, LOG_DEBUG);
211
212 $object = new self($this->db);
213
214 $this->db->begin();
215
216 // Load source object
217 $result = $object->fetchCommon($fromid);
218 if ($result > 0 && !empty($object->table_element_line)) {
219 $object->fetchLines();
220 }
221
222 // get lines so they will be clone
223 //foreach($this->lines as $line)
224 // $line->fetch_optionals();
225
226 // Reset some properties
227 unset($object->id);
228 unset($object->import_key);
229
230
231 // Clear fields
232 $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default'];
233 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
234 $object->status = self::STATUS_DRAFT;
235 // ...
236 // Clear extrafields that are unique
237 if (is_array($object->array_options) && count($object->array_options) > 0) {
238 $extrafields->fetch_name_optionals_label($this->table_element);
239 foreach ($object->array_options as $key => $option) {
240 $shortkey = preg_replace('/options_/', '', $key);
241 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
242 unset($object->array_options[$key]);
243 }
244 }
245 }
246
247 // Create clone
248 $object->context['createfromclone'] = 'createfromclone';
249 $result = $object->createCommon($user);
250 if ($result < 0) {
251 $error++;
253 }
254
255 if (!$error) {
256 // copy internal contacts
257 if ($this->copy_linked_contact($object, 'internal') < 0) {
258 $error++;
259 }
260 }
261
262 if (!$error) {
263 // copy external contacts if same company
264 if (property_exists($this, 'socid') && $this->socid == $object->socid) {
265 if ($this->copy_linked_contact($object, 'external') < 0) {
266 $error++;
267 }
268 }
269 }
270
271 unset($object->context['createfromclone']);
272
273 // End
274 if (!$error) {
275 $this->db->commit();
276 return $object;
277 } else {
278 $this->db->rollback();
279 return -1;
280 }
281 }
282
290 public function fetch($id, $ref = null)
291 {
292 $result = $this->fetchCommon($id, $ref);
293 if ($result > 0 && !empty($this->table_element_line)) {
294 $this->fetchLines();
295 }
296 return $result;
297 }
298
304 public function fetchLines()
305 {
306 $this->lines = array();
307
308 $result = $this->fetchLinesCommon();
309 return $result;
310 }
311
312
325 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
326 {
327 dol_syslog(__METHOD__, LOG_DEBUG);
328
329 $records = array();
330
331 $sql = 'SELECT ';
332 $sql .= $this->getFieldList();
333 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
334 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
335 $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
336 } else {
337 $sql .= ' WHERE 1 = 1';
338 }
339
340 // Manage filter
341 $errormessage = '';
342 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
343 if ($errormessage) {
344 $this->errors[] = $errormessage;
345 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
346 return -1;
347 }
348
349 if (!empty($sortfield)) {
350 $sql .= $this->db->order($sortfield, $sortorder);
351 }
352 if (!empty($limit)) {
353 $sql .= ' '.$this->db->plimit($limit, $offset);
354 }
355
356 $resql = $this->db->query($sql);
357 if ($resql) {
358 $num = $this->db->num_rows($resql);
359 $i = 0;
360 while ($i < ($limit ? min($limit, $num) : $num)) {
361 $obj = $this->db->fetch_object($resql);
362
363 $record = new self($this->db);
364 $record->setVarsFromFetchObj($obj);
365
366 $records[$record->id] = $record;
367
368 $i++;
369 }
370 $this->db->free($resql);
371
372 return $records;
373 } else {
374 $this->errors[] = 'Error '.$this->db->lasterror();
375 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
376
377 return -1;
378 }
379 }
380
388 public function update(User $user, $notrigger = 0)
389 {
390 return $this->updateCommon($user, $notrigger);
391 }
392
400 public function delete(User $user, $notrigger = 0)
401 {
402 return $this->deleteCommon($user, $notrigger);
403 //return $this->deleteCommon($user, $notrigger, 1);
404 }
405
414 public function deleteLine(User $user, $idline, $notrigger = 0)
415 {
416 if ($this->status < 0) {
417 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
418 return -2;
419 }
420
421 return $this->deleteLineCommon($user, $idline, $notrigger);
422 }
423
433 public function doStockMovement($label, $code_inv, $fk_entrepot, $direction = 1)
434 {
435 global $user, $langs;
436
437 require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
438 include_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php';
439 include_once DOL_DOCUMENT_ROOT . '/product/stock/stocktransfer/class/stocktransfer.class.php';
440
441 $p = new Product($this->db);
442 $p->fetch($this->fk_product);
443
444 $op = array();
445 $op[0] = "+".trim((string) $this->qty);
446 $op[1] = "-".trim((string) $this->qty);
447 $movementstock = new MouvementStock($this->db);
448 $st = new StockTransfer($this->db);
449 $movementstock->origin_type = $st->origin_type;
450 $movementstock->origin_id = $this->fk_stocktransfer;
451
452 if (empty($this->batch)) { // no batch for line
453 $result = $movementstock->_create(
454 $user,
455 $p->id,
456 $fk_entrepot,
457 (float) $op[$direction],
458 $direction,
459 empty($direction) ? $this->pmp : 0,
460 $label,
461 $code_inv
462 );
463
464 if ($result < 0) {
465 $this->setErrorsFromObject($movementstock);
466 return -1;
467 }
468 } else {
469 if ($p->hasbatch()) {
470 $arraybatchinfo = $p->loadBatchInfo($this->batch);
471 if (count($arraybatchinfo) > 0) {
472 $firstrecord = array_shift($arraybatchinfo);
473 $dlc = $firstrecord['eatby'];
474 $dluo = $firstrecord['sellby'];
475 } else {
476 $dlc = '';
477 $dluo = '';
478 }
479
480 $result = $movementstock->_create(
481 $user,
482 $p->id,
483 $fk_entrepot,
484 (float) $op[$direction],
485 $direction,
486 empty($direction) ? $this->pmp : 0,
487 $label,
488 $code_inv,
489 '',
490 $dlc,
491 $dluo,
492 $this->batch
493 );
494
495 if ($result < 0) {
496 $this->setErrorsFromObject($movementstock);
497 return $result;
498 }
499 } else {
500 $this->error = $langs->trans('StockTransferNoBatchForProduct', $p->getNomUrl());
501 $this->errors[] = $this->error;
502 return -1;
503 }
504 }
505
506 return 1;
507 }
508
516 public function validate($user, $notrigger = 0)
517 {
518 global $conf, $langs;
519
520 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
521
522 $error = 0;
523
524 // Protection
525 if ($this->status == self::STATUS_VALIDATED) {
526 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
527 return 0;
528 }
529
530 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransferline->write))
531 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransferline->stocktransferline_advance->validate))))
532 {
533 $this->error='NotEnoughPermissions';
534 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
535 return -1;
536 }*/
537
538 $now = dol_now();
539
540 $this->db->begin();
541
542 // Define new ref
543 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
544 $num = $this->getNextNumRef();
545 } else {
546 $num = (string) $this->ref;
547 }
548 $this->newref = $num;
549
550 if (!empty($num)) {
551 // Validate
552 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
553 $sql .= " SET ref = '".$this->db->escape($num)."',";
554 $sql .= " status = ".self::STATUS_VALIDATED;
555 if (!empty($this->fields['date_validation'])) {
556 $sql .= ", date_validation = '".$this->db->idate($now)."',";
557 }
558 if (!empty($this->fields['fk_user_valid'])) {
559 $sql .= ", fk_user_valid = ".((int) $user->id);
560 }
561 $sql .= " WHERE rowid = ".((int) $this->id);
562
563 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
564 $resql = $this->db->query($sql);
565 if (!$resql) {
566 dol_print_error($this->db);
567 $this->error = $this->db->lasterror();
568 $error++;
569 }
570
571 if (!$error && !$notrigger) {
572 // Call trigger
573 $result = $this->call_trigger('STOCKTRANSFERLINE_VALIDATE', $user);
574 if ($result < 0) {
575 $error++;
576 }
577 // End call triggers
578 }
579 }
580
581 if (!$error) {
582 $this->oldref = $this->ref;
583
584 // Rename directory if dir was a temporary ref
585 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
586 // Now we rename also files into index
587 $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)."'";
588 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransferline/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity);
589 $resql = $this->db->query($sql);
590 if (!$resql) {
591 $error++;
592 $this->error = $this->db->lasterror();
593 }
594 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'stocktransferline/".$this->db->escape($this->newref)."'";
595 $sql .= " WHERE filepath = 'stocktransferline/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity);
596 $resql = $this->db->query($sql);
597 if (!$resql) {
598 $error++;
599 $this->error = $this->db->lasterror();
600 }
601
602 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
603 $oldref = dol_sanitizeFileName($this->ref);
604 $newref = dol_sanitizeFileName($num);
605 $dirsource = $conf->stocktransfer->dir_output.'/stocktransferline/'.$oldref;
606 $dirdest = $conf->stocktransfer->dir_output.'/stocktransferline/'.$newref;
607 if (!$error && file_exists($dirsource)) {
608 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
609
610 if (@rename($dirsource, $dirdest)) {
611 dol_syslog("Rename ok");
612 // Rename docs starting with $oldref with $newref
613 $listoffiles = dol_dir_list($conf->stocktransfer->dir_output.'/stocktransferline/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
614 foreach ($listoffiles as $fileentry) {
615 $dirsource = $fileentry['name'];
616 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
617 $dirsource = $fileentry['path'].'/'.$dirsource;
618 $dirdest = $fileentry['path'].'/'.$dirdest;
619 @rename($dirsource, $dirdest);
620 }
621 }
622 }
623 }
624 }
625
626 // Set new ref and current status
627 if (!$error) {
628 $this->ref = $num;
629 $this->status = self::STATUS_VALIDATED;
630 }
631
632 if (!$error) {
633 $this->db->commit();
634 return 1;
635 } else {
636 $this->db->rollback();
637 return -1;
638 }
639 }
640
641
649 public function setDraft($user, $notrigger = 0)
650 {
651 // Protection
652 if ($this->status <= self::STATUS_DRAFT) {
653 return 0;
654 }
655
656 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
657 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
658 {
659 $this->error='Permission denied';
660 return -1;
661 }*/
662
663 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'STOCKTRANSFERLINE_UNVALIDATE');
664 }
665
673 public function cancel($user, $notrigger = 0)
674 {
675 // Protection
676 if ($this->status != self::STATUS_VALIDATED) {
677 return 0;
678 }
679
680 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
681 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
682 {
683 $this->error='Permission denied';
684 return -1;
685 }*/
686
687 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'STOCKTRANSFERLINE_CLOSE');
688 }
689
697 public function reopen($user, $notrigger = 0)
698 {
699 // Protection
700 if ($this->status != self::STATUS_CANCELED) {
701 return 0;
702 }
703
704 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
705 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
706 {
707 $this->error='Permission denied';
708 return -1;
709 }*/
710
711 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'STOCKTRANSFERLINE_REOPEN');
712 }
713
724 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
725 {
726 global $conf, $langs, $hookmanager;
727
728 if (!empty($conf->dol_no_mouse_hover)) {
729 $notooltip = 1;
730 } // Force disable tooltips
731
732 $result = '';
733
734 $label = '<u>'.$langs->trans("StockTransferLine").'</u>';
735 $label .= '<br>';
736 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
737 if (isset($this->status)) {
738 $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
739 }
740
741 $url = dol_buildpath('/stocktransfer/stocktransferline_card.php', 1).'?id='.$this->id;
742
743 if ($option != 'nolink') {
744 // Add param to save lastsearch_values or not
745 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
746 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
747 $add_save_lastsearch_values = 1;
748 }
749 if ($add_save_lastsearch_values) {
750 $url .= '&save_lastsearch_values=1';
751 }
752 }
753
754 $linkclose = '';
755 if (empty($notooltip)) {
756 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
757 $label = $langs->trans("ShowStockTransferLine");
758 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
759 }
760 $linkclose .= ' title="'.dolPrintHTMLForAttribute($label).'"';
761 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
762 } else {
763 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
764 }
765
766 $linkstart = '<a href="'.$url.'"';
767 $linkstart .= $linkclose.'>';
768 $linkend = '</a>';
769
770 $result .= $linkstart;
771
772 if (empty($this->showphoto_on_popup)) {
773 if ($withpicto) {
774 $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);
775 }
776 } else {
777 if ($withpicto) {
778 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
779
780 list($class, $module) = explode('@', $this->picto);
781 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
782 $filearray = dol_dir_list($upload_dir, "files");
783 $filename = $filearray[0]['name'];
784 if (!empty($filename)) {
785 $pospoint = strpos($filearray[0]['name'], '.');
786
787 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
788 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
789 $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>';
790 } else {
791 $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>';
792 }
793
794 $result .= '</div>';
795 } else {
796 $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);
797 }
798 }
799 }
800
801 if ($withpicto != 2) {
802 $result .= $this->ref;
803 }
804
805 $result .= $linkend;
806 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
807
808 global $action, $hookmanager;
809 $hookmanager->initHooks(array('stocktransferlinedao'));
810 $parameters = array('id' => $this->id, 'getnomurl' => $result);
811 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
812 if ($reshook > 0) {
813 $result = $hookmanager->resPrint;
814 } else {
815 $result .= $hookmanager->resPrint;
816 }
817
818 return $result;
819 }
820
827 public function getLibStatut($mode = 0)
828 {
829 return $this->LibStatut($this->status, $mode);
830 }
831
832 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
840 public function LibStatut($status, $mode = 0)
841 {
842 // phpcs:enable
843 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
844 global $langs;
845 //$langs->load("stocktransfer@stocktransfer");
846 $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft');
847 $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Enabled');
848 $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled');
849 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft');
850 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Enabled');
851 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled');
852 }
853
854 $statusType = 'status'.$status;
855 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
856 if ($status == self::STATUS_CANCELED) {
857 $statusType = 'status6';
858 }
859
860 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
861 }
862
869 public function info($id)
870 {
871 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
872 $sql .= ' fk_user_creat, fk_user_modif';
873 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
874 $sql .= ' WHERE t.rowid = '.((int) $id);
875 $result = $this->db->query($sql);
876 if ($result) {
877 if ($this->db->num_rows($result)) {
878 $obj = $this->db->fetch_object($result);
879 $this->id = $obj->rowid;
880
881 $this->user_creation_id = $obj->fk_user_creat;
882 $this->user_modification_id = $obj->fk_user_modif;
883 $this->date_creation = $this->db->jdate($obj->datec);
884 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
885 }
886
887 $this->db->free($result);
888 } else {
889 dol_print_error($this->db);
890 }
891 }
892
899 public function initAsSpecimen()
900 {
901 return $this->initAsSpecimenCommon();
902 }
903
909 public function getNextNumRef()
910 {
911 global $langs, $conf;
912 $langs->load("stocks");
913
914 if (!getDolGlobalString('STOCKTRANSFER_STOCKTRANSFERLINE_ADDON')) {
915 $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON = 'mod_stocktransferline_standard';
916 }
917
918 if (getDolGlobalString('STOCKTRANSFER_STOCKTRANSFERLINE_ADDON')) {
919 $mybool = false;
920
921 $file = getDolGlobalString('STOCKTRANSFER_STOCKTRANSFERLINE_ADDON') . ".php";
922 $classname = getDolGlobalString('STOCKTRANSFER_STOCKTRANSFERLINE_ADDON');
923
924 // Include file with class
925 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
926 foreach ($dirmodels as $reldir) {
927 $dir = dol_buildpath($reldir."core/modules/stocktransfer/");
928
929 // Load file with numbering class (if found)
930 $mybool = ((bool) @include_once $dir.$file) || $mybool;
931 }
932
933 if (!$mybool) {
934 dol_print_error(null, "Failed to include file ".$file);
935 return '';
936 }
937
938 if (class_exists($classname)) {
939 $obj = new $classname();
940 '@phan-var-force ModeleNumRefStockTransfer $obj';
941 $numref = $obj->getNextValue($this);
942
943 if ($numref != '' && $numref != '-1') {
944 return $numref;
945 } else {
946 $this->error = $obj->error;
947 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
948 return "";
949 }
950 } else {
951 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
952 return "";
953 }
954 } else {
955 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
956 return "";
957 }
958 }
959
971 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
972 {
973 global $conf, $langs;
974
975 $result = 0;
976 $includedocgeneration = 0;
977
978 $langs->load("stocks");
979
980 if (!dol_strlen($modele)) {
981 $modele = 'standard_stocktransferline';
982
983 if (!empty($this->model_pdf)) {
984 $modele = $this->model_pdf;
985 } elseif (getDolGlobalString('STOCKTRANSFERLINE_ADDON_PDF')) {
986 $modele = getDolGlobalString('STOCKTRANSFERLINE_ADDON_PDF');
987 }
988 }
989
990 $modelpath = "core/modules/stocktransfer/doc/";
991
992 if ($includedocgeneration) {
993 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
994 }
995
996 return $result;
997 }
998
1006 public function doScheduledJob()
1007 {
1008 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1009
1010 $error = 0;
1011 $this->output = '';
1012 $this->error = '';
1013
1014 dol_syslog(__METHOD__, LOG_DEBUG);
1015
1016 $now = dol_now();
1017
1018 $this->db->begin();
1019
1020 // ...
1021
1022 $this->db->commit();
1023
1024 return $error;
1025 }
1026}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
$object ref
Definition info.php:90
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.
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.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:169
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
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:65
dol_now($mode='gmt')
Return date for now.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0, $forbiddenfields=array())
forgeSQLFromUniversalSearchCriteria
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string