dolibarr 24.0.0-beta
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-2025 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 //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
243 unset($object->array_options[$key]);
244 }
245 }
246 }
247
248 // Create clone
249 $object->context['createfromclone'] = 'createfromclone';
250 $result = $object->createCommon($user);
251 if ($result < 0) {
252 $error++;
254 }
255
256 if (!$error) {
257 // copy internal contacts
258 if ($this->copy_linked_contact($object, 'internal') < 0) {
259 $error++;
260 }
261 }
262
263 if (!$error) {
264 // copy external contacts if same company
265 if (property_exists($this, 'socid') && $this->socid == $object->socid) {
266 if ($this->copy_linked_contact($object, 'external') < 0) {
267 $error++;
268 }
269 }
270 }
271
272 unset($object->context['createfromclone']);
273
274 // End
275 if (!$error) {
276 $this->db->commit();
277 return $object;
278 } else {
279 $this->db->rollback();
280 return -1;
281 }
282 }
283
291 public function fetch($id, $ref = null)
292 {
293 $result = $this->fetchCommon($id, $ref);
294 if ($result > 0 && !empty($this->table_element_line)) {
295 $this->fetchLines();
296 }
297 return $result;
298 }
299
305 public function fetchLines()
306 {
307 $this->lines = array();
308
309 $result = $this->fetchLinesCommon();
310 return $result;
311 }
312
313
326 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
327 {
328 dol_syslog(__METHOD__, LOG_DEBUG);
329
330 $records = array();
331
332 $sql = 'SELECT ';
333 $sql .= $this->getFieldList();
334 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
335 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
336 $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
337 } else {
338 $sql .= ' WHERE 1 = 1';
339 }
340
341 // Manage filter
342 $errormessage = '';
343 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
344 if ($errormessage) {
345 $this->errors[] = $errormessage;
346 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
347 return -1;
348 }
349
350 if (!empty($sortfield)) {
351 $sql .= $this->db->order($sortfield, $sortorder);
352 }
353 if (!empty($limit)) {
354 $sql .= ' '.$this->db->plimit($limit, $offset);
355 }
356
357 $resql = $this->db->query($sql);
358 if ($resql) {
359 $num = $this->db->num_rows($resql);
360 $i = 0;
361 while ($i < ($limit ? min($limit, $num) : $num)) {
362 $obj = $this->db->fetch_object($resql);
363
364 $record = new self($this->db);
365 $record->setVarsFromFetchObj($obj);
366
367 $records[$record->id] = $record;
368
369 $i++;
370 }
371 $this->db->free($resql);
372
373 return $records;
374 } else {
375 $this->errors[] = 'Error '.$this->db->lasterror();
376 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
377
378 return -1;
379 }
380 }
381
389 public function update(User $user, $notrigger = 0)
390 {
391 return $this->updateCommon($user, $notrigger);
392 }
393
401 public function delete(User $user, $notrigger = 0)
402 {
403 return $this->deleteCommon($user, $notrigger);
404 //return $this->deleteCommon($user, $notrigger, 1);
405 }
406
415 public function deleteLine(User $user, $idline, $notrigger = 0)
416 {
417 if ($this->status < 0) {
418 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
419 return -2;
420 }
421
422 return $this->deleteLineCommon($user, $idline, $notrigger);
423 }
424
434 public function doStockMovement($label, $code_inv, $fk_entrepot, $direction = 1)
435 {
436 global $user, $langs;
437
438 require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
439 include_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php';
440 include_once DOL_DOCUMENT_ROOT . '/product/stock/stocktransfer/class/stocktransfer.class.php';
441
442 $p = new Product($this->db);
443 $p->fetch($this->fk_product);
444
445 $op = array();
446 $op[0] = "+".trim((string) $this->qty);
447 $op[1] = "-".trim((string) $this->qty);
448 $movementstock = new MouvementStock($this->db);
449 $st = new StockTransfer($this->db);
450 $movementstock->origin_type = $st->origin_type;
451 $movementstock->origin_id = $this->fk_stocktransfer;
452
453 if (empty($this->batch)) { // no batch for line
454 $result = $movementstock->_create(
455 $user,
456 $p->id,
457 $fk_entrepot,
458 (float) $op[$direction],
459 $direction,
460 empty($direction) ? $this->pmp : 0,
461 $label,
462 $code_inv
463 );
464
465 if ($result < 0) {
466 $this->setErrorsFromObject($movementstock);
467 return -1;
468 }
469 } else {
470 if ($p->hasbatch()) {
471 $arraybatchinfo = $p->loadBatchInfo($this->batch);
472 if (count($arraybatchinfo) > 0) {
473 $firstrecord = array_shift($arraybatchinfo);
474 $dlc = $firstrecord['eatby'];
475 $dluo = $firstrecord['sellby'];
476 } else {
477 $dlc = '';
478 $dluo = '';
479 }
480
481 $result = $movementstock->_create(
482 $user,
483 $p->id,
484 $fk_entrepot,
485 (float) $op[$direction],
486 $direction,
487 empty($direction) ? $this->pmp : 0,
488 $label,
489 $code_inv,
490 '',
491 $dlc,
492 $dluo,
493 $this->batch
494 );
495
496 if ($result < 0) {
497 $this->setErrorsFromObject($movementstock);
498 return $result;
499 }
500 } else {
501 $this->error = $langs->trans('StockTransferNoBatchForProduct', $p->getNomUrl());
502 $this->errors[] = $this->error;
503 return -1;
504 }
505 }
506
507 return 1;
508 }
509
517 public function validate($user, $notrigger = 0)
518 {
519 global $conf, $langs;
520
521 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
522
523 $error = 0;
524
525 // Protection
526 if ($this->status == self::STATUS_VALIDATED) {
527 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
528 return 0;
529 }
530
531 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransferline->write))
532 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransferline->stocktransferline_advance->validate))))
533 {
534 $this->error='NotEnoughPermissions';
535 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
536 return -1;
537 }*/
538
539 $now = dol_now();
540
541 $this->db->begin();
542
543 // Define new ref
544 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
545 $num = $this->getNextNumRef();
546 } else {
547 $num = (string) $this->ref;
548 }
549 $this->newref = $num;
550
551 if (!empty($num)) {
552 // Validate
553 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
554 $sql .= " SET ref = '".$this->db->escape($num)."',";
555 $sql .= " status = ".self::STATUS_VALIDATED;
556 if (!empty($this->fields['date_validation'])) {
557 $sql .= ", date_validation = '".$this->db->idate($now)."',";
558 }
559 if (!empty($this->fields['fk_user_valid'])) {
560 $sql .= ", fk_user_valid = ".((int) $user->id);
561 }
562 $sql .= " WHERE rowid = ".((int) $this->id);
563
564 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
565 $resql = $this->db->query($sql);
566 if (!$resql) {
567 dol_print_error($this->db);
568 $this->error = $this->db->lasterror();
569 $error++;
570 }
571
572 if (!$error && !$notrigger) {
573 // Call trigger
574 $result = $this->call_trigger('STOCKTRANSFERLINE_VALIDATE', $user);
575 if ($result < 0) {
576 $error++;
577 }
578 // End call triggers
579 }
580 }
581
582 if (!$error) {
583 $this->oldref = $this->ref;
584
585 // Rename directory if dir was a temporary ref
586 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
587 // Now we rename also files into index
588 $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)."'";
589 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransferline/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity);
590 $resql = $this->db->query($sql);
591 if (!$resql) {
592 $error++;
593 $this->error = $this->db->lasterror();
594 }
595 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'stocktransferline/".$this->db->escape($this->newref)."'";
596 $sql .= " WHERE filepath = 'stocktransferline/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
597 $resql = $this->db->query($sql);
598 if (!$resql) {
599 $error++;
600 $this->error = $this->db->lasterror();
601 }
602
603 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
604 $oldref = dol_sanitizeFileName($this->ref);
605 $newref = dol_sanitizeFileName($num);
606 $dirsource = $conf->stocktransfer->dir_output.'/stocktransferline/'.$oldref;
607 $dirdest = $conf->stocktransfer->dir_output.'/stocktransferline/'.$newref;
608 if (!$error && file_exists($dirsource)) {
609 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
610
611 if (@rename($dirsource, $dirdest)) {
612 dol_syslog("Rename ok");
613 // Rename docs starting with $oldref with $newref
614 $listoffiles = dol_dir_list($conf->stocktransfer->dir_output.'/stocktransferline/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
615 foreach ($listoffiles as $fileentry) {
616 $dirsource = $fileentry['name'];
617 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
618 $dirsource = $fileentry['path'].'/'.$dirsource;
619 $dirdest = $fileentry['path'].'/'.$dirdest;
620 @rename($dirsource, $dirdest);
621 }
622 }
623 }
624 }
625 }
626
627 // Set new ref and current status
628 if (!$error) {
629 $this->ref = $num;
630 $this->status = self::STATUS_VALIDATED;
631 }
632
633 if (!$error) {
634 $this->db->commit();
635 return 1;
636 } else {
637 $this->db->rollback();
638 return -1;
639 }
640 }
641
642
650 public function setDraft($user, $notrigger = 0)
651 {
652 // Protection
653 if ($this->status <= self::STATUS_DRAFT) {
654 return 0;
655 }
656
657 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
658 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
659 {
660 $this->error='Permission denied';
661 return -1;
662 }*/
663
664 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'STOCKTRANSFERLINE_UNVALIDATE');
665 }
666
674 public function cancel($user, $notrigger = 0)
675 {
676 // Protection
677 if ($this->status != self::STATUS_VALIDATED) {
678 return 0;
679 }
680
681 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
682 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
683 {
684 $this->error='Permission denied';
685 return -1;
686 }*/
687
688 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'STOCKTRANSFERLINE_CLOSE');
689 }
690
698 public function reopen($user, $notrigger = 0)
699 {
700 // Protection
701 if ($this->status != self::STATUS_CANCELED) {
702 return 0;
703 }
704
705 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
706 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
707 {
708 $this->error='Permission denied';
709 return -1;
710 }*/
711
712 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'STOCKTRANSFERLINE_REOPEN');
713 }
714
725 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
726 {
727 global $conf, $langs, $hookmanager;
728
729 if (!empty($conf->dol_no_mouse_hover)) {
730 $notooltip = 1;
731 } // Force disable tooltips
732
733 $result = '';
734
735 $label = '<u>'.$langs->trans("StockTransferLine").'</u>';
736 $label .= '<br>';
737 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
738 if (isset($this->status)) {
739 $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
740 }
741
742 $url = dol_buildpath('/stocktransfer/stocktransferline_card.php', 1).'?id='.$this->id;
743
744 if ($option != 'nolink') {
745 // Add param to save lastsearch_values or not
746 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
747 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
748 $add_save_lastsearch_values = 1;
749 }
750 if ($add_save_lastsearch_values) {
751 $url .= '&save_lastsearch_values=1';
752 }
753 }
754
755 $linkclose = '';
756 if (empty($notooltip)) {
757 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
758 $label = $langs->trans("ShowStockTransferLine");
759 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
760 }
761 $linkclose .= ' title="'.dolPrintHTMLForAttribute($label).'"';
762 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
763 } else {
764 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
765 }
766
767 $linkstart = '<a href="'.$url.'"';
768 $linkstart .= $linkclose.'>';
769 $linkend = '</a>';
770
771 $result .= $linkstart;
772
773 if (empty($this->showphoto_on_popup)) {
774 if ($withpicto) {
775 $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);
776 }
777 } else {
778 if ($withpicto) {
779 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
780
781 list($class, $module) = explode('@', $this->picto);
782 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
783 $filearray = dol_dir_list($upload_dir, "files");
784 $filename = $filearray[0]['name'];
785 if (!empty($filename)) {
786 $pospoint = strpos($filearray[0]['name'], '.');
787
788 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
789 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
790 $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>';
791 } else {
792 $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>';
793 }
794
795 $result .= '</div>';
796 } else {
797 $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);
798 }
799 }
800 }
801
802 if ($withpicto != 2) {
803 $result .= $this->ref;
804 }
805
806 $result .= $linkend;
807 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
808
809 global $action, $hookmanager;
810 $hookmanager->initHooks(array('stocktransferlinedao'));
811 $parameters = array('id' => $this->id, 'getnomurl' => $result);
812 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
813 if ($reshook > 0) {
814 $result = $hookmanager->resPrint;
815 } else {
816 $result .= $hookmanager->resPrint;
817 }
818
819 return $result;
820 }
821
828 public function getLibStatut($mode = 0)
829 {
830 return $this->LibStatut($this->status, $mode);
831 }
832
833 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
841 public function LibStatut($status, $mode = 0)
842 {
843 // phpcs:enable
844 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
845 global $langs;
846 //$langs->load("stocktransfer@stocktransfer");
847 $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft');
848 $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Enabled');
849 $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled');
850 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft');
851 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Enabled');
852 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled');
853 }
854
855 $statusType = 'status'.$status;
856 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
857 if ($status == self::STATUS_CANCELED) {
858 $statusType = 'status6';
859 }
860
861 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
862 }
863
870 public function info($id)
871 {
872 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
873 $sql .= ' fk_user_creat, fk_user_modif';
874 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
875 $sql .= ' WHERE t.rowid = '.((int) $id);
876 $result = $this->db->query($sql);
877 if ($result) {
878 if ($this->db->num_rows($result)) {
879 $obj = $this->db->fetch_object($result);
880 $this->id = $obj->rowid;
881
882 $this->user_creation_id = $obj->fk_user_creat;
883 $this->user_modification_id = $obj->fk_user_modif;
884 $this->date_creation = $this->db->jdate($obj->datec);
885 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
886 }
887
888 $this->db->free($result);
889 } else {
890 dol_print_error($this->db);
891 }
892 }
893
900 public function initAsSpecimen()
901 {
902 return $this->initAsSpecimenCommon();
903 }
904
910 public function getNextNumRef()
911 {
912 global $langs, $conf;
913 $langs->load("stocks");
914
915 if (!getDolGlobalString('STOCKTRANSFER_STOCKTRANSFERLINE_ADDON')) {
916 $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON = 'mod_stocktransferline_standard';
917 }
918
919 if (getDolGlobalString('STOCKTRANSFER_STOCKTRANSFERLINE_ADDON')) {
920 $mybool = false;
921
922 $file = getDolGlobalString('STOCKTRANSFER_STOCKTRANSFERLINE_ADDON') . ".php";
923 $classname = getDolGlobalString('STOCKTRANSFER_STOCKTRANSFERLINE_ADDON');
924
925 // Include file with class
926 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
927 foreach ($dirmodels as $reldir) {
928 $dir = dol_buildpath($reldir."core/modules/stocktransfer/");
929
930 // Load file with numbering class (if found)
931 $mybool = ((bool) @include_once $dir.$file) || $mybool;
932 }
933
934 if (!$mybool) {
935 dol_print_error(null, "Failed to include file ".$file);
936 return '';
937 }
938
939 if (class_exists($classname)) {
940 $obj = new $classname();
941 '@phan-var-force ModeleNumRefStockTransfer $obj';
942 $numref = $obj->getNextValue($this);
943
944 if ($numref != '' && $numref != '-1') {
945 return $numref;
946 } else {
947 $this->error = $obj->error;
948 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
949 return "";
950 }
951 } else {
952 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
953 return "";
954 }
955 } else {
956 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
957 return "";
958 }
959 }
960
972 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
973 {
974 global $conf, $langs;
975
976 $result = 0;
977 $includedocgeneration = 0;
978
979 $langs->load("stocks");
980
981 if (!dol_strlen($modele)) {
982 $modele = 'standard_stocktransferline';
983
984 if (!empty($this->model_pdf)) {
985 $modele = $this->model_pdf;
986 } elseif (getDolGlobalString('STOCKTRANSFERLINE_ADDON_PDF')) {
987 $modele = getDolGlobalString('STOCKTRANSFERLINE_ADDON_PDF');
988 }
989 }
990
991 $modelpath = "core/modules/stocktransfer/doc/";
992
993 if ($includedocgeneration) {
994 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
995 }
996
997 return $result;
998 }
999
1007 public function doScheduledJob()
1008 {
1009 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1010
1011 $error = 0;
1012 $this->output = '';
1013 $this->error = '';
1014
1015 dol_syslog(__METHOD__, LOG_DEBUG);
1016
1017 $now = dol_now();
1018
1019 $this->db->begin();
1020
1021 // ...
1022
1023 $this->db->commit();
1024
1025 return $error;
1026 }
1027}
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:168
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:64
dol_now($mode='gmt')
Return date for now.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
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.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
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 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.
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
buildzip.php