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