dolibarr 21.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) ---Put here your own copyright and developer email---
5 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
6 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
28// Put here all includes required by your class file
29require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
30//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
31//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
32
37{
41 public $element = 'stocktransferline';
42
46 public $table_element = 'stocktransfer_stocktransferline';
47
51 public $picto = 'stocktransferline@stocktransfer';
52
53 const STATUS_DRAFT = 0;
54 const STATUS_VALIDATED = 1;
55 const STATUS_CANCELED = 9;
56
57
83 // BEGIN MODULEBUILDER PROPERTIES
87 public $fields = array(
88 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'comment' => "Id"),
89 'amount' => array('type' => 'price', 'label' => 'Amount', 'enabled' => 1, 'position' => 40, 'notnull' => 0, 'visible' => 1, 'default' => 'null', 'isameasure' => 1, 'help' => "Help text for amount",),
90 'qty' => array('type' => 'real', 'label' => 'Qty', 'enabled' => 1, 'position' => 45, 'notnull' => 0, 'visible' => 1, 'default' => '0', 'isameasure' => 1, 'css' => 'maxwidth75imp', 'help' => "Help text for quantity",),
91 'fk_warehouse_destination' => array('type' => 'integer:Entrepot:product/stock/class/entrepot.class.php', 'label' => 'Entrepôt de destination', 'enabled' => 1, 'position' => 50, 'notnull' => 1, 'visible' => 1,),
92 'fk_warehouse_source' => array('type' => 'integer:Entrepot:product/stock/class/entrepot.class.php', 'label' => 'Entrepôt source', 'enabled' => 1, 'position' => 50, 'notnull' => 1, 'visible' => 1,),
93 'fk_stocktransfer' => array('type' => 'integer:StockTransfer:stocktransfer/stock/class/stocktransfer.class.php', 'label' => 'StockTransfer', 'enabled' => 1, 'position' => 50, 'notnull' => 1, 'visible' => 0,),
94 'fk_product' => array('type' => 'integer:Product:product/class/product.class.php', 'label' => 'Product', 'enabled' => 1, 'position' => 50, 'notnull' => 1, 'visible' => 1,),
95 'batch' => array('type' => 'varchar(128)', 'label' => 'Batch', 'enabled' => 1, 'position' => 1000, 'notnull' => -1, 'visible' => 1,),
96 'pmp' => array('type' => 'double'/*, 'help'=>'THMEstimatedHelp'*/, 'label' => 'PMP', 'enabled' => 1, 'position' => 50, 'notnull' => 0, 'visible' => 1,),
97 'rang' => array('type' => 'integer', 'label' => 'Qty', 'enabled' => 1, 'position' => 45, 'notnull' => 0, 'visible' => 0, 'default' => '0', 'isameasure' => 1, 'css' => 'maxwidth75imp', 'help' => "Help text for quantity",),
98 );
102 public $rowid;
106 public $amount;
107
111 public $qty;
115 public $fk_warehouse_destination;
119 public $fk_warehouse_source;
123 public $fk_stocktransfer;
127 public $fk_product;
131 public $batch;
132
136 public $pmp;
137
138 // END MODULEBUILDER PROPERTIES
139
140
146 public function __construct(DoliDB $db)
147 {
148 global $conf, $langs;
149
150 $this->db = $db;
151
152 $this->ismultientitymanaged = 0;
153 $this->isextrafieldmanaged = 1;
154
155 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
156 $this->fields['rowid']['visible'] = 0;
157 }
158 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
159 $this->fields['entity']['enabled'] = 0;
160 }
161
162 // Example to show how to set values of fields definition dynamically
163 /*if ($user->rights->stocktransfer->stocktransferline->read) {
164 $this->fields['myfield']['visible'] = 1;
165 $this->fields['myfield']['noteditable'] = 0;
166 }*/
167
168 // Unset fields that are disabled
169 foreach ($this->fields as $key => $val) {
170 if (isset($val['enabled']) && empty($val['enabled'])) {
171 unset($this->fields[$key]);
172 }
173 }
174
175 // Translate some data of arrayofkeyval
176 if (is_object($langs)) {
177 foreach ($this->fields as $key => $val) {
178 if (isset($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
179 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
180 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
181 }
182 }
183 }
184 }
185 }
186
194 public function create(User $user, $notrigger = 0)
195 {
196 return $this->createCommon($user, $notrigger);
197 }
198
206 public function createFromClone(User $user, $fromid)
207 {
208 global $langs, $extrafields;
209 $error = 0;
210
211 dol_syslog(__METHOD__, LOG_DEBUG);
212
213 $object = new self($this->db);
214
215 $this->db->begin();
216
217 // Load source object
218 $result = $object->fetchCommon($fromid);
219 if ($result > 0 && !empty($object->table_element_line)) {
220 $object->fetchLines();
221 }
222
223 // get lines so they will be clone
224 //foreach($this->lines as $line)
225 // $line->fetch_optionals();
226
227 // Reset some properties
228 unset($object->id);
229 unset($object->import_key);
230
231
232 // Clear fields
233 $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default'];
234 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
235 $object->status = self::STATUS_DRAFT;
236 // ...
237 // Clear extrafields that are unique
238 if (is_array($object->array_options) && count($object->array_options) > 0) {
239 $extrafields->fetch_name_optionals_label($this->table_element);
240 foreach ($object->array_options as $key => $option) {
241 $shortkey = preg_replace('/options_/', '', $key);
242 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
243 //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
244 unset($object->array_options[$key]);
245 }
246 }
247 }
248
249 // Create clone
250 $object->context['createfromclone'] = 'createfromclone';
251 $result = $object->createCommon($user);
252 if ($result < 0) {
253 $error++;
254 $this->error = $object->error;
255 $this->errors = $object->errors;
256 }
257
258 if (!$error) {
259 // copy internal contacts
260 if ($this->copy_linked_contact($object, 'internal') < 0) {
261 $error++;
262 }
263 }
264
265 if (!$error) {
266 // copy external contacts if same company
267 if (property_exists($this, 'socid') && $this->socid == $object->socid) {
268 if ($this->copy_linked_contact($object, 'external') < 0) {
269 $error++;
270 }
271 }
272 }
273
274 unset($object->context['createfromclone']);
275
276 // End
277 if (!$error) {
278 $this->db->commit();
279 return $object;
280 } else {
281 $this->db->rollback();
282 return -1;
283 }
284 }
285
293 public function fetch($id, $ref = null)
294 {
295 $result = $this->fetchCommon($id, $ref);
296 if ($result > 0 && !empty($this->table_element_line)) {
297 $this->fetchLines();
298 }
299 return $result;
300 }
301
307 public function fetchLines()
308 {
309 $this->lines = array();
310
311 $result = $this->fetchLinesCommon();
312 return $result;
313 }
314
315
328 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
329 {
330 dol_syslog(__METHOD__, LOG_DEBUG);
331
332 $records = array();
333
334 $sql = 'SELECT ';
335 $sql .= $this->getFieldList();
336 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
337 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
338 $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
339 } else {
340 $sql .= ' WHERE 1 = 1';
341 }
342
343 // Manage filter
344 $errormessage = '';
345 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
346 if ($errormessage) {
347 $this->errors[] = $errormessage;
348 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
349 return -1;
350 }
351
352 if (!empty($sortfield)) {
353 $sql .= $this->db->order($sortfield, $sortorder);
354 }
355 if (!empty($limit)) {
356 $sql .= ' '.$this->db->plimit($limit, $offset);
357 }
358
359 $resql = $this->db->query($sql);
360 if ($resql) {
361 $num = $this->db->num_rows($resql);
362 $i = 0;
363 while ($i < ($limit ? min($limit, $num) : $num)) {
364 $obj = $this->db->fetch_object($resql);
365
366 $record = new self($this->db);
367 $record->setVarsFromFetchObj($obj);
368
369 $records[$record->id] = $record;
370
371 $i++;
372 }
373 $this->db->free($resql);
374
375 return $records;
376 } else {
377 $this->errors[] = 'Error '.$this->db->lasterror();
378 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
379
380 return -1;
381 }
382 }
383
391 public function update(User $user, $notrigger = 0)
392 {
393 return $this->updateCommon($user, $notrigger);
394 }
395
403 public function delete(User $user, $notrigger = 0)
404 {
405 return $this->deleteCommon($user, $notrigger);
406 //return $this->deleteCommon($user, $notrigger, 1);
407 }
408
417 public function deleteLine(User $user, $idline, $notrigger = 0)
418 {
419 if ($this->status < 0) {
420 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
421 return -2;
422 }
423
424 return $this->deleteLineCommon($user, $idline, $notrigger);
425 }
426
436 public function doStockMovement($label, $code_inv, $fk_entrepot, $direction = 1)
437 {
438 global $user, $langs;
439
440 require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
441 include_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php';
442 include_once DOL_DOCUMENT_ROOT . '/product/stock/stocktransfer/class/stocktransfer.class.php';
443
444 $p = new Product($this->db);
445 $p->fetch($this->fk_product);
446
447 $op = array();
448 $op[0] = "+".trim((string) $this->qty);
449 $op[1] = "-".trim((string) $this->qty);
450 $movementstock = new MouvementStock($this->db);
451 $st = new StockTransfer($this->db);
452 $movementstock->origin_type = $st->origin_type;
453 $movementstock->origin_id = $this->fk_stocktransfer;
454
455 if (empty($this->batch)) { // no batch for line
456 $result = $movementstock->_create(
457 $user,
458 $p->id,
459 $fk_entrepot,
460 $op[$direction],
461 $direction,
462 empty($direction) ? $this->pmp : 0,
463 $label,
464 $code_inv
465 );
466
467 if ($result < 0) {
468 $this->setErrorsFromObject($movementstock);
469 return -1;
470 }
471 } else {
472 if ($p->hasbatch()) {
473 $arraybatchinfo = $p->loadBatchInfo($this->batch);
474 if (count($arraybatchinfo) > 0) {
475 $firstrecord = array_shift($arraybatchinfo);
476 $dlc = $firstrecord['eatby'];
477 $dluo = $firstrecord['sellby'];
478 } else {
479 $dlc = '';
480 $dluo = '';
481 }
482
483 $result = $movementstock->_create(
484 $user,
485 $p->id,
486 $fk_entrepot,
487 $op[$direction],
488 $direction,
489 empty($direction) ? $this->pmp : 0,
490 $label,
491 $code_inv,
492 '',
493 $dlc,
494 $dluo,
495 $this->batch
496 );
497
498 if ($result < 0) {
499 $this->setErrorsFromObject($movementstock);
500 return $result;
501 }
502 } else {
503 $this->error = $langs->trans('StockTransferNoBatchForProduct', $p->getNomUrl());
504 $this->errors[] = $this->error;
505 return -1;
506 }
507 }
508
509 return 1;
510 }
511
519 public function validate($user, $notrigger = 0)
520 {
521 global $conf, $langs;
522
523 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
524
525 $error = 0;
526
527 // Protection
528 if ($this->status == self::STATUS_VALIDATED) {
529 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
530 return 0;
531 }
532
533 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransferline->write))
534 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransferline->stocktransferline_advance->validate))))
535 {
536 $this->error='NotEnoughPermissions';
537 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
538 return -1;
539 }*/
540
541 $now = dol_now();
542
543 $this->db->begin();
544
545 // Define new ref
546 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
547 $num = $this->getNextNumRef();
548 } else {
549 $num = $this->ref;
550 }
551 $this->newref = $num;
552
553 if (!empty($num)) {
554 // Validate
555 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
556 $sql .= " SET ref = '".$this->db->escape($num)."',";
557 $sql .= " status = ".self::STATUS_VALIDATED;
558 if (!empty($this->fields['date_validation'])) {
559 $sql .= ", date_validation = '".$this->db->idate($now)."',";
560 }
561 if (!empty($this->fields['fk_user_valid'])) {
562 $sql .= ", fk_user_valid = ".((int) $user->id);
563 }
564 $sql .= " WHERE rowid = ".((int) $this->id);
565
566 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
567 $resql = $this->db->query($sql);
568 if (!$resql) {
569 dol_print_error($this->db);
570 $this->error = $this->db->lasterror();
571 $error++;
572 }
573
574 if (!$error && !$notrigger) {
575 // Call trigger
576 $result = $this->call_trigger('STOCKTRANSFERLINE_VALIDATE', $user);
577 if ($result < 0) {
578 $error++;
579 }
580 // End call triggers
581 }
582 }
583
584 if (!$error) {
585 $this->oldref = $this->ref;
586
587 // Rename directory if dir was a temporary ref
588 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
589 // Now we rename also files into index
590 $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)."'";
591 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransferline/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity);
592 $resql = $this->db->query($sql);
593 if (!$resql) {
594 $error++;
595 $this->error = $this->db->lasterror();
596 }
597 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'stocktransferline/".$this->db->escape($this->newref)."'";
598 $sql .= " WHERE filepath = 'stocktransferline/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
599 $resql = $this->db->query($sql);
600 if (!$resql) {
601 $error++;
602 $this->error = $this->db->lasterror();
603 }
604
605 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
606 $oldref = dol_sanitizeFileName($this->ref);
607 $newref = dol_sanitizeFileName($num);
608 $dirsource = $conf->stocktransfer->dir_output.'/stocktransferline/'.$oldref;
609 $dirdest = $conf->stocktransfer->dir_output.'/stocktransferline/'.$newref;
610 if (!$error && file_exists($dirsource)) {
611 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
612
613 if (@rename($dirsource, $dirdest)) {
614 dol_syslog("Rename ok");
615 // Rename docs starting with $oldref with $newref
616 $listoffiles = dol_dir_list($conf->stocktransfer->dir_output.'/stocktransferline/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
617 foreach ($listoffiles as $fileentry) {
618 $dirsource = $fileentry['name'];
619 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
620 $dirsource = $fileentry['path'].'/'.$dirsource;
621 $dirdest = $fileentry['path'].'/'.$dirdest;
622 @rename($dirsource, $dirdest);
623 }
624 }
625 }
626 }
627 }
628
629 // Set new ref and current status
630 if (!$error) {
631 $this->ref = $num;
632 $this->status = self::STATUS_VALIDATED;
633 }
634
635 if (!$error) {
636 $this->db->commit();
637 return 1;
638 } else {
639 $this->db->rollback();
640 return -1;
641 }
642 }
643
644
652 public function setDraft($user, $notrigger = 0)
653 {
654 // Protection
655 if ($this->status <= self::STATUS_DRAFT) {
656 return 0;
657 }
658
659 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
660 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
661 {
662 $this->error='Permission denied';
663 return -1;
664 }*/
665
666 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'STOCKTRANSFERLINE_UNVALIDATE');
667 }
668
676 public function cancel($user, $notrigger = 0)
677 {
678 // Protection
679 if ($this->status != self::STATUS_VALIDATED) {
680 return 0;
681 }
682
683 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
684 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
685 {
686 $this->error='Permission denied';
687 return -1;
688 }*/
689
690 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'STOCKTRANSFERLINE_CLOSE');
691 }
692
700 public function reopen($user, $notrigger = 0)
701 {
702 // Protection
703 if ($this->status != self::STATUS_CANCELED) {
704 return 0;
705 }
706
707 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
708 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
709 {
710 $this->error='Permission denied';
711 return -1;
712 }*/
713
714 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'STOCKTRANSFERLINE_REOPEN');
715 }
716
727 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
728 {
729 global $conf, $langs, $hookmanager;
730
731 if (!empty($conf->dol_no_mouse_hover)) {
732 $notooltip = 1;
733 } // Force disable tooltips
734
735 $result = '';
736
737 $label = '<u>'.$langs->trans("StockTransferLine").'</u>';
738 $label .= '<br>';
739 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
740 if (isset($this->status)) {
741 $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
742 }
743
744 $url = dol_buildpath('/stocktransfer/stocktransferline_card.php', 1).'?id='.$this->id;
745
746 if ($option != 'nolink') {
747 // Add param to save lastsearch_values or not
748 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
749 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
750 $add_save_lastsearch_values = 1;
751 }
752 if ($add_save_lastsearch_values) {
753 $url .= '&save_lastsearch_values=1';
754 }
755 }
756
757 $linkclose = '';
758 if (empty($notooltip)) {
759 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
760 $label = $langs->trans("ShowStockTransferLine");
761 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
762 }
763 $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
764 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
765 } else {
766 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
767 }
768
769 $linkstart = '<a href="'.$url.'"';
770 $linkstart .= $linkclose.'>';
771 $linkend = '</a>';
772
773 $result .= $linkstart;
774
775 if (empty($this->showphoto_on_popup)) {
776 if ($withpicto) {
777 $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);
778 }
779 } else {
780 if ($withpicto) {
781 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
782
783 list($class, $module) = explode('@', $this->picto);
784 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
785 $filearray = dol_dir_list($upload_dir, "files");
786 $filename = $filearray[0]['name'];
787 if (!empty($filename)) {
788 $pospoint = strpos($filearray[0]['name'], '.');
789
790 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
791 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
792 $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>';
793 } else {
794 $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>';
795 }
796
797 $result .= '</div>';
798 } else {
799 $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);
800 }
801 }
802 }
803
804 if ($withpicto != 2) {
805 $result .= $this->ref;
806 }
807
808 $result .= $linkend;
809 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
810
811 global $action, $hookmanager;
812 $hookmanager->initHooks(array('stocktransferlinedao'));
813 $parameters = array('id' => $this->id, 'getnomurl' => $result);
814 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
815 if ($reshook > 0) {
816 $result = $hookmanager->resPrint;
817 } else {
818 $result .= $hookmanager->resPrint;
819 }
820
821 return $result;
822 }
823
830 public function getLibStatut($mode = 0)
831 {
832 return $this->LibStatut($this->status, $mode);
833 }
834
835 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
843 public function LibStatut($status, $mode = 0)
844 {
845 // phpcs:enable
846 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
847 global $langs;
848 //$langs->load("stocktransfer@stocktransfer");
849 $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft');
850 $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Enabled');
851 $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled');
852 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft');
853 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Enabled');
854 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled');
855 }
856
857 $statusType = 'status'.$status;
858 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
859 if ($status == self::STATUS_CANCELED) {
860 $statusType = 'status6';
861 }
862
863 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
864 }
865
872 public function info($id)
873 {
874 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
875 $sql .= ' fk_user_creat, fk_user_modif';
876 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
877 $sql .= ' WHERE t.rowid = '.((int) $id);
878 $result = $this->db->query($sql);
879 if ($result) {
880 if ($this->db->num_rows($result)) {
881 $obj = $this->db->fetch_object($result);
882 $this->id = $obj->rowid;
883
884 $this->user_creation_id = $obj->fk_user_creat;
885 $this->user_modification_id = $obj->fk_user_modif;
886 $this->date_creation = $this->db->jdate($obj->datec);
887 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
888 }
889
890 $this->db->free($result);
891 } else {
892 dol_print_error($this->db);
893 }
894 }
895
902 public function initAsSpecimen()
903 {
904 return $this->initAsSpecimenCommon();
905 }
906
912 public function getNextNumRef()
913 {
914 global $langs, $conf;
915 $langs->load("stocks");
916
917 if (!getDolGlobalString('STOCKTRANSFER_STOCKTRANSFERLINE_ADDON')) {
918 $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON = 'mod_stocktransferline_standard';
919 }
920
921 if (getDolGlobalString('STOCKTRANSFER_STOCKTRANSFERLINE_ADDON')) {
922 $mybool = false;
923
924 $file = getDolGlobalString('STOCKTRANSFER_STOCKTRANSFERLINE_ADDON') . ".php";
925 $classname = getDolGlobalString('STOCKTRANSFER_STOCKTRANSFERLINE_ADDON');
926
927 // Include file with class
928 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
929 foreach ($dirmodels as $reldir) {
930 $dir = dol_buildpath($reldir."core/modules/stocktransfer/");
931
932 // Load file with numbering class (if found)
933 $mybool = ((bool) @include_once $dir.$file) || $mybool;
934 }
935
936 if (!$mybool) {
937 dol_print_error(null, "Failed to include file ".$file);
938 return '';
939 }
940
941 if (class_exists($classname)) {
942 $obj = new $classname();
943 '@phan-var-force ModeleNumRefStockTransfer $obj';
944 $numref = $obj->getNextValue($this);
945
946 if ($numref != '' && $numref != '-1') {
947 return $numref;
948 } else {
949 $this->error = $obj->error;
950 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
951 return "";
952 }
953 } else {
954 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
955 return "";
956 }
957 } else {
958 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
959 return "";
960 }
961 }
962
974 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
975 {
976 global $conf, $langs;
977
978 $result = 0;
979 $includedocgeneration = 0;
980
981 $langs->load("stocks");
982
983 if (!dol_strlen($modele)) {
984 $modele = 'standard_stocktransferline';
985
986 if (!empty($this->model_pdf)) {
987 $modele = $this->model_pdf;
988 } elseif (getDolGlobalString('STOCKTRANSFERLINE_ADDON_PDF')) {
989 $modele = getDolGlobalString('STOCKTRANSFERLINE_ADDON_PDF');
990 }
991 }
992
993 $modelpath = "core/modules/stocktransfer/doc/";
994
995 if ($includedocgeneration) {
996 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
997 }
998
999 return $result;
1000 }
1001
1009 public function doScheduledJob()
1010 {
1011 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1012
1013 $error = 0;
1014 $this->output = '';
1015 $this->error = '';
1016
1017 dol_syslog(__METHOD__, LOG_DEBUG);
1018
1019 $now = dol_now();
1020
1021 $this->db->begin();
1022
1023 // ...
1024
1025 $this->db->commit();
1026
1027 return $error;
1028 }
1029}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
$object ref
Definition info.php:89
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)
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_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return 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