dolibarr 18.0.6
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 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
26// Put here all includes required by your class file
27require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
28//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
29//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
30
35{
39 public $element = 'stocktransferline';
40
44 public $table_element = 'stocktransfer_stocktransferline';
45
50 public $ismultientitymanaged = 0;
51
55 public $isextrafieldmanaged = 1;
56
60 public $picto = 'stocktransferline@stocktransfer';
61
62
63 const STATUS_DRAFT = 0;
64 const STATUS_VALIDATED = 1;
65 const STATUS_CANCELED = 9;
66
67
93 // BEGIN MODULEBUILDER PROPERTIES
97 public $fields=array(
98 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"),
99 'amount' => array('type'=>'price', 'label'=>'Amount', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1, 'default'=>'null', 'isameasure'=>'1', 'help'=>"Help text for amount",),
100 '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",),
101 '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,),
102 '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,),
103 'fk_stocktransfer' => array('type'=>'integer:StockTransfer:stocktransfer/stock/class/stocktransfer.class.php', 'label'=>'StockTransfer', 'enabled'=>'1', 'position'=>50, 'notnull'=>1, 'visible'=>0,),
104 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php', 'label'=>'Product', 'enabled'=>'1', 'position'=>50, 'notnull'=>1, 'visible'=>1,),
105 'batch' => array('type'=>'varchar(128)', 'label'=>'Batch', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>1,),
106 'pmp' => array('type'=>'double'/*, 'help'=>'THMEstimatedHelp'*/, 'label'=>'PMP', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1,),
107 '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",),
108 );
109 public $rowid;
110 public $amount;
111 public $qty;
112 public $fk_warehouse_destination;
113 public $fk_warehouse_source;
114 public $fk_stocktransfer;
115 public $fk_product;
116 public $batch;
117 // END MODULEBUILDER PROPERTIES
118
119
125 public function __construct(DoliDB $db)
126 {
127 global $conf, $langs;
128
129 $this->db = $db;
130
131 if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) $this->fields['rowid']['visible'] = 0;
132 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) $this->fields['entity']['enabled'] = 0;
133
134 // Example to show how to set values of fields definition dynamically
135 /*if ($user->rights->stocktransfer->stocktransferline->read) {
136 $this->fields['myfield']['visible'] = 1;
137 $this->fields['myfield']['noteditable'] = 0;
138 }*/
139
140 // Unset fields that are disabled
141 foreach ($this->fields as $key => $val) {
142 if (isset($val['enabled']) && empty($val['enabled'])) {
143 unset($this->fields[$key]);
144 }
145 }
146
147 // Translate some data of arrayofkeyval
148 if (is_object($langs)) {
149 foreach ($this->fields as $key => $val) {
150 if (is_array($val['arrayofkeyval'])) {
151 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
152 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
153 }
154 }
155 }
156 }
157 }
158
166 public function create(User $user, $notrigger = false)
167 {
168 return $this->createCommon($user, $notrigger);
169 }
170
178 public function createFromClone(User $user, $fromid)
179 {
180 global $langs, $extrafields;
181 $error = 0;
182
183 dol_syslog(__METHOD__, LOG_DEBUG);
184
185 $object = new self($this->db);
186
187 $this->db->begin();
188
189 // Load source object
190 $result = $object->fetchCommon($fromid);
191 if ($result > 0 && !empty($object->table_element_line)) $object->fetchLines();
192
193 // get lines so they will be clone
194 //foreach($this->lines as $line)
195 // $line->fetch_optionals();
196
197 // Reset some properties
198 unset($object->id);
199 unset($object->import_key);
200
201
202 // Clear fields
203 $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default'];
204 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
205 $object->status = self::STATUS_DRAFT;
206 // ...
207 // Clear extrafields that are unique
208 if (is_array($object->array_options) && count($object->array_options) > 0) {
209 $extrafields->fetch_name_optionals_label($this->table_element);
210 foreach ($object->array_options as $key => $option) {
211 $shortkey = preg_replace('/options_/', '', $key);
212 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
213 //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
214 unset($object->array_options[$key]);
215 }
216 }
217 }
218
219 // Create clone
220 $object->context['createfromclone'] = 'createfromclone';
221 $result = $object->createCommon($user);
222 if ($result < 0) {
223 $error++;
224 $this->error = $object->error;
225 $this->errors = $object->errors;
226 }
227
228 if (!$error) {
229 // copy internal contacts
230 if ($this->copy_linked_contact($object, 'internal') < 0) {
231 $error++;
232 }
233 }
234
235 if (!$error) {
236 // copy external contacts if same company
237 if (property_exists($this, 'socid') && $this->socid == $object->socid) {
238 if ($this->copy_linked_contact($object, 'external') < 0)
239 $error++;
240 }
241 }
242
243 unset($object->context['createfromclone']);
244
245 // End
246 if (!$error) {
247 $this->db->commit();
248 return $object;
249 } else {
250 $this->db->rollback();
251 return -1;
252 }
253 }
254
262 public function fetch($id, $ref = null)
263 {
264 $result = $this->fetchCommon($id, $ref);
265 if ($result > 0 && !empty($this->table_element_line)) $this->fetchLines();
266 return $result;
267 }
268
274 public function fetchLines()
275 {
276 $this->lines = array();
277
278 $result = $this->fetchLinesCommon();
279 return $result;
280 }
281
282
294 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
295 {
296 global $conf;
297
298 dol_syslog(__METHOD__, LOG_DEBUG);
299
300 $records = array();
301
302 $sql = 'SELECT ';
303 $sql .= $this->getFieldList();
304 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
305 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
306 else $sql .= ' WHERE 1 = 1';
307 // Manage filter
308 $sqlwhere = array();
309 if (count($filter) > 0) {
310 foreach ($filter as $key => $value) {
311 if ($key == 't.rowid') {
312 $sqlwhere[] = $key.'='.$value;
313 } elseif (strpos($key, 'date') !== false) {
314 $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\'';
315 } elseif ($key == 'customsql') {
316 $sqlwhere[] = $value;
317 } else {
318 $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\'';
319 }
320 }
321 }
322 if (count($sqlwhere) > 0) {
323 $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")";
324 }
325
326 if (!empty($sortfield)) {
327 $sql .= $this->db->order($sortfield, $sortorder);
328 }
329 if (!empty($limit)) {
330 $sql .= ' '.$this->db->plimit($limit, $offset);
331 }
332
333 $resql = $this->db->query($sql);
334 if ($resql) {
335 $num = $this->db->num_rows($resql);
336 $i = 0;
337 while ($i < ($limit ? min($limit, $num) : $num)) {
338 $obj = $this->db->fetch_object($resql);
339
340 $record = new self($this->db);
341 $record->setVarsFromFetchObj($obj);
342
343 $records[$record->id] = $record;
344
345 $i++;
346 }
347 $this->db->free($resql);
348
349 return $records;
350 } else {
351 $this->errors[] = 'Error '.$this->db->lasterror();
352 dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
353
354 return -1;
355 }
356 }
357
365 public function update(User $user, $notrigger = false)
366 {
367 return $this->updateCommon($user, $notrigger);
368 }
369
377 public function delete(User $user, $notrigger = false)
378 {
379 return $this->deleteCommon($user, $notrigger);
380 //return $this->deleteCommon($user, $notrigger, 1);
381 }
382
391 public function deleteLine(User $user, $idline, $notrigger = false)
392 {
393 if ($this->status < 0) {
394 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
395 return -2;
396 }
397
398 return $this->deleteLineCommon($user, $idline, $notrigger);
399 }
400
410 public function doStockMovement($label, $code_inv, $fk_entrepot, $direction = 1)
411 {
412
413 global $conf, $user, $langs;
414
415 require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
416 include_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php';
417 include_once DOL_DOCUMENT_ROOT . '/product/stock/stocktransfer/class/stocktransfer.class.php';
418
419 $p = new Product($this->db);
420 $p->fetch($this->fk_product);
421
422 $op[0] = "+".trim($this->qty);
423 $op[1] = "-".trim($this->qty);
424 $movementstock = new MouvementStock($this->db);
425 $st = new StockTransfer($this->db);
426 $movementstock->origin_type = $st->origin_type;
427 $movementstock->origin_id = $this->fk_stocktransfer;
428
429 if (empty($this->batch)) { // no batch for line
430 /*$result = $p->correct_stock(
431 $user,
432 $fk_entrepot,
433 $this->qty,
434 $direction, // 1=décrémentation
435 $label,
436 empty($direction) ? $this->pmp : 0,
437 GETPOST('inventorycode', 'alphanohtml'),
438 'stocktransfer',
439 $this->fk_stocktransfer
440 );*/
441
442 $result = $movementstock->_create($user,
443 $p->id,
444 $fk_entrepot,
445 $op[$direction],
446 $direction,
447 empty($direction) ? $this->pmp : 0,
448 $label,
449 $code_inv);
450
451 if ($result < 0) {
452 setEventMessages($p->errors, $p->errorss, 'errors');
453 return 0;
454 }
455 } else {
456 if ($p->hasbatch()) {
457 $arraybatchinfo = $p->loadBatchInfo($this->batch);
458 if (count($arraybatchinfo) > 0) {
459 $firstrecord = array_shift($arraybatchinfo);
460 $dlc = $firstrecord['eatby'];
461 $dluo = $firstrecord['sellby'];
462 //var_dump($batch); var_dump($arraybatchinfo); var_dump($firstrecord); var_dump($dlc); var_dump($dluo); exit;
463 } else {
464 $dlc = '';
465 $dluo = '';
466 }
467
468 /*$result = $p->correct_stock_batch(
469 $user,
470 $fk_entrepot,
471 $this->qty,
472 $direction,
473 $label,
474 empty($direction) ? $this->pmp : 0,
475 $dlc,
476 $dluo,
477 $this->batch,
478 GETPOST("codemove")
479 );*/
480
481 $result = $movementstock->_create($user,
482 $p->id,
483 $fk_entrepot,
484 $op[$direction],
485 $direction,
486 empty($direction) ? $this->pmp : 0,
487 $label,
488 $code_inv,
489 '',
490 $dlc,
491 $dluo,
492 $this->batch);
493
494 if ($result < 0) {
495 setEventMessages($p->errors, $p->errorss, 'errors');
496 return 0;
497 }
498 } else {
499 setEventMessages($langs->trans('StockTransferNoBatchForProduct', $p->getNomUrl()), '', 'errors');
500 return -1;
501 }
502 }
503
504 return 1;
505 }
506
514 public function validate($user, $notrigger = 0)
515 {
516 global $conf, $langs;
517
518 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
519
520 $error = 0;
521
522 // Protection
523 if ($this->status == self::STATUS_VALIDATED) {
524 dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
525 return 0;
526 }
527
528 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransferline->write))
529 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransferline->stocktransferline_advance->validate))))
530 {
531 $this->error='NotEnoughPermissions';
532 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
533 return -1;
534 }*/
535
536 $now = dol_now();
537
538 $this->db->begin();
539
540 // Define new ref
541 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
542 $num = $this->getNextNumRef();
543 } else {
544 $num = $this->ref;
545 }
546 $this->newref = $num;
547
548 if (!empty($num)) {
549 // Validate
550 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
551 $sql .= " SET ref = '".$this->db->escape($num)."',";
552 $sql .= " status = ".self::STATUS_VALIDATED;
553 if (!empty($this->fields['date_validation'])) $sql .= ", date_validation = '".$this->db->idate($now)."',";
554 if (!empty($this->fields['fk_user_valid'])) $sql .= ", fk_user_valid = ".((int) $user->id);
555 $sql .= " WHERE rowid = ".((int) $this->id);
556
557 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
558 $resql = $this->db->query($sql);
559 if (!$resql) {
560 dol_print_error($this->db);
561 $this->error = $this->db->lasterror();
562 $error++;
563 }
564
565 if (!$error && !$notrigger) {
566 // Call trigger
567 $result = $this->call_trigger('STOCKTRANSFERLINE_VALIDATE', $user);
568 if ($result < 0) $error++;
569 // End call triggers
570 }
571 }
572
573 if (!$error) {
574 $this->oldref = $this->ref;
575
576 // Rename directory if dir was a temporary ref
577 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
578 // Now we rename also files into index
579 $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)."'";
580 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'stocktransferline/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity);
581 $resql = $this->db->query($sql);
582 if (!$resql) {
583 $error++; $this->error = $this->db->lasterror();
584 }
585 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'stocktransferline/".$this->db->escape($this->newref)."'";
586 $sql .= " WHERE filepath = 'stocktransferline/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
587 $resql = $this->db->query($sql);
588 if (!$resql) {
589 $error++; $this->error = $this->db->lasterror();
590 }
591
592 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
593 $oldref = dol_sanitizeFileName($this->ref);
594 $newref = dol_sanitizeFileName($num);
595 $dirsource = $conf->stocktransfer->dir_output.'/stocktransferline/'.$oldref;
596 $dirdest = $conf->stocktransfer->dir_output.'/stocktransferline/'.$newref;
597 if (!$error && file_exists($dirsource)) {
598 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
599
600 if (@rename($dirsource, $dirdest)) {
601 dol_syslog("Rename ok");
602 // Rename docs starting with $oldref with $newref
603 $listoffiles = dol_dir_list($conf->stocktransfer->dir_output.'/stocktransferline/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
604 foreach ($listoffiles as $fileentry) {
605 $dirsource = $fileentry['name'];
606 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
607 $dirsource = $fileentry['path'].'/'.$dirsource;
608 $dirdest = $fileentry['path'].'/'.$dirdest;
609 @rename($dirsource, $dirdest);
610 }
611 }
612 }
613 }
614 }
615
616 // Set new ref and current status
617 if (!$error) {
618 $this->ref = $num;
619 $this->status = self::STATUS_VALIDATED;
620 }
621
622 if (!$error) {
623 $this->db->commit();
624 return 1;
625 } else {
626 $this->db->rollback();
627 return -1;
628 }
629 }
630
631
639 public function setDraft($user, $notrigger = 0)
640 {
641 // Protection
642 if ($this->status <= self::STATUS_DRAFT) {
643 return 0;
644 }
645
646 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
647 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
648 {
649 $this->error='Permission denied';
650 return -1;
651 }*/
652
653 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'STOCKTRANSFERLINE_UNVALIDATE');
654 }
655
663 public function cancel($user, $notrigger = 0)
664 {
665 // Protection
666 if ($this->status != self::STATUS_VALIDATED) {
667 return 0;
668 }
669
670 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
671 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
672 {
673 $this->error='Permission denied';
674 return -1;
675 }*/
676
677 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'STOCKTRANSFERLINE_CLOSE');
678 }
679
687 public function reopen($user, $notrigger = 0)
688 {
689 // Protection
690 if ($this->status != self::STATUS_CANCELED) {
691 return 0;
692 }
693
694 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->write))
695 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->stocktransfer->stocktransfer_advance->validate))))
696 {
697 $this->error='Permission denied';
698 return -1;
699 }*/
700
701 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'STOCKTRANSFERLINE_REOPEN');
702 }
703
714 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
715 {
716 global $conf, $langs, $hookmanager;
717
718 if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips
719
720 $result = '';
721
722 $label = '<u>'.$langs->trans("StockTransferLine").'</u>';
723 $label .= '<br>';
724 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
725 if (isset($this->status)) {
726 $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
727 }
728
729 $url = dol_buildpath('/stocktransfer/stocktransferline_card.php', 1).'?id='.$this->id;
730
731 if ($option != 'nolink') {
732 // Add param to save lastsearch_values or not
733 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
734 if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1;
735 if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1';
736 }
737
738 $linkclose = '';
739 if (empty($notooltip)) {
740 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
741 $label = $langs->trans("ShowStockTransferLine");
742 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
743 }
744 $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
745 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
746 } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
747
748 $linkstart = '<a href="'.$url.'"';
749 $linkstart .= $linkclose.'>';
750 $linkend = '</a>';
751
752 $result .= $linkstart;
753
754 if (empty($this->showphoto_on_popup)) {
755 if ($withpicto) $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);
756 } else {
757 if ($withpicto) {
758 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
759
760 list($class, $module) = explode('@', $this->picto);
761 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
762 $filearray = dol_dir_list($upload_dir, "files");
763 $filename = $filearray[0]['name'];
764 if (!empty($filename)) {
765 $pospoint = strpos($filearray[0]['name'], '.');
766
767 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
768 if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) {
769 $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>';
770 } else {
771 $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>';
772 }
773
774 $result .= '</div>';
775 } else {
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 }
779 }
780
781 if ($withpicto != 2) $result .= $this->ref;
782
783 $result .= $linkend;
784 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
785
786 global $action, $hookmanager;
787 $hookmanager->initHooks(array('stocktransferlinedao'));
788 $parameters = array('id'=>$this->id, 'getnomurl'=>$result);
789 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
790 if ($reshook > 0) $result = $hookmanager->resPrint;
791 else $result .= $hookmanager->resPrint;
792
793 return $result;
794 }
795
802 public function getLibStatut($mode = 0)
803 {
804 return $this->LibStatut($this->status, $mode);
805 }
806
807 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
815 public function LibStatut($status, $mode = 0)
816 {
817 // phpcs:enable
818 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
819 global $langs;
820 //$langs->load("stocktransfer@stocktransfer");
821 $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft');
822 $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Enabled');
823 $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled');
824 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft');
825 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Enabled');
826 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled');
827 }
828
829 $statusType = 'status'.$status;
830 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
831 if ($status == self::STATUS_CANCELED) $statusType = 'status6';
832
833 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
834 }
835
842 public function info($id)
843 {
844 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
845 $sql .= ' fk_user_creat, fk_user_modif';
846 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
847 $sql .= ' WHERE t.rowid = '.((int) $id);
848 $result = $this->db->query($sql);
849 if ($result) {
850 if ($this->db->num_rows($result)) {
851 $obj = $this->db->fetch_object($result);
852 $this->id = $obj->rowid;
853
854 $this->user_creation_id = $obj->fk_user_creat;
855 $this->user_modification_id = $obj->fk_user_modif;
856 $this->date_creation = $this->db->jdate($obj->datec);
857 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
858 }
859
860 $this->db->free($result);
861 } else {
862 dol_print_error($this->db);
863 }
864 }
865
872 public function initAsSpecimen()
873 {
874 $this->initAsSpecimenCommon();
875 }
876
882 public function getLinesArray()
883 {
884 $this->lines = array();
885
886 $objectline = new StockTransferLineLine($this->db);
887 $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_stocktransferline = '.((int) $this->id)));
888
889 if (is_numeric($result)) {
890 $this->error = $objectline->error;
891 $this->errors = $objectline->errors;
892 return $result;
893 } else {
894 $this->lines = $result;
895 return $this->lines;
896 }
897 }
898
904 public function getNextNumRef()
905 {
906 global $langs, $conf;
907 $langs->load("stocks");
908
909 if (empty($conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON)) {
910 $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON = 'mod_stocktransferline_standard';
911 }
912
913 if (!empty($conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON)) {
914 $mybool = false;
915
916 $file = $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON.".php";
917 $classname = $conf->global->STOCKTRANSFER_STOCKTRANSFERLINE_ADDON;
918
919 // Include file with class
920 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
921 foreach ($dirmodels as $reldir) {
922 $dir = dol_buildpath($reldir."core/modules/stocktransfer/");
923
924 // Load file with numbering class (if found)
925 $mybool |= @include_once $dir.$file;
926 }
927
928 if ($mybool === false) {
929 dol_print_error('', "Failed to include file ".$file);
930 return '';
931 }
932
933 if (class_exists($classname)) {
934 $obj = new $classname();
935 $numref = $obj->getNextValue($this);
936
937 if ($numref != '' && $numref != '-1') {
938 return $numref;
939 } else {
940 $this->error = $obj->error;
941 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
942 return "";
943 }
944 } else {
945 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
946 return "";
947 }
948 } else {
949 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
950 return "";
951 }
952 }
953
965 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
966 {
967 global $conf, $langs;
968
969 $result = 0;
970 $includedocgeneration = 0;
971
972 $langs->load("stocks");
973
974 if (!dol_strlen($modele)) {
975 $modele = 'standard_stocktransferline';
976
977 if ($this->modelpdf) {
978 $modele = $this->modelpdf;
979 } elseif (!empty($conf->global->STOCKTRANSFERLINE_ADDON_PDF)) {
980 $modele = $conf->global->STOCKTRANSFERLINE_ADDON_PDF;
981 }
982 }
983
984 $modelpath = "core/modules/stocktransfer/doc/";
985
986 if ($includedocgeneration) {
987 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
988 }
989
990 return $result;
991 }
992
1000 public function doScheduledJob()
1001 {
1002 global $conf, $langs;
1003
1004 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1005
1006 $error = 0;
1007 $this->output = '';
1008 $this->error = '';
1009
1010 dol_syslog(__METHOD__, LOG_DEBUG);
1011
1012 $now = dol_now();
1013
1014 $this->db->begin();
1015
1016 // ...
1017
1018 $this->db->commit();
1019
1020 return $error;
1021 }
1022}
1023
1028{
1029 // To complete with content of an object StockTransferLineLine
1030 // We should have a field rowid, fk_stocktransferline and position
1031
1035 public $isextrafieldmanaged = 0;
1036
1042 public function __construct(DoliDB $db)
1043 {
1044 $this->db = $db;
1045 }
1046}
$object ref
Definition info.php:78
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
fetchCommon($id, $ref=null, $morewhere='')
Load object in memory from the database.
createCommon(User $user, $notrigger=false)
Create object into database.
deleteCommon(User $user, $notrigger=false, $forcechilddeletion=0)
Delete object in database.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
updateCommon(User $user, $notrigger=false)
Update object into database.
fetchLinesCommon($morewhere='')
Load object in memory from the 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.
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.
create(User $user, $notrigger=false)
Create object into database.
validate($user, $notrigger=0)
Validate object.
update(User $user, $notrigger=false)
Update object into database.
getLinesArray()
Create an array of lines.
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.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter=array(), $filtermode='AND')
Load list of objects in memory from the database.
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.
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 optionaly the picto)
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
Class StockTransferLineLine.
__construct(DoliDB $db)
Constructor.
Class to manage Dolibarr users.
dol_dir_list($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:62
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_now($mode='auto')
Return date for now.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
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_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.