dolibarr  18.0.6
mo.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2020 Lenin Rivas <lenin@leninrivas.com>
4  * Copyright (C) 2023 Frédéric France <frederic.france@free.fr>
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
27 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
28 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
29 
33 class Mo extends CommonObject
34 {
38  public $element = 'mo';
39 
43  public $table_element = 'mrp_mo';
44 
48  public $ismultientitymanaged = 1;
49 
53  public $isextrafieldmanaged = 1;
54 
58  public $picto = 'mrp';
59 
60 
61  const STATUS_DRAFT = 0;
62  const STATUS_VALIDATED = 1; // To produce
63  const STATUS_INPROGRESS = 2;
64  const STATUS_PRODUCED = 3;
65  const STATUS_CANCELED = 9;
66 
67 
97  public $fields = array(
98  'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",),
99  'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'position'=>5, 'notnull'=>1, 'default'=>'1', 'index'=>1),
100  'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>4, 'position'=>10, 'notnull'=>1, 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of object", 'showoncombobox'=>'1', 'noteditable'=>1),
101  'fk_bom' => array('type'=>'integer:Bom:bom/class/bom.class.php:0:(t.status:=:1)', 'filter'=>'active=1', 'label'=>'BOM', 'enabled'=>'$conf->bom->enabled', 'visible'=>1, 'position'=>33, 'notnull'=>-1, 'index'=>1, 'comment'=>"Original BOM", 'css'=>'minwidth100 maxwidth500', 'csslist'=>'tdoverflowmax150', 'picto'=>'bom'),
102  'mrptype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>1, 'position'=>34, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing', 1=>'Disassemble'), 'css'=>'minwidth150', 'csslist'=>'minwidth150 center'),
103  'fk_product' => array('type'=>'integer:Product:product/class/product.class.php:0', 'label'=>'Product', 'enabled'=>'isModEnabled("product")', 'visible'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'comment'=>"Product to produce", 'css'=>'maxwidth300', 'csslist'=>'tdoverflowmax100', 'picto'=>'product'),
104  'qty' => array('type'=>'real', 'label'=>'QtyToProduce', 'enabled'=>1, 'visible'=>1, 'position'=>40, 'notnull'=>1, 'comment'=>"Qty to produce", 'css'=>'width75', 'default'=>1, 'isameasure'=>1),
105  'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>42, 'notnull'=>-1, 'searchall'=>1, 'showoncombobox'=>'2', 'css'=>'maxwidth300', 'csslist'=>'tdoverflowmax200', 'alwayseditable'=>1),
106  'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1', 'label'=>'ThirdParty', 'picto'=>'company', 'enabled'=>'isModEnabled("societe")', 'visible'=>-1, 'position'=>50, 'notnull'=>-1, 'index'=>1, 'css'=>'maxwidth400', 'csslist'=>'tdoverflowmax150'),
107  'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Project', 'picto'=>'project', 'enabled'=>'$conf->project->enabled', 'visible'=>-1, 'position'=>51, 'notnull'=>-1, 'index'=>1, 'css'=>'minwidth200 maxwidth400', 'csslist'=>'tdoverflowmax100'),
108  'fk_warehouse' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php:0', 'label'=>'WarehouseForProduction', 'picto'=>'stock', 'enabled'=>'isModEnabled("stock")', 'visible'=>1, 'position'=>52, 'css'=>'maxwidth400', 'csslist'=>'tdoverflowmax200'),
109  'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61, 'notnull'=>-1,),
110  'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>62, 'notnull'=>-1,),
111  'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>500, 'notnull'=>1,),
112  'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'position'=>501, 'notnull'=>1,),
113  'date_valid' => array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-2, 'position'=>502,),
114  'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-2, 'position'=>510, 'notnull'=>1, 'foreignkey'=>'user.rowid', 'csslist'=>'tdoverflowmax100'),
115  'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'position'=>511, 'notnull'=>-1, 'csslist'=>'tdoverflowmax100'),
116  'date_start_planned' => array('type'=>'datetime', 'label'=>'DateStartPlannedMo', 'enabled'=>1, 'visible'=>1, 'position'=>55, 'notnull'=>-1, 'index'=>1, 'help'=>'KeepEmptyForAsap', 'alwayseditable'=>1),
117  'date_end_planned' => array('type'=>'datetime', 'label'=>'DateEndPlannedMo', 'enabled'=>1, 'visible'=>1, 'position'=>56, 'notnull'=>-1, 'index'=>1, 'alwayseditable'=>1),
118  'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>1000, 'notnull'=>-1,),
119  'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>1010),
120  'status' => array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>2, 'position'=>1000, 'default'=>0, 'notnull'=>1, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '2'=>'InProgress', '3'=>'StatusMOProduced', '9'=>'Canceled')),
121  'fk_parent_line' => array('type'=>'integer:MoLine:mrp/class/mo.class.php', 'label'=>'ParentMo', 'enabled'=>1, 'visible'=>0, 'position'=>1020, 'default'=>0, 'notnull'=>0, 'index'=>1,'showoncombobox'=>0),
122  );
123  public $rowid;
124  public $entity;
125  public $ref;
126 
130  public $mrptype;
131  public $label;
132  public $qty;
133  public $fk_warehouse;
134  public $fk_soc;
135  public $socid;
136 
140  public $note_public;
141 
145  public $note_private;
146 
150  public $date_creation;
151 
155  public $date_valid;
156 
160  public $tms;
161 
162  public $fk_user_creat;
163  public $fk_user_modif;
164  public $import_key;
165  public $status;
166 
170  public $fk_product;
171 
175  public $product;
176 
180  public $date_start_planned;
181 
185  public $date_end_planned;
186 
187 
191  public $fk_bom;
192 
196  public $bom;
197 
201  public $fk_project;
202 
203  // If this object has a subtable with lines
204 
208  public $table_element_line = 'mrp_production';
209 
213  public $fk_element = 'fk_mo';
214 
218  public $class_element_line = 'MoLine';
219 
223  protected $childtables = array();
224 
228  protected $childtablesoncascade = array('mrp_production');
229 
233  public $lines = array();
234 
238  public $line = array();
239 
243  public $fk_parent_line;
244 
248  public $tpl = array();
249 
255  public function __construct(DoliDB $db)
256  {
257  global $conf, $langs;
258 
259  $this->db = $db;
260 
261  if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) {
262  $this->fields['rowid']['visible'] = 0;
263  }
264  if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
265  $this->fields['entity']['enabled'] = 0;
266  }
267 
268  // Unset fields that are disabled
269  foreach ($this->fields as $key => $val) {
270  if (isset($val['enabled']) && empty($val['enabled'])) {
271  unset($this->fields[$key]);
272  }
273  }
274 
275  // Translate some data of arrayofkeyval
276  foreach ($this->fields as $key => $val) {
277  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
278  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
279  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
280  }
281  }
282  }
283  }
284 
292  public function create(User $user, $notrigger = false)
293  {
294  $error = 0;
295  $idcreated = 0;
296 
297  // If kits feature is enabled and we don't allow kits into BOM and MO, we check that the product is not a kit/virtual product
298  if (getDolGlobalString('PRODUIT_SOUSPRODUITS') && !getDolGlobalString('ALLOW_USE_KITS_INTO_BOM_AND_MO') && $this->fk_product > 0) {
299  include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
300  $tmpproduct = new Product($this->db);
301  $tmpproduct->fetch($this->fk_product);
302  if ($tmpproduct->hasFatherOrChild(1) > 0) {
303  $this->error = 'ErrorAVirtualProductCantBeUsedIntoABomOrMo';
304  $this->errors[] = $this->error;
305  return -1;
306  }
307  }
308 
309  $this->db->begin();
310 
311  if ($this->fk_bom > 0) {
312  // If there is a nown BOM, we force the type of MO to the type of BOM
313  include_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
314  $tmpbom = new BOM($this->db);
315  $tmpbom->fetch($this->fk_bom);
316 
317  $this->mrptype = $tmpbom->bomtype;
318  }
319 
320  if (!$error) {
321  $idcreated = $this->createCommon($user, $notrigger);
322  if ($idcreated <= 0) {
323  $error++;
324  }
325  }
326 
327  if (!$error) {
328  $result = $this->createProduction($user, $notrigger); // Insert lines from BOM
329  if ($result <= 0) {
330  $error++;
331  }
332  }
333 
334  if (!$error) {
335  $this->db->commit();
336  } else {
337  $this->db->rollback();
338  }
339 
340  return $idcreated;
341  }
342 
350  public function createFromClone(User $user, $fromid)
351  {
352  global $langs, $extrafields;
353  $error = 0;
354 
355  dol_syslog(__METHOD__, LOG_DEBUG);
356 
357  $object = new self($this->db);
358 
359  $this->db->begin();
360 
361  // Load source object
362  $result = $object->fetchCommon($fromid);
363  if ($result > 0 && !empty($object->table_element_line)) {
364  $object->fetchLines();
365  }
366 
367  // get lines so they will be clone
368  //foreach($this->lines as $line)
369  // $line->fetch_optionals();
370 
371  // Reset some properties
372  unset($object->id);
373  unset($object->fk_user_creat);
374  unset($object->import_key);
375 
376  // Remove produced and consumed lines
377  foreach ($object->lines as $key => $line) {
378  if (in_array($line->role, array('consumed', 'produced'))) {
379  unset($object->lines[$key]);
380  }
381  }
382 
383  // Clear fields
384  $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default'];
385  $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
386  $object->status = self::STATUS_DRAFT;
387  // ...
388  // Clear extrafields that are unique
389  if (is_array($object->array_options) && count($object->array_options) > 0) {
390  $extrafields->fetch_name_optionals_label($this->table_element);
391  foreach ($object->array_options as $key => $option) {
392  $shortkey = preg_replace('/options_/', '', $key);
393  if (!empty($extrafields->attributes[$this->element]['unique'][$shortkey])) {
394  //var_dump($key);
395  //var_dump($clonedObj->array_options[$key]); exit;
396  unset($object->array_options[$key]);
397  }
398  }
399  }
400 
401  // Create clone
402  $object->context['createfromclone'] = 'createfromclone';
403  $result = $object->createCommon($user);
404  if ($result < 0) {
405  $error++;
406  $this->error = $object->error;
407  $this->errors = $object->errors;
408  }
409 
410  if (!$error) {
411  // copy internal contacts
412  if ($this->copy_linked_contact($object, 'internal') < 0) {
413  $error++;
414  }
415  }
416 
417  if (!$error) {
418  // copy external contacts if same company
419  if (property_exists($this, 'socid') && $this->socid == $object->socid) {
420  if ($this->copy_linked_contact($object, 'external') < 0) {
421  $error++;
422  }
423  }
424  }
425 
426  unset($object->context['createfromclone']);
427 
428  // End
429  if (!$error) {
430  $this->db->commit();
431  return $object;
432  } else {
433  $this->db->rollback();
434  return -1;
435  }
436  }
437 
445  public function fetch($id, $ref = null)
446  {
447  $result = $this->fetchCommon($id, $ref);
448  if ($result > 0 && !empty($this->table_element_line)) {
449  $this->fetchLines();
450  }
451 
452  $this->socid = $this->fk_soc;
453 
454  return $result;
455  }
456 
462  public function fetchLines()
463  {
464  $this->lines = array();
465 
466  $result = $this->fetchLinesCommon();
467  return $result;
468  }
469 
470 
482  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
483  {
484  global $conf;
485 
486  dol_syslog(__METHOD__, LOG_DEBUG);
487 
488  $records = array();
489 
490  $sql = 'SELECT ';
491  $sql .= $this->getFieldList();
492  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
493  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
494  $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
495  } else {
496  $sql .= ' WHERE 1 = 1';
497  }
498  // Manage filter
499  $sqlwhere = array();
500  if (count($filter) > 0) {
501  foreach ($filter as $key => $value) {
502  if ($key == 't.rowid') {
503  $sqlwhere[] = $key." = ".((int) $value);
504  } elseif (strpos($key, 'date') !== false) {
505  $sqlwhere[] = $key." = '".$this->db->idate($value)."'";
506  } elseif ($key == 'customsql') {
507  $sqlwhere[] = $value;
508  } else {
509  $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'";
510  }
511  }
512  }
513  if (count($sqlwhere) > 0) {
514  $sql .= ' AND ('.implode(' '.$this->db->escape($filtermode).' ', $sqlwhere).')';
515  }
516 
517  if (!empty($sortfield)) {
518  $sql .= $this->db->order($sortfield, $sortorder);
519  }
520  if (!empty($limit)) {
521  $sql .= $this->db->plimit($limit, $offset);
522  }
523 
524  $resql = $this->db->query($sql);
525  if ($resql) {
526  $num = $this->db->num_rows($resql);
527  $i = 0;
528  while ($i < min($limit, $num)) {
529  $obj = $this->db->fetch_object($resql);
530 
531  $record = new self($this->db);
532  $record->setVarsFromFetchObj($obj);
533 
534  $records[$record->id] = $record;
535 
536  $i++;
537  }
538  $this->db->free($resql);
539 
540  return $records;
541  } else {
542  $this->errors[] = 'Error '.$this->db->lasterror();
543  dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
544 
545  return -1;
546  }
547  }
548 
556  public function fetchLinesLinked($role, $lineid = 0)
557  {
558  $resarray = array();
559  $mostatic = new MoLine($this->db);
560 
561  $sql = 'SELECT ';
562  $sql .= $mostatic->getFieldList();
563  $sql .= ' FROM '.MAIN_DB_PREFIX.$mostatic->table_element.' as t';
564  $sql .= " WHERE t.role = '".$this->db->escape($role)."'";
565  if ($lineid > 0) {
566  $sql .= ' AND t.fk_mrp_production = '.((int) $lineid);
567  } else {
568  $sql .= 'AND t.fk_mo = '.((int) $this->id);
569  }
570 
571  $resql = $this->db->query($sql);
572  if ($resql) {
573  $num = $this->db->num_rows($resql);
574 
575  $i = 0;
576  while ($i < $num) {
577  $obj = $this->db->fetch_object($resql);
578  if ($obj) {
579  $resarray[] = array(
580  'rowid'=> $obj->rowid,
581  'date'=> $this->db->jdate($obj->date_creation),
582  'qty' => $obj->qty,
583  'role' => $obj->role,
584  'fk_product' => $obj->fk_product,
585  'fk_warehouse' => $obj->fk_warehouse,
586  'batch' => $obj->batch,
587  'fk_stock_movement' => $obj->fk_stock_movement
588  );
589  }
590 
591  $i++;
592  }
593 
594  return $resarray;
595  } else {
596  $this->error = $this->db->lasterror();
597  return array();
598  }
599  }
600 
601 
607  public function countMovements()
608  {
609  $result = 0;
610 
611  $sql = 'SELECT COUNT(rowid) as nb FROM '.MAIN_DB_PREFIX.'stock_mouvement as sm';
612  $sql .= " WHERE sm.origintype = 'mo' and sm.fk_origin = ".((int) $this->id);
613 
614  $resql = $this->db->query($sql);
615  if ($resql) {
616  $num = $this->db->num_rows($resql);
617 
618  $i = 0;
619  while ($i < $num) {
620  $obj = $this->db->fetch_object($resql);
621  if ($obj) {
622  $result = $obj->nb;
623  }
624 
625  $i++;
626  }
627  } else {
628  $this->error = $this->db->lasterror();
629  }
630 
631  return $result;
632  }
633 
634 
642  public function update(User $user, $notrigger = false)
643  {
644  global $langs;
645 
646  $error = 0;
647 
648  $this->db->begin();
649 
650  $result = $this->updateCommon($user, $notrigger);
651  if ($result <= 0) {
652  $error++;
653  }
654 
655  // Update the lines (the qty) to consume or to produce
656  $result = $this->updateProduction($user, $notrigger);
657  if ($result <= 0) {
658  $error++;
659  }
660 
661  if (!$error) {
662  $this->db->commit();
663  return 1;
664  } else {
665  $this->db->rollback();
666  return -1;
667  }
668  }
669 
670 
678  public function createProduction(User $user, $notrigger = true)
679  {
680  $error = 0;
681  $role = "";
682 
683  if ($this->status != self::STATUS_DRAFT) {
684  return -1;
685  }
686 
687  $this->db->begin();
688 
689  // Insert lines in mrp_production table from BOM data
690  if (!$error) {
691  $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'mrp_production WHERE fk_mo = '.((int) $this->id);
692  $this->db->query($sql);
693 
694  $moline = new MoLine($this->db);
695 
696  // Line to produce
697  $moline->fk_mo = $this->id;
698  $moline->qty = $this->qty;
699  $moline->fk_product = $this->fk_product;
700  $moline->position = 1;
701 
702  if ($this->fk_bom > 0) { // If a BOM is defined, we know what to produce.
703  include_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
704  $bom = new BOM($this->db);
705  $bom->fetch($this->fk_bom);
706  if ($bom->bomtype == 1) {
707  $role = 'toproduce';
708  $moline->role = 'toconsume';
709  } else {
710  $role = 'toconsume';
711  $moline->role = 'toproduce';
712  }
713  } else {
714  if ($this->mrptype == 1) {
715  $moline->role = 'toconsume';
716  } else {
717  $moline->role = 'toproduce';
718  }
719  }
720 
721  $resultline = $moline->create($user, false); // Never use triggers here
722  if ($resultline <= 0) {
723  $error++;
724  $this->error = $moline->error;
725  $this->errors = $moline->errors;
726  dol_print_error($this->db, $moline->error, $moline->errors);
727  }
728 
729  if ($this->fk_bom > 0) { // If a BOM is defined, we know what to consume.
730  if ($bom->id > 0) {
731  // Lines to consume
732  if (!$error) {
733  foreach ($bom->lines as $line) {
734  $moline = new MoLine($this->db);
735 
736  $moline->fk_mo = $this->id;
737  $moline->origin_id = $line->id;
738  $moline->origin_type = 'bomline';
739  if ($line->qty_frozen) {
740  $moline->qty = $line->qty; // Qty to consume does not depends on quantity to produce
741  } else {
742  $moline->qty = price2num(($line->qty / ( !empty($bom->qty) ? $bom->qty : 1 ) ) * $this->qty / ( !empty($line->efficiency) ? $line->efficiency : 1 ), 'MS'); // Calculate with Qty to produce and more presition
743  }
744  if ($moline->qty <= 0) {
745  $error++;
746  $this->error = "BadValueForquantityToConsume";
747  break;
748  } else {
749  $moline->fk_product = $line->fk_product;
750  $moline->role = $role;
751  $moline->position = $line->position;
752  $moline->qty_frozen = $line->qty_frozen;
753  $moline->disable_stock_change = $line->disable_stock_change;
754  if (!empty($line->fk_default_workstation)) $moline->fk_default_workstation = $line->fk_default_workstation;
755 
756  $resultline = $moline->create($user, false); // Never use triggers here
757  if ($resultline <= 0) {
758  $error++;
759  $this->error = $moline->error;
760  $this->errors = $moline->errors;
761  dol_print_error($this->db, $moline->error, $moline->errors);
762  break;
763  }
764  }
765  }
766  }
767  }
768  }
769  }
770 
771  if (!$error) {
772  $this->db->commit();
773  return 1;
774  } else {
775  $this->db->rollback();
776  return -1;
777  }
778  }
779 
787  public function updateProduction(User $user, $notrigger = true)
788  {
789  $error = 0;
790 
791  if ($this->status != self::STATUS_DRAFT) return 1;
792 
793  $this->db->begin();
794 
795  $oldQty = $this->oldQty;
796  $newQty = $this->qty;
797  if ($newQty != $oldQty && !empty($this->oldQty)) {
798  $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "mrp_production WHERE fk_mo = " . (int) $this->id;
799  $resql = $this->db->query($sql);
800  if ($resql) {
801  while ($obj = $this->db->fetch_object($resql)) {
802  $moLine = new MoLine($this->db);
803  $res = $moLine->fetch($obj->rowid);
804  if (!$res) $error++;
805 
806  if ($moLine->role == 'toconsume' || $moLine->role == 'toproduce') {
807  if (empty($moLine->qty_frozen)) {
808  $qty = $newQty * $moLine->qty / $oldQty;
809  $moLine->qty = price2num($qty * (!empty($line->efficiency) ? $line->efficiency : 1 ), 'MS'); // Calculate with Qty to produce and efficiency
810  $res = $moLine->update($user);
811  if (!$res) $error++;
812  }
813  }
814  }
815  }
816  }
817 
818  if (!$error) {
819  $this->db->commit();
820  return 1;
821  } else {
822  $this->db->rollback();
823  return -1;
824  }
825  }
826 
827 
835  public function delete(User $user, $notrigger = false)
836  {
837  return $this->deleteCommon($user, $notrigger);
838  //return $this->deleteCommon($user, $notrigger, 1);
839  }
840 
849  public function deleteLine(User $user, $idline, $notrigger = false)
850  {
851  global $langs;
852  $langs->loadLangs(array('stocks', 'mrp'));
853 
854  if ($this->status < 0) {
855  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
856  return -2;
857  }
858 
859  $productstatic = new Product($this->db);
860  $fk_movement = GETPOST('fk_movement', 'int');
861  $arrayoflines = $this->fetchLinesLinked('consumed', $idline);
862 
863  if (!empty($arrayoflines)) {
864  $this->db->begin();
865 
866  $stockmove = new MouvementStock($this->db);
867  $stockmove->setOrigin($this->element, $this->id);
868 
869  if (!empty($fk_movement)) {
870  $moline = new MoLine($this->db);
871  $TArrayMoLine = $moline->fetchAll('', '', 1, 0, array('customsql' => 'fk_stock_movement ='.$fk_movement));
872  $moline = array_shift($TArrayMoLine);
873 
874  $movement = new MouvementStock($this->db);
875  $movement->fetch($fk_movement);
876  $productstatic->fetch($movement->product_id);
877  $qtytoprocess = $movement->qty;
878 
879  // Reverse stock movement
880  $labelmovementCancel = $langs->trans("CancelProductionForRef", $productstatic->ref);
881  $codemovementCancel = $langs->trans("StockIncrease");
882 
883  if (($qtytoprocess >= 0)) {
884  $idstockmove = $stockmove->reception($user, $movement->product_id, $movement->warehouse_id, $qtytoprocess, 0, $labelmovementCancel, '', '', $movement->batch, dol_now(), 0, $codemovementCancel);
885  } else {
886  $idstockmove = $stockmove->livraison($user, $movement->product_id, $movement->warehouse_id, $qtytoprocess, 0, $labelmovementCancel, dol_now(), '', '', $movement->batch, 0, $codemovementCancel);
887  }
888  if ($idstockmove < 0) {
889  $this->error++;
890  $this->db->rollback();
891  setEventMessages($stockmove->error, $stockmove->errors, 'errors');
892  } else {
893  $this->db->commit();
894  }
895  return $moline->delete($user, $notrigger);
896  } else {
897  foreach ($arrayoflines as $key => $arrayofline) {
898  $lineDetails = $arrayoflines[$key];
899  $productstatic->fetch($lineDetails['fk_product']);
900  $qtytoprocess = $lineDetails['qty'];
901 
902  // Reverse stock movement
903  $labelmovementCancel = $langs->trans("CancelProductionForRef", $productstatic->ref);
904  $codemovementCancel = $langs->trans("StockIncrease");
905 
906  if ($qtytoprocess >= 0) {
907  $idstockmove = $stockmove->reception($user, $lineDetails['fk_product'], $lineDetails['fk_warehouse'], $qtytoprocess, 0, $labelmovementCancel, '', '', $lineDetails['batch'], dol_now(), 0, $codemovementCancel);
908  } else {
909  $idstockmove = $stockmove->livraison($user, $lineDetails['fk_product'], $lineDetails['fk_warehouse'], $qtytoprocess, 0, $labelmovementCancel, dol_now(), '', '', $lineDetails['batch'], 0, $codemovementCancel);
910  }
911  if ($idstockmove < 0) {
912  $this->error++;
913  $this->db->rollback();
914  setEventMessages($stockmove->error, $stockmove->errors, 'errors');
915  } else {
916  $this->db->commit();
917  }
918  }
919  return $this->deleteLineCommon($user, $idline, $notrigger);
920  }
921  } else {
922  return $this->deleteLineCommon($user, $idline, $notrigger);
923  }
924  }
925 
926 
934  public function getNextNumRef($prod)
935  {
936  global $langs, $conf;
937  $langs->load("mrp");
938 
939  if (!empty($conf->global->MRP_MO_ADDON)) {
940  $mybool = false;
941 
942  $file = $conf->global->MRP_MO_ADDON.".php";
943  $classname = $conf->global->MRP_MO_ADDON;
944 
945  // Include file with class
946  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
947  foreach ($dirmodels as $reldir) {
948  $dir = dol_buildpath($reldir."core/modules/mrp/");
949 
950  // Load file with numbering class (if found)
951  $mybool |= @include_once $dir.$file;
952  }
953 
954  if ($mybool === false) {
955  dol_print_error('', "Failed to include file ".$file);
956  return '';
957  }
958 
959  $obj = new $classname();
960  $numref = $obj->getNextValue($prod, $this);
961 
962  if ($numref != "") {
963  return $numref;
964  } else {
965  $this->error = $obj->error;
966  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
967  return "";
968  }
969  } else {
970  print $langs->trans("Error")." ".$langs->trans("Error_MRP_MO_ADDON_NotDefined");
971  return "";
972  }
973  }
974 
982  public function validate($user, $notrigger = 0)
983  {
984  global $conf, $langs;
985 
986  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
987 
988  $error = 0;
989 
990  // Protection
991  if ($this->status == self::STATUS_VALIDATED) {
992  dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
993  return 0;
994  }
995 
996  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mrp->create))
997  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mrp->mrp_advance->validate))))
998  {
999  $this->error='NotEnoughPermissions';
1000  dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
1001  return -1;
1002  }*/
1003 
1004  $now = dol_now();
1005 
1006  $this->db->begin();
1007 
1008  // Define new ref
1009  if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
1010  $this->fetch_product();
1011  $num = $this->getNextNumRef($this->product);
1012  } else {
1013  $num = $this->ref;
1014  }
1015  $this->newref = $num;
1016 
1017  // Validate
1018  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1019  $sql .= " SET ref = '".$this->db->escape($num)."',";
1020  $sql .= " status = ".self::STATUS_VALIDATED.",";
1021  $sql .= " date_valid='".$this->db->idate($now)."',";
1022  $sql .= " fk_user_valid = ".$user->id;
1023  $sql .= " WHERE rowid = ".((int) $this->id);
1024 
1025  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
1026  $resql = $this->db->query($sql);
1027  if (!$resql) {
1028  dol_print_error($this->db);
1029  $this->error = $this->db->lasterror();
1030  $error++;
1031  }
1032 
1033  if (!$error && !$notrigger) {
1034  // Call trigger
1035  $result = $this->call_trigger('MRP_MO_VALIDATE', $user);
1036  if ($result < 0) {
1037  $error++;
1038  }
1039  // End call triggers
1040  }
1041 
1042  if (!$error) {
1043  $this->oldref = $this->ref;
1044 
1045  // Rename directory if dir was a temporary ref
1046  if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
1047  // Now we rename also files into index
1048  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'mrp/".$this->db->escape($this->newref)."'";
1049  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'mrp/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
1050  $resql = $this->db->query($sql);
1051  if (!$resql) {
1052  $error++; $this->error = $this->db->lasterror();
1053  }
1054  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'mrp/".$this->db->escape($this->newref)."'";
1055  $sql .= " WHERE filepath = 'mrp/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
1056  $resql = $this->db->query($sql);
1057  if (!$resql) {
1058  $error++; $this->error = $this->db->lasterror();
1059  }
1060 
1061  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
1062  $oldref = dol_sanitizeFileName($this->ref);
1063  $newref = dol_sanitizeFileName($num);
1064  $dirsource = $conf->mrp->dir_output.'/'.$oldref;
1065  $dirdest = $conf->mrp->dir_output.'/'.$newref;
1066  if (!$error && file_exists($dirsource)) {
1067  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
1068 
1069  if (@rename($dirsource, $dirdest)) {
1070  dol_syslog("Rename ok");
1071  // Rename docs starting with $oldref with $newref
1072  $listoffiles = dol_dir_list($conf->mrp->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
1073  foreach ($listoffiles as $fileentry) {
1074  $dirsource = $fileentry['name'];
1075  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
1076  $dirsource = $fileentry['path'].'/'.$dirsource;
1077  $dirdest = $fileentry['path'].'/'.$dirdest;
1078  @rename($dirsource, $dirdest);
1079  }
1080  }
1081  }
1082  }
1083  }
1084 
1085  // Set new ref and current status
1086  if (!$error) {
1087  $this->ref = $num;
1088  $this->status = self::STATUS_VALIDATED;
1089  }
1090 
1091  if (!$error) {
1092  $this->db->commit();
1093  return 1;
1094  } else {
1095  $this->db->rollback();
1096  return -1;
1097  }
1098  }
1099 
1107  public function setDraft($user, $notrigger = 0)
1108  {
1109  // Protection
1110  if ($this->status <= self::STATUS_DRAFT) {
1111  return 0;
1112  }
1113 
1114  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->write))
1115  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->mymodule_advance->validate))))
1116  {
1117  $this->error='Permission denied';
1118  return -1;
1119  }*/
1120 
1121  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'MRP_MO_UNVALIDATE');
1122  }
1123 
1131  public function cancel($user, $notrigger = 0)
1132  {
1133  // Protection
1134  if ($this->status != self::STATUS_VALIDATED && $this->status != self::STATUS_INPROGRESS) {
1135  return 0;
1136  }
1137 
1138  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->write))
1139  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->mymodule_advance->validate))))
1140  {
1141  $this->error='Permission denied';
1142  return -1;
1143  }*/
1144 
1145  return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'MRP_MO_CANCEL');
1146  }
1147 
1155  public function reopen($user, $notrigger = 0)
1156  {
1157  // Protection
1158  if ($this->status != self::STATUS_PRODUCED && $this->status != self::STATUS_CANCELED) {
1159  return 0;
1160  }
1161 
1162  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->write))
1163  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->mymodule_advance->validate))))
1164  {
1165  $this->error='Permission denied';
1166  return -1;
1167  }*/
1168 
1169  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'MRP_MO_REOPEN');
1170  }
1171 
1179  public function getTooltipContentArray($params)
1180  {
1181  global $conf, $langs;
1182 
1183  $langs->loadLangs(['mrp', 'products']);
1184  $nofetch = isset($params['nofetch']) ? true : false;
1185 
1186  $datas = [];
1187 
1188  $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("ManufacturingOrder").'</u>';
1189  if (isset($this->status)) {
1190  $datas['picto'] .= ' '.$this->getLibStatut(5);
1191  }
1192  $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
1193  if (isset($this->label)) {
1194  $datas['label'] = '<br><b>'.$langs->trans('Label').':</b> '.$this->label;
1195  }
1196  if (isset($this->mrptype)) {
1197  $datas['type'] = '<br><b>'.$langs->trans('Type').':</b> '.$this->fields['mrptype']['arrayofkeyval'][$this->mrptype];
1198  }
1199  if (isset($this->qty)) {
1200  $datas['qty'] = '<br><b>'.$langs->trans('QtyToProduce').':</b> '.$this->qty;
1201  }
1202  if (!$nofetch && isset($this->fk_product)) {
1203  require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
1204  $product = new Product($this->db);
1205  $product->fetch($this->fk_product);
1206  $datas['product'] = '<br><b>'.$langs->trans('Product').':</b> '.$product->getNomUrl(1, '', 0, -1, 1);
1207  }
1208  if (!$nofetch && isset($this->fk_warehouse)) {
1209  require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php';
1210  $warehouse = new Entrepot($this->db);
1211  $warehouse->fetch($this->fk_warehouse);
1212  $datas['warehouse'] = '<br><b>'.$langs->trans('WarehouseForProduction').':</b> '.$warehouse->getNomUrl(1, '', 0, 1);
1213  }
1214 
1215  return $datas;
1216  }
1217 
1228  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
1229  {
1230  global $conf, $langs, $hookmanager;
1231 
1232  if (!empty($conf->dol_no_mouse_hover)) {
1233  $notooltip = 1; // Force disable tooltips
1234  }
1235 
1236  $result = '';
1237  $params = [
1238  'id' => $this->id,
1239  'objecttype' => $this->element,
1240  'option' => $option,
1241  'nofetch' => 1,
1242  ];
1243  $classfortooltip = 'classfortooltip';
1244  $dataparams = '';
1245  if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1246  $classfortooltip = 'classforajaxtooltip';
1247  $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1248  $label = '';
1249  } else {
1250  $label = implode($this->getTooltipContentArray($params));
1251  }
1252 
1253  $url = DOL_URL_ROOT.'/mrp/mo_card.php?id='.$this->id;
1254  if ($option == 'production') {
1255  $url = DOL_URL_ROOT.'/mrp/mo_production.php?id='.$this->id;
1256  }
1257 
1258  if ($option != 'nolink') {
1259  // Add param to save lastsearch_values or not
1260  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1261  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1262  $add_save_lastsearch_values = 1;
1263  }
1264  if ($add_save_lastsearch_values) {
1265  $url .= '&save_lastsearch_values=1';
1266  }
1267  }
1268 
1269  $linkclose = '';
1270  if (empty($notooltip)) {
1271  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
1272  $label = $langs->trans("ShowMo");
1273  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1274  }
1275  $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1276  $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1277  } else {
1278  $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1279  }
1280 
1281  $linkstart = '<a href="'.$url.'"';
1282  $linkstart .= $linkclose.'>';
1283  $linkend = '</a>';
1284 
1285  $result .= $linkstart;
1286  if ($withpicto) {
1287  $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (($withpicto != 2) ? 'class="paddingright"' : ''), 0, 0, $notooltip ? 0 : 1);
1288  }
1289  if ($withpicto != 2) {
1290  $result .= $this->ref;
1291  }
1292  $result .= $linkend;
1293  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
1294 
1295  global $action, $hookmanager;
1296  $hookmanager->initHooks(array('modao'));
1297  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
1298  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1299  if ($reshook > 0) {
1300  $result = $hookmanager->resPrint;
1301  } else {
1302  $result .= $hookmanager->resPrint;
1303  }
1304 
1305  return $result;
1306  }
1307 
1314  public function getLibStatut($mode = 0)
1315  {
1316  return $this->LibStatut($this->status, $mode);
1317  }
1318 
1319  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1327  public function LibStatut($status, $mode = 0)
1328  {
1329  // phpcs:enable
1330  if (empty($this->labelStatus)) {
1331  global $langs;
1332  //$langs->load("mrp");
1333  $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
1334  $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ValidatedToProduce');
1335  $this->labelStatus[self::STATUS_INPROGRESS] = $langs->transnoentitiesnoconv('InProgress');
1336  $this->labelStatus[self::STATUS_PRODUCED] = $langs->transnoentitiesnoconv('StatusMOProduced');
1337  $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
1338 
1339  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
1340  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
1341  $this->labelStatusShort[self::STATUS_INPROGRESS] = $langs->transnoentitiesnoconv('InProgress');
1342  $this->labelStatusShort[self::STATUS_PRODUCED] = $langs->transnoentitiesnoconv('StatusMOProduced');
1343  $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
1344  }
1345 
1346  $statusType = 'status'.$status;
1347  if ($status == self::STATUS_VALIDATED) {
1348  $statusType = 'status1';
1349  }
1350  if ($status == self::STATUS_INPROGRESS) {
1351  $statusType = 'status4';
1352  }
1353  if ($status == self::STATUS_PRODUCED) {
1354  $statusType = 'status6';
1355  }
1356  if ($status == self::STATUS_CANCELED) {
1357  $statusType = 'status9';
1358  }
1359 
1360  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
1361  }
1362 
1369  public function info($id)
1370  {
1371  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
1372  $sql .= ' fk_user_creat, fk_user_modif';
1373  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
1374  $sql .= ' WHERE t.rowid = '.((int) $id);
1375  $result = $this->db->query($sql);
1376  if ($result) {
1377  if ($this->db->num_rows($result)) {
1378  $obj = $this->db->fetch_object($result);
1379  $this->id = $obj->rowid;
1380 
1381  $this->user_creation_id = $obj->fk_user_creat;
1382  $this->user_modification_id = $obj->fk_user_modif;
1383  $this->date_creation = $this->db->jdate($obj->datec);
1384  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
1385  }
1386 
1387  $this->db->free($result);
1388  } else {
1389  dol_print_error($this->db);
1390  }
1391  }
1392 
1399  public function initAsSpecimen()
1400  {
1401  $this->initAsSpecimenCommon();
1402 
1403  $this->lines = array();
1404  }
1405 
1412  public function getLinesArray($rolefilter = '')
1413  {
1414  $this->lines = array();
1415 
1416  $objectline = new MoLine($this->db);
1417 
1418  $TFilters = array('customsql'=>'fk_mo = '.((int) $this->id));
1419  if (!empty($rolefilter)) $TFilters['role'] = $rolefilter;
1420  $result = $objectline->fetchAll('ASC', 'position', 0, 0, $TFilters);
1421 
1422  if (is_numeric($result)) {
1423  $this->error = $objectline->error;
1424  $this->errors = $objectline->errors;
1425  return $result;
1426  } else {
1427  $this->lines = $result;
1428  return $this->lines;
1429  }
1430  }
1431 
1443  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1444  {
1445  global $conf, $langs;
1446 
1447  $langs->load("mrp");
1448 
1449  if (!dol_strlen($modele)) {
1450  //$modele = 'standard';
1451  $modele = ''; // Remove this once a pdf_standard.php exists.
1452 
1453  if ($this->model_pdf) {
1454  $modele = $this->model_pdf;
1455  } elseif (!empty($conf->global->MO_ADDON_PDF)) {
1456  $modele = $conf->global->MO_ADDON_PDF;
1457  }
1458  }
1459 
1460  $modelpath = "core/modules/mrp/doc/";
1461 
1462  if (empty($modele)) {
1463  return 1; // Remove this once a pdf_standard.php exists.
1464  }
1465 
1466  return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1467  }
1468 
1476  public function doScheduledJob()
1477  {
1478  global $conf, $langs;
1479 
1480  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1481 
1482  $error = 0;
1483  $this->output = '';
1484  $this->error = '';
1485 
1486  dol_syslog(__METHOD__, LOG_DEBUG);
1487 
1488  $now = dol_now();
1489 
1490  $this->db->begin();
1491 
1492  // ...
1493 
1494  $this->db->commit();
1495 
1496  return $error;
1497  }
1498 
1509  public function printOriginLinesList($restrictlist = '', $selectedLines = array())
1510  {
1511  global $langs, $hookmanager, $conf, $form;
1512 
1513  $langs->load('stocks');
1514  $text_stock_options = $langs->trans("RealStockDesc").'<br>';
1515  $text_stock_options .= $langs->trans("RealStockWillAutomaticallyWhen").'<br>';
1516  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || !empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE) ? '- '.$langs->trans("DeStockOnShipment").'<br>' : '');
1517  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) ? '- '.$langs->trans("DeStockOnValidateOrder").'<br>' : '');
1518  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_BILL) ? '- '.$langs->trans("DeStockOnBill").'<br>' : '');
1519  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL) ? '- '.$langs->trans("ReStockOnBill").'<br>' : '');
1520  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER) ? '- '.$langs->trans("ReStockOnValidateOrder").'<br>' : '');
1521  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) ? '- '.$langs->trans("ReStockOnDispatchOrder").'<br>' : '');
1522  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE) ? '- '.$langs->trans("StockOnReception").'<br>' : '');
1523 
1524  print '<tr class="liste_titre">';
1525  // Product or sub-bom
1526  print '<td class="linecoldescription">'.$langs->trans('Ref');
1527  if (!empty($conf->global->BOM_SUB_BOM)) {
1528  print ' &nbsp; <a id="show_all" href="#">'.img_picto('', 'folder-open', 'class="paddingright"').$langs->trans("ExpandAll").'</a>&nbsp;&nbsp;';
1529  print '<a id="hide_all" href="#">'.img_picto('', 'folder', 'class="paddingright"').$langs->trans("UndoExpandAll").'</a>&nbsp;';
1530  }
1531  print '</td>';
1532  // Qty
1533  print '<td class="right">'.$langs->trans('Qty');
1534  if ($this->bom->bomtype == 0) {
1535  print ' <span class="opacitymedium">('.$langs->trans("ForAQuantityOf", $this->bom->qty).')</span>';
1536  } else {
1537  print ' <span class="opacitymedium">('.$langs->trans("ForAQuantityToConsumeOf", $this->bom->qty).')</span>';
1538  }
1539  print '</td>';
1540  print '<td class="center">'.$form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1).'</td>';
1541  print '<td class="center">'.$form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc")).'</td>';
1542  print '<td class="center">'.$langs->trans('QtyFrozen').'</td>';
1543  print '<td class="center">'.$langs->trans('DisableStockChange').'</td>';
1544  print '<td class="center">'.$langs->trans('MoChildGenerate').'</td>';
1545  //print '<td class="center">'.$form->showCheckAddButtons('checkforselect', 1).'</td>';
1546  //print '<td class="center"></td>';
1547  print '</tr>';
1548  $i = 0;
1549 
1550  if (!empty($this->lines)) {
1551  foreach ($this->lines as $line) {
1552  $reshook = 0;
1553  if (is_object($hookmanager)) {
1554  $parameters = array('line'=>$line, 'i'=>$i, 'restrictlist'=>$restrictlist, 'selectedLines'=> $selectedLines);
1555  if (!empty($line->fk_parent_line)) { $parameters['fk_parent_line'] = $line->fk_parent_line; }
1556  $reshook = $hookmanager->executeHooks('printOriginObjectLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1557  }
1558  if (empty($reshook)) {
1559  $this->printOriginLine($line, '', $restrictlist, '/core/tpl', $selectedLines);
1560  }
1561 
1562  $i++;
1563  }
1564  }
1565  }
1566 
1567 
1581  public function printOriginLine($line, $var, $restrictlist = '', $defaulttpldir = '/core/tpl', $selectedLines = array())
1582  {
1583  global $langs, $conf;
1584 
1585  $this->tpl['id'] = $line->id;
1586 
1587  $this->tpl['label'] = '';
1588  if (!empty($line->fk_product)) {
1589  $productstatic = new Product($this->db);
1590  $productstatic->fetch($line->fk_product);
1591  $productstatic->load_virtual_stock();
1592  $this->tpl['label'] .= $productstatic->getNomUrl(1);
1593  //$this->tpl['label'].= ' - '.$productstatic->label;
1594  } else {
1595  // If origin MRP line is not a product, but another MRP
1596  // TODO
1597  }
1598 
1599  $this->tpl['qty_bom'] = 1;
1600  if (is_object($this->bom) && $this->bom->qty > 1) {
1601  $this->tpl['qty_bom'] = $this->bom->qty;
1602  }
1603 
1604  $this->tpl['stock'] = $productstatic->stock_reel;
1605  $this->tpl['seuil_stock_alerte'] = $productstatic->seuil_stock_alerte;
1606  $this->tpl['virtual_stock'] = $productstatic->stock_theorique;
1607  $this->tpl['qty'] = $line->qty;
1608  $this->tpl['qty_frozen'] = $line->qty_frozen;
1609  $this->tpl['disable_stock_change'] = $line->disable_stock_change;
1610  $this->tpl['efficiency'] = $line->efficiency;
1611 
1612  $tpl = DOL_DOCUMENT_ROOT.'/mrp/tpl/originproductline.tpl.php';
1613  $res = include $tpl;
1614  }
1615 
1624  public static function replaceThirdparty($db, $origin_id, $dest_id)
1625  {
1626  $tables = array('mrp_mo');
1627 
1628  return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
1629  }
1630 
1631 
1637  public function getMoChilds()
1638  {
1639 
1640  $TMoChilds = array();
1641  $error = 0;
1642 
1643  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."mrp_mo as mo_child";
1644  $sql.= " WHERE fk_parent_line IN ";
1645  $sql.= " (SELECT rowid FROM ".MAIN_DB_PREFIX."mrp_production as line_parent";
1646  $sql.= " WHERE fk_mo=".((int) $this->id).")";
1647 
1648  $resql = $this->db->query($sql);
1649 
1650  if ($resql) {
1651  if ($this->db->num_rows($resql) > 0) {
1652  while ($obj = $this->db->fetch_object($resql)) {
1653  $MoChild = new Mo($this->db);
1654  $res = $MoChild->fetch($obj->rowid);
1655  if ($res > 0) $TMoChilds[$MoChild->id] = $MoChild;
1656  else $error++;
1657  }
1658  }
1659  } else {
1660  $error++;
1661  }
1662 
1663  if ($error) {
1664  return -1;
1665  } else {
1666  return $TMoChilds;
1667  }
1668  }
1669 
1675  public function getMoParent()
1676  {
1677  $MoParent = new Mo($this->db);
1678  $error = 0;
1679 
1680  $sql = "SELECT lineparent.fk_mo as id_moparent FROM ".MAIN_DB_PREFIX."mrp_mo as mo";
1681  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."mrp_production lineparent ON mo.fk_parent_line = lineparent.rowid";
1682  $sql.= " WHERE mo.rowid = ".((int) $this->id);
1683 
1684  $resql = $this->db->query($sql);
1685 
1686  if ($resql) {
1687  if ($this->db->num_rows($resql) > 0) {
1688  $obj = $this->db->fetch_object($resql);
1689  $res = $MoParent->fetch($obj->id_moparent);
1690  if ($res < 0) $error++;
1691  } else {
1692  return 0;
1693  }
1694  } else {
1695  $error++;
1696  }
1697 
1698  if ($error) {
1699  return -1;
1700  } else {
1701  return $MoParent;
1702  }
1703  }
1704 
1712  public function getKanbanView($option = '', $arraydata = null)
1713  {
1714  global $langs;
1715 
1716  $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1717 
1718  $return = '<div class="box-flex-item box-flex-grow-zero">';
1719  $return .= '<div class="info-box info-box-sm">';
1720  $return .= '<span class="info-box-icon bg-infobox-action">';
1721  $return .= img_picto('', $this->picto);
1722  //$return .= '<i class="fa fa-dol-action"></i>'; // Can be image
1723  $return .= '</span>';
1724  $return .= '<div class="info-box-content">';
1725  $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
1726  $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1727  if (!empty($arraydata['bom'])) {
1728  $return .= '<br><span class="info-box-label">'.$arraydata['bom']->getNomUrl(1).'</span>';
1729  }
1730  if (!empty($arraydata['product'])) {
1731  $return .= '<br><span class="info-box-label">'.$arraydata['product']->getNomUrl(1).'</span>';
1732  }
1733  if (property_exists($this, 'qty')) {
1734  $return .= '<br><span class="info-box-label">'.$langs->trans('Quantity').' : '.$this->qty.'</span>';
1735  }
1736  if (method_exists($this, 'getLibStatut')) {
1737  $return .= '<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).'</div>';
1738  }
1739  $return .= '</div>';
1740  $return .= '</div>';
1741  $return .= '</div>';
1742  return $return;
1743  }
1744 }
1745 
1750 {
1754  public $element = 'mrp_production';
1755 
1759  public $table_element = 'mrp_production';
1760 
1764  public $ismultientitymanaged = 0;
1765 
1769  public $isextrafieldmanaged = 0;
1770 
1771  public $fields = array(
1772  'rowid' =>array('type'=>'integer', 'label'=>'ID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
1773  'fk_mo' =>array('type'=>'integer', 'label'=>'Mo', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>15),
1774  'origin_id' =>array('type'=>'integer', 'label'=>'Origin', 'enabled'=>1, 'visible'=>-1, 'notnull'=>0, 'position'=>17),
1775  'origin_type' =>array('type'=>'varchar(10)', 'label'=>'Origin type', 'enabled'=>1, 'visible'=>-1, 'notnull'=>0, 'position'=>18),
1776  'position' =>array('type'=>'integer', 'label'=>'Position', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>20),
1777  'fk_product' =>array('type'=>'integer', 'label'=>'Product', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>25),
1778  'fk_warehouse' =>array('type'=>'integer', 'label'=>'Warehouse', 'enabled'=>1, 'visible'=>-1, 'position'=>30),
1779  'qty' =>array('type'=>'real', 'label'=>'Qty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35),
1780  'qty_frozen' => array('type'=>'smallint', 'label'=>'QuantityFrozen', 'enabled'=>1, 'visible'=>1, 'default'=>0, 'position'=>105, 'css'=>'maxwidth50imp', 'help'=>'QuantityConsumedInvariable'),
1781  'disable_stock_change' => array('type'=>'smallint', 'label'=>'DisableStockChange', 'enabled'=>1, 'visible'=>1, 'default'=>0, 'position'=>108, 'css'=>'maxwidth50imp', 'help'=>'DisableStockChangeHelp'),
1782  'batch' =>array('type'=>'varchar(30)', 'label'=>'Batch', 'enabled'=>1, 'visible'=>-1, 'position'=>140),
1783  'role' =>array('type'=>'varchar(10)', 'label'=>'Role', 'enabled'=>1, 'visible'=>-1, 'position'=>145),
1784  'fk_mrp_production' =>array('type'=>'integer', 'label'=>'Fk mrp production', 'enabled'=>1, 'visible'=>-1, 'position'=>150),
1785  'fk_stock_movement' =>array('type'=>'integer', 'label'=>'StockMovement', 'enabled'=>1, 'visible'=>-1, 'position'=>155),
1786  'date_creation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>160),
1787  'tms' =>array('type'=>'timestamp', 'label'=>'Tms', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>165),
1788  'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserCreation', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>170),
1789  'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModification', 'enabled'=>1, 'visible'=>-1, 'position'=>175),
1790  'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-1, 'position'=>180),
1791  'fk_default_workstation' =>array('type'=>'integer', 'label'=>'DefaultWorkstation', 'enabled'=>1, 'visible'=>1, 'notnull'=>0, 'position'=>185)
1792  );
1793 
1794  public $rowid;
1795  public $fk_mo;
1796  public $origin_id;
1797  public $origin_type;
1798  public $position;
1799  public $fk_product;
1800  public $fk_warehouse;
1801  public $qty;
1802  public $qty_frozen;
1803  public $disable_stock_change;
1804  public $efficiency;
1805  public $batch;
1806  public $role;
1807  public $fk_mrp_production;
1808  public $fk_stock_movement;
1809  public $date_creation;
1810  public $tms;
1811  public $fk_user_creat;
1812  public $fk_user_modif;
1813  public $import_key;
1814  public $fk_parent_line;
1815 
1819  public $fk_default_workstation;
1820 
1826  public function __construct(DoliDB $db)
1827  {
1828  global $conf, $langs;
1829 
1830  $this->db = $db;
1831 
1832  if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) {
1833  $this->fields['rowid']['visible'] = 0;
1834  }
1835  if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
1836  $this->fields['entity']['enabled'] = 0;
1837  }
1838 
1839  // Unset fields that are disabled
1840  foreach ($this->fields as $key => $val) {
1841  if (isset($val['enabled']) && empty($val['enabled'])) {
1842  unset($this->fields[$key]);
1843  }
1844  }
1845 
1846  // Translate some data of arrayofkeyval
1847  if (is_object($langs)) {
1848  foreach ($this->fields as $key => $val) {
1849  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
1850  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
1851  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
1852  }
1853  }
1854  }
1855  }
1856  }
1857 
1865  public function create(User $user, $notrigger = false)
1866  {
1867  if (empty($this->qty)) {
1868  $this->error = 'BadValueForQty';
1869  return -1;
1870  }
1871 
1872  return $this->createCommon($user, $notrigger);
1873  }
1874 
1882  public function fetch($id, $ref = null)
1883  {
1884  $result = $this->fetchCommon($id, $ref);
1885  return $result;
1886  }
1887 
1899  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
1900  {
1901  global $conf;
1902 
1903  dol_syslog(__METHOD__, LOG_DEBUG);
1904 
1905  $records = array();
1906 
1907  $sql = 'SELECT ';
1908  $sql .= $this->getFieldList();
1909  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
1910  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
1911  $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
1912  } else {
1913  $sql .= ' WHERE 1 = 1';
1914  }
1915  // Manage filter
1916  $sqlwhere = array();
1917  if (count($filter) > 0) {
1918  foreach ($filter as $key => $value) {
1919  if ($key == 't.rowid') {
1920  $sqlwhere[] = $key." = ".((int) $value);
1921  } elseif (strpos($key, 'date') !== false) {
1922  $sqlwhere[] = $key." = '".$this->db->idate($value)."'";
1923  } elseif ($key == 'customsql') {
1924  $sqlwhere[] = $value;
1925  } else {
1926  $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'";
1927  }
1928  }
1929  }
1930  if (count($sqlwhere) > 0) {
1931  $sql .= ' AND ('.implode(' '.$this->db->escape($filtermode).' ', $sqlwhere).')';
1932  }
1933 
1934  if (!empty($sortfield)) {
1935  $sql .= $this->db->order($sortfield, $sortorder);
1936  }
1937  if (!empty($limit)) {
1938  $sql .= $this->db->plimit($limit, $offset);
1939  }
1940 
1941  $resql = $this->db->query($sql);
1942  if ($resql) {
1943  $num = $this->db->num_rows($resql);
1944  $i = 0;
1945  while ($i < ($limit ? min($limit, $num) : $num)) {
1946  $obj = $this->db->fetch_object($resql);
1947 
1948  $record = new self($this->db);
1949  $record->setVarsFromFetchObj($obj);
1950 
1951  $records[$record->id] = $record;
1952 
1953  $i++;
1954  }
1955  $this->db->free($resql);
1956 
1957  return $records;
1958  } else {
1959  $this->errors[] = 'Error '.$this->db->lasterror();
1960  dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
1961 
1962  return -1;
1963  }
1964  }
1965 
1973  public function update(User $user, $notrigger = false)
1974  {
1975  return $this->updateCommon($user, $notrigger);
1976  }
1977 
1985  public function delete(User $user, $notrigger = false)
1986  {
1987  return $this->deleteCommon($user, $notrigger);
1988  //return $this->deleteCommon($user, $notrigger, 1);
1989  }
1990 }
$object ref
Definition: info.php:78
Class for BOM.
Definition: bom.class.php:39
Parent class of all other business classes (invoices, contracts, proposals, orders,...
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
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.
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.
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
fetch_product()
Load the product with id $this->fk_product into this->product.
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 warehouses.
Class for Mo.
Definition: mo.class.php:34
__construct(DoliDB $db)
Constructor.
Definition: mo.class.php:255
update(User $user, $notrigger=false)
Update object into database.
Definition: mo.class.php:642
fetchLinesLinked($role, $lineid=0)
Get list of lines linked to current line for a defined role.
Definition: mo.class.php:556
getMoChilds()
Function used to return childs of Mo.
Definition: mo.class.php:1637
static replaceThirdparty($db, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
Definition: mo.class.php:1624
printOriginLinesList($restrictlist='', $selectedLines=array())
Return HTML table table of source object lines TODO Move this and previous function into output html ...
Definition: mo.class.php:1509
fetchLines()
Load object lines in memory from the database.
Definition: mo.class.php:462
getNextNumRef($prod)
Returns the reference to the following non used MO depending on the active numbering module defined i...
Definition: mo.class.php:934
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
Definition: mo.class.php:849
cancel($user, $notrigger=0)
Set cancel status.
Definition: mo.class.php:1131
fetch($id, $ref=null)
Load object in memory from the database.
Definition: mo.class.php:445
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
Definition: mo.class.php:1399
reopen($user, $notrigger=0)
Set back to validated status.
Definition: mo.class.php:1155
updateProduction(User $user, $notrigger=true)
Update quantities in lines to consume and/or lines to produce.
Definition: mo.class.php:787
getMoParent()
Function used to return childs of Mo.
Definition: mo.class.php:1675
getLinesArray($rolefilter='')
Create an array of lines.
Definition: mo.class.php:1412
LibStatut($status, $mode=0)
Return the status.
Definition: mo.class.php:1327
setDraft($user, $notrigger=0)
Set draft status.
Definition: mo.class.php:1107
printOriginLine($line, $var, $restrictlist='', $defaulttpldir='/core/tpl', $selectedLines=array())
Return HTML with a line of table array of source object lines TODO Move this and previous function in...
Definition: mo.class.php:1581
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter=array(), $filtermode='AND')
Load list of objects in memory from the database.
Definition: mo.class.php:482
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually picto)
Definition: mo.class.php:1712
validate($user, $notrigger=0)
Validate Mo.
Definition: mo.class.php:982
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
Definition: mo.class.php:1476
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
Definition: mo.class.php:1443
getTooltipContentArray($params)
getTooltipContentArray
Definition: mo.class.php:1179
createProduction(User $user, $notrigger=true)
Erase and update the line to consume and to produce.
Definition: mo.class.php:678
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
Definition: mo.class.php:1228
getLibStatut($mode=0)
Return label of the status.
Definition: mo.class.php:1314
info($id)
Load the info information in the object.
Definition: mo.class.php:1369
create(User $user, $notrigger=false)
Create object into database.
Definition: mo.class.php:292
countMovements()
Count number of movement with origin of MO.
Definition: mo.class.php:607
createFromClone(User $user, $fromid)
Clone an object into another one.
Definition: mo.class.php:350
Class MoLine.
Definition: mo.class.php:1750
create(User $user, $notrigger=false)
Create object into database.
Definition: mo.class.php:1865
update(User $user, $notrigger=false)
Update object into database.
Definition: mo.class.php:1973
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter=array(), $filtermode='AND')
Load list of objects in memory from the database.
Definition: mo.class.php:1899
__construct(DoliDB $db)
Constructor.
Definition: mo.class.php:1826
fetch($id, $ref=null)
Load object in memory from the database.
Definition: mo.class.php:1882
Class to manage stock movements.
Class to manage products or services.
Class to manage Dolibarr users.
Definition: user.class.php:48
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
Definition: index.php:746
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
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
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
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.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
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.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.