dolibarr  18.0.0-beta
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'=>'$conf->stock->enabled', '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 
152 
153  public $tms;
154  public $fk_user_creat;
155  public $fk_user_modif;
156  public $import_key;
157  public $status;
158 
162  public $fk_product;
163 
167  public $product;
168 
172  public $date_start_planned;
173 
177  public $date_end_planned;
178 
179 
183  public $fk_bom;
184 
188  public $bom;
189 
193  public $fk_project;
194 
195  // If this object has a subtable with lines
196 
200  public $table_element_line = 'mrp_production';
201 
205  public $fk_element = 'fk_mo';
206 
210  public $class_element_line = 'MoLine';
211 
215  protected $childtables = array();
216 
220  protected $childtablesoncascade = array('mrp_production');
221 
225  public $lines = array();
226 
230  public $line = array();
231 
235  public $fk_parent_line;
236 
240  public $tpl = array();
241 
247  public function __construct(DoliDB $db)
248  {
249  global $conf, $langs;
250 
251  $this->db = $db;
252 
253  if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) {
254  $this->fields['rowid']['visible'] = 0;
255  }
256  if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
257  $this->fields['entity']['enabled'] = 0;
258  }
259 
260  // Unset fields that are disabled
261  foreach ($this->fields as $key => $val) {
262  if (isset($val['enabled']) && empty($val['enabled'])) {
263  unset($this->fields[$key]);
264  }
265  }
266 
267  // Translate some data of arrayofkeyval
268  foreach ($this->fields as $key => $val) {
269  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
270  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
271  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
272  }
273  }
274  }
275  }
276 
284  public function create(User $user, $notrigger = false)
285  {
286  $error = 0;
287  $idcreated = 0;
288 
289  // 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
290  if (getDolGlobalString('PRODUIT_SOUSPRODUITS') && !getDolGlobalString('ALLOW_USE_KITS_INTO_BOM_AND_MO') && $this->fk_product > 0) {
291  include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
292  $tmpproduct = new Product($this->db);
293  $tmpproduct->fetch($this->fk_product);
294  if ($tmpproduct->hasFatherOrChild(1) > 0) {
295  $this->error = 'ErrorAVirtualProductCantBeUsedIntoABomOrMo';
296  $this->errors[] = $this->error;
297  return -1;
298  }
299  }
300 
301  $this->db->begin();
302 
303  if ($this->fk_bom > 0) {
304  // If there is a nown BOM, we force the type of MO to the type of BOM
305  include_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
306  $tmpbom = new BOM($this->db);
307  $tmpbom->fetch($this->fk_bom);
308 
309  $this->mrptype = $tmpbom->bomtype;
310  }
311 
312  if (!$error) {
313  $idcreated = $this->createCommon($user, $notrigger);
314  if ($idcreated <= 0) {
315  $error++;
316  }
317  }
318 
319  if (!$error) {
320  $result = $this->createProduction($user, $notrigger); // Insert lines from BOM
321  if ($result <= 0) {
322  $error++;
323  }
324  }
325 
326  if (!$error) {
327  $this->db->commit();
328  } else {
329  $this->db->rollback();
330  }
331 
332  return $idcreated;
333  }
334 
342  public function createFromClone(User $user, $fromid)
343  {
344  global $langs, $extrafields;
345  $error = 0;
346 
347  dol_syslog(__METHOD__, LOG_DEBUG);
348 
349  $object = new self($this->db);
350 
351  $this->db->begin();
352 
353  // Load source object
354  $result = $object->fetchCommon($fromid);
355  if ($result > 0 && !empty($object->table_element_line)) {
356  $object->fetchLines();
357  }
358 
359  // get lines so they will be clone
360  //foreach($this->lines as $line)
361  // $line->fetch_optionals();
362 
363  // Reset some properties
364  unset($object->id);
365  unset($object->fk_user_creat);
366  unset($object->import_key);
367 
368  // Clear fields
369  $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default'];
370  $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
371  $object->status = self::STATUS_DRAFT;
372  // ...
373  // Clear extrafields that are unique
374  if (is_array($object->array_options) && count($object->array_options) > 0) {
375  $extrafields->fetch_name_optionals_label($this->table_element);
376  foreach ($object->array_options as $key => $option) {
377  $shortkey = preg_replace('/options_/', '', $key);
378  if (!empty($extrafields->attributes[$this->element]['unique'][$shortkey])) {
379  //var_dump($key);
380  //var_dump($clonedObj->array_options[$key]); exit;
381  unset($object->array_options[$key]);
382  }
383  }
384  }
385 
386  // Create clone
387  $object->context['createfromclone'] = 'createfromclone';
388  $result = $object->createCommon($user);
389  if ($result < 0) {
390  $error++;
391  $this->error = $object->error;
392  $this->errors = $object->errors;
393  }
394 
395  if (!$error) {
396  // copy internal contacts
397  if ($this->copy_linked_contact($object, 'internal') < 0) {
398  $error++;
399  }
400  }
401 
402  if (!$error) {
403  // copy external contacts if same company
404  if (property_exists($this, 'socid') && $this->socid == $object->socid) {
405  if ($this->copy_linked_contact($object, 'external') < 0) {
406  $error++;
407  }
408  }
409  }
410 
411  unset($object->context['createfromclone']);
412 
413  // End
414  if (!$error) {
415  $this->db->commit();
416  return $object;
417  } else {
418  $this->db->rollback();
419  return -1;
420  }
421  }
422 
430  public function fetch($id, $ref = null)
431  {
432  $result = $this->fetchCommon($id, $ref);
433  if ($result > 0 && !empty($this->table_element_line)) {
434  $this->fetchLines();
435  }
436 
437  $this->socid = $this->fk_soc;
438 
439  return $result;
440  }
441 
447  public function fetchLines()
448  {
449  $this->lines = array();
450 
451  $result = $this->fetchLinesCommon();
452  return $result;
453  }
454 
455 
467  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
468  {
469  global $conf;
470 
471  dol_syslog(__METHOD__, LOG_DEBUG);
472 
473  $records = array();
474 
475  $sql = 'SELECT ';
476  $sql .= $this->getFieldList();
477  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
478  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
479  $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
480  } else {
481  $sql .= ' WHERE 1 = 1';
482  }
483  // Manage filter
484  $sqlwhere = array();
485  if (count($filter) > 0) {
486  foreach ($filter as $key => $value) {
487  if ($key == 't.rowid') {
488  $sqlwhere[] = $key." = ".((int) $value);
489  } elseif (strpos($key, 'date') !== false) {
490  $sqlwhere[] = $key." = '".$this->db->idate($value)."'";
491  } elseif ($key == 'customsql') {
492  $sqlwhere[] = $value;
493  } else {
494  $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'";
495  }
496  }
497  }
498  if (count($sqlwhere) > 0) {
499  $sql .= ' AND ('.implode(' '.$this->db->escape($filtermode).' ', $sqlwhere).')';
500  }
501 
502  if (!empty($sortfield)) {
503  $sql .= $this->db->order($sortfield, $sortorder);
504  }
505  if (!empty($limit)) {
506  $sql .= $this->db->plimit($limit, $offset);
507  }
508 
509  $resql = $this->db->query($sql);
510  if ($resql) {
511  $num = $this->db->num_rows($resql);
512  $i = 0;
513  while ($i < min($limit, $num)) {
514  $obj = $this->db->fetch_object($resql);
515 
516  $record = new self($this->db);
517  $record->setVarsFromFetchObj($obj);
518 
519  $records[$record->id] = $record;
520 
521  $i++;
522  }
523  $this->db->free($resql);
524 
525  return $records;
526  } else {
527  $this->errors[] = 'Error '.$this->db->lasterror();
528  dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
529 
530  return -1;
531  }
532  }
533 
541  public function fetchLinesLinked($role, $lineid = 0)
542  {
543  $resarray = array();
544  $mostatic = new MoLine($this->db);
545 
546  $sql = 'SELECT ';
547  $sql .= $mostatic->getFieldList();
548  $sql .= ' FROM '.MAIN_DB_PREFIX.$mostatic->table_element.' as t';
549  $sql .= " WHERE t.role = '".$this->db->escape($role)."'";
550  if ($lineid > 0) {
551  $sql .= ' AND t.fk_mrp_production = '.((int) $lineid);
552  } else {
553  $sql .= 'AND t.fk_mo = '.((int) $this->id);
554  }
555 
556  $resql = $this->db->query($sql);
557  if ($resql) {
558  $num = $this->db->num_rows($resql);
559 
560  $i = 0;
561  while ($i < $num) {
562  $obj = $this->db->fetch_object($resql);
563  if ($obj) {
564  $resarray[] = array(
565  'rowid'=> $obj->rowid,
566  'date'=> $this->db->jdate($obj->date_creation),
567  'qty' => $obj->qty,
568  'role' => $obj->role,
569  'fk_product' => $obj->fk_product,
570  'fk_warehouse' => $obj->fk_warehouse,
571  'batch' => $obj->batch,
572  'fk_stock_movement' => $obj->fk_stock_movement
573  );
574  }
575 
576  $i++;
577  }
578 
579  return $resarray;
580  } else {
581  $this->error = $this->db->lasterror();
582  return array();
583  }
584  }
585 
586 
592  public function countMovements()
593  {
594  $result = 0;
595 
596  $sql = 'SELECT COUNT(rowid) as nb FROM '.MAIN_DB_PREFIX.'stock_mouvement as sm';
597  $sql .= " WHERE sm.origintype = 'mo' and sm.fk_origin = ".((int) $this->id);
598 
599  $resql = $this->db->query($sql);
600  if ($resql) {
601  $num = $this->db->num_rows($resql);
602 
603  $i = 0;
604  while ($i < $num) {
605  $obj = $this->db->fetch_object($resql);
606  if ($obj) {
607  $result = $obj->nb;
608  }
609 
610  $i++;
611  }
612  } else {
613  $this->error = $this->db->lasterror();
614  }
615 
616  return $result;
617  }
618 
619 
627  public function update(User $user, $notrigger = false)
628  {
629  global $langs;
630 
631  $error = 0;
632 
633  $this->db->begin();
634 
635  $result = $this->updateCommon($user, $notrigger);
636  if ($result <= 0) {
637  $error++;
638  }
639 
640  // Update the lines (the qty) to consume or to produce
641  $result = $this->updateProduction($user, $notrigger);
642  if ($result <= 0) {
643  $error++;
644  }
645 
646  if (!$error) {
647  $this->db->commit();
648  return 1;
649  } else {
650  $this->db->rollback();
651  return -1;
652  }
653  }
654 
655 
663  public function createProduction(User $user, $notrigger = true)
664  {
665  $error = 0;
666  $role = "";
667 
668  if ($this->status != self::STATUS_DRAFT) {
669  return -1;
670  }
671 
672  $this->db->begin();
673 
674  // Insert lines in mrp_production table from BOM data
675  if (!$error) {
676  $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'mrp_production WHERE fk_mo = '.((int) $this->id);
677  $this->db->query($sql);
678 
679  $moline = new MoLine($this->db);
680 
681  // Line to produce
682  $moline->fk_mo = $this->id;
683  $moline->qty = $this->qty;
684  $moline->fk_product = $this->fk_product;
685  $moline->position = 1;
686 
687  if ($this->fk_bom > 0) { // If a BOM is defined, we know what to produce.
688  include_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
689  $bom = new Bom($this->db);
690  $bom->fetch($this->fk_bom);
691  if ($bom->bomtype == 1) {
692  $role = 'toproduce';
693  $moline->role = 'toconsume';
694  } else {
695  $role = 'toconsume';
696  $moline->role = 'toproduce';
697  }
698  } else {
699  if ($this->mrptype == 1) {
700  $moline->role = 'toconsume';
701  } else {
702  $moline->role = 'toproduce';
703  }
704  }
705 
706  $resultline = $moline->create($user, false); // Never use triggers here
707  if ($resultline <= 0) {
708  $error++;
709  $this->error = $moline->error;
710  $this->errors = $moline->errors;
711  dol_print_error($this->db, $moline->error, $moline->errors);
712  }
713 
714  if ($this->fk_bom > 0) { // If a BOM is defined, we know what to consume.
715  if ($bom->id > 0) {
716  // Lines to consume
717  if (!$error) {
718  foreach ($bom->lines as $line) {
719  $moline = new MoLine($this->db);
720 
721  $moline->fk_mo = $this->id;
722  $moline->origin_id = $line->id;
723  $moline->origin_type = 'bomline';
724  if ($line->qty_frozen) {
725  $moline->qty = $line->qty; // Qty to consume does not depends on quantity to produce
726  } else {
727  $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
728  }
729  if ($moline->qty <= 0) {
730  $error++;
731  $this->error = "BadValueForquantityToConsume";
732  break;
733  } else {
734  $moline->fk_product = $line->fk_product;
735  $moline->role = $role;
736  $moline->position = $line->position;
737  $moline->qty_frozen = $line->qty_frozen;
738  $moline->disable_stock_change = $line->disable_stock_change;
739  if (!empty($line->fk_default_workstation)) $moline->fk_default_workstation = $line->fk_default_workstation;
740 
741  $resultline = $moline->create($user, false); // Never use triggers here
742  if ($resultline <= 0) {
743  $error++;
744  $this->error = $moline->error;
745  $this->errors = $moline->errors;
746  dol_print_error($this->db, $moline->error, $moline->errors);
747  break;
748  }
749  }
750  }
751  }
752  }
753  }
754  }
755 
756  if (!$error) {
757  $this->db->commit();
758  return 1;
759  } else {
760  $this->db->rollback();
761  return -1;
762  }
763  }
764 
772  public function updateProduction(User $user, $notrigger = true)
773  {
774  $error = 0;
775 
776  if ($this->status != self::STATUS_DRAFT) return 1;
777 
778  $this->db->begin();
779 
780  $oldQty = $this->oldQty;
781  $newQty = $this->qty;
782  if ($newQty != $oldQty && !empty($this->oldQty)) {
783  $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "mrp_production WHERE fk_mo = " . (int) $this->id;
784  $resql = $this->db->query($sql);
785  if ($resql) {
786  while ($obj = $this->db->fetch_object($resql)) {
787  $moLine = new MoLine($this->db);
788  $res = $moLine->fetch($obj->rowid);
789  if (!$res) $error++;
790 
791  if ($moLine->role == 'toconsume' || $moLine->role == 'toproduce') {
792  if (empty($moLine->qty_frozen)) {
793  $qty = $newQty * $moLine->qty / $oldQty;
794  $moLine->qty = price2num($qty * (!empty($line->efficiency) ? $line->efficiency : 1 ), 'MS'); // Calculate with Qty to produce and more presition
795  $res = $moLine->update($user);
796  if (!$res) $error++;
797  }
798  }
799  }
800  }
801  }
802 
803  if (!$error) {
804  $this->db->commit();
805  return 1;
806  } else {
807  $this->db->rollback();
808  return -1;
809  }
810  }
811 
812 
820  public function delete(User $user, $notrigger = false)
821  {
822  return $this->deleteCommon($user, $notrigger);
823  //return $this->deleteCommon($user, $notrigger, 1);
824  }
825 
834  public function deleteLine(User $user, $idline, $notrigger = false)
835  {
836  global $langs;
837  $langs->load('stocks');
838 
839  if ($this->status < 0) {
840  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
841  return -2;
842  }
843 
844  $productstatic = new Product($this->db);
845  $fk_movement = GETPOST('fk_movement', 'int');
846  $arrayoflines = $this->fetchLinesLinked('consumed', $idline);
847 
848  if (!empty($arrayoflines)) {
849  $this->db->begin();
850 
851  $stockmove = new MouvementStock($this->db);
852  $stockmove->setOrigin($this->element, $this->id);
853 
854  if (!empty($fk_movement)) {
855  $moline = new MoLine($this->db);
856  $TArrayMoLine = $moline->fetchAll('', '', 1, 0, array('customsql' => 'fk_stock_movement ='.$fk_movement));
857  $moline = array_shift($TArrayMoLine);
858 
859  $movement = new MouvementStock($this->db);
860  $movement->fetch($fk_movement);
861  $productstatic->fetch($movement->product_id);
862  $qtytoprocess = $movement->qty;
863 
864  // Reverse stock movement
865  $labelmovementCancel = $langs->trans("CancelProductionForRef", $productstatic->ref);
866  $codemovementCancel = $langs->trans("StockIncrease");
867 
868  if (($qtytoprocess >= 0)) {
869  $idstockmove = $stockmove->reception($user, $movement->product_id, $movement->warehouse_id, $qtytoprocess, 0, $labelmovementCancel, '', '', $movement->batch, dol_now(), 0, $codemovementCancel);
870  } else {
871  $idstockmove = $stockmove->livraison($user, $movement->product_id, $movement->warehouse_id, $qtytoprocess, 0, $labelmovementCancel, dol_now(), '', '', $movement->batch, 0, $codemovementCancel);
872  }
873  if ($idstockmove < 0) {
874  $this->error++;
875  $this->db->rollback();
876  setEventMessages($stockmove->error, $stockmove->errors, 'errors');
877  } else {
878  $this->db->commit();
879  }
880  return $moline->delete($user, $notrigger);
881  } else {
882  foreach ($arrayoflines as $key => $arrayofline) {
883  $lineDetails = $arrayoflines[$key];
884  $productstatic->fetch($lineDetails['fk_product']);
885  $qtytoprocess = $lineDetails['qty'];
886 
887  // Reverse stock movement
888  $labelmovementCancel = $langs->trans("CancelProductionForRef", $productstatic->ref);
889  $codemovementCancel = $langs->trans("StockIncrease");
890 
891  if ($qtytoprocess >= 0) {
892  $idstockmove = $stockmove->reception($user, $lineDetails['fk_product'], $lineDetails['fk_warehouse'], $qtytoprocess, 0, $labelmovementCancel, '', '', $lineDetails['batch'], dol_now(), 0, $codemovementCancel);
893  } else {
894  $idstockmove = $stockmove->livraison($user, $lineDetails['fk_product'], $lineDetails['fk_warehouse'], $qtytoprocess, 0, $labelmovementCancel, dol_now(), '', '', $lineDetails['batch'], 0, $codemovementCancel);
895  }
896  if ($idstockmove < 0) {
897  $this->error++;
898  $this->db->rollback();
899  setEventMessages($stockmove->error, $stockmove->errors, 'errors');
900  } else {
901  $this->db->commit();
902  }
903  }
904  return $this->deleteLineCommon($user, $idline, $notrigger);
905  }
906  } else {
907  return $this->deleteLineCommon($user, $idline, $notrigger);
908  }
909  }
910 
911 
919  public function getNextNumRef($prod)
920  {
921  global $langs, $conf;
922  $langs->load("mrp");
923 
924  if (!empty($conf->global->MRP_MO_ADDON)) {
925  $mybool = false;
926 
927  $file = $conf->global->MRP_MO_ADDON.".php";
928  $classname = $conf->global->MRP_MO_ADDON;
929 
930  // Include file with class
931  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
932  foreach ($dirmodels as $reldir) {
933  $dir = dol_buildpath($reldir."core/modules/mrp/");
934 
935  // Load file with numbering class (if found)
936  $mybool |= @include_once $dir.$file;
937  }
938 
939  if ($mybool === false) {
940  dol_print_error('', "Failed to include file ".$file);
941  return '';
942  }
943 
944  $obj = new $classname();
945  $numref = $obj->getNextValue($prod, $this);
946 
947  if ($numref != "") {
948  return $numref;
949  } else {
950  $this->error = $obj->error;
951  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
952  return "";
953  }
954  } else {
955  print $langs->trans("Error")." ".$langs->trans("Error_MRP_MO_ADDON_NotDefined");
956  return "";
957  }
958  }
959 
967  public function validate($user, $notrigger = 0)
968  {
969  global $conf, $langs;
970 
971  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
972 
973  $error = 0;
974 
975  // Protection
976  if ($this->status == self::STATUS_VALIDATED) {
977  dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
978  return 0;
979  }
980 
981  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mrp->create))
982  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mrp->mrp_advance->validate))))
983  {
984  $this->error='NotEnoughPermissions';
985  dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
986  return -1;
987  }*/
988 
989  $now = dol_now();
990 
991  $this->db->begin();
992 
993  // Define new ref
994  if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
995  $this->fetch_product();
996  $num = $this->getNextNumRef($this->product);
997  } else {
998  $num = $this->ref;
999  }
1000  $this->newref = $num;
1001 
1002  // Validate
1003  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
1004  $sql .= " SET ref = '".$this->db->escape($num)."',";
1005  $sql .= " status = ".self::STATUS_VALIDATED.",";
1006  $sql .= " date_valid='".$this->db->idate($now)."',";
1007  $sql .= " fk_user_valid = ".$user->id;
1008  $sql .= " WHERE rowid = ".((int) $this->id);
1009 
1010  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
1011  $resql = $this->db->query($sql);
1012  if (!$resql) {
1013  dol_print_error($this->db);
1014  $this->error = $this->db->lasterror();
1015  $error++;
1016  }
1017 
1018  if (!$error && !$notrigger) {
1019  // Call trigger
1020  $result = $this->call_trigger('MRP_MO_VALIDATE', $user);
1021  if ($result < 0) {
1022  $error++;
1023  }
1024  // End call triggers
1025  }
1026 
1027  if (!$error) {
1028  $this->oldref = $this->ref;
1029 
1030  // Rename directory if dir was a temporary ref
1031  if (preg_match('/^[\(]?PROV/i', $this->ref)) {
1032  // Now we rename also files into index
1033  $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)."'";
1034  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'mrp/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
1035  $resql = $this->db->query($sql);
1036  if (!$resql) {
1037  $error++; $this->error = $this->db->lasterror();
1038  }
1039 
1040  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
1041  $oldref = dol_sanitizeFileName($this->ref);
1042  $newref = dol_sanitizeFileName($num);
1043  $dirsource = $conf->mrp->dir_output.'/'.$oldref;
1044  $dirdest = $conf->mrp->dir_output.'/'.$newref;
1045  if (!$error && file_exists($dirsource)) {
1046  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
1047 
1048  if (@rename($dirsource, $dirdest)) {
1049  dol_syslog("Rename ok");
1050  // Rename docs starting with $oldref with $newref
1051  $listoffiles = dol_dir_list($conf->mrp->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
1052  foreach ($listoffiles as $fileentry) {
1053  $dirsource = $fileentry['name'];
1054  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
1055  $dirsource = $fileentry['path'].'/'.$dirsource;
1056  $dirdest = $fileentry['path'].'/'.$dirdest;
1057  @rename($dirsource, $dirdest);
1058  }
1059  }
1060  }
1061  }
1062  }
1063 
1064  // Set new ref and current status
1065  if (!$error) {
1066  $this->ref = $num;
1067  $this->status = self::STATUS_VALIDATED;
1068  }
1069 
1070  if (!$error) {
1071  $this->db->commit();
1072  return 1;
1073  } else {
1074  $this->db->rollback();
1075  return -1;
1076  }
1077  }
1078 
1086  public function setDraft($user, $notrigger = 0)
1087  {
1088  // Protection
1089  if ($this->status <= self::STATUS_DRAFT) {
1090  return 0;
1091  }
1092 
1093  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->write))
1094  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->mymodule_advance->validate))))
1095  {
1096  $this->error='Permission denied';
1097  return -1;
1098  }*/
1099 
1100  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'MRP_MO_UNVALIDATE');
1101  }
1102 
1110  public function cancel($user, $notrigger = 0)
1111  {
1112  // Protection
1113  if ($this->status != self::STATUS_VALIDATED && $this->status != self::STATUS_INPROGRESS) {
1114  return 0;
1115  }
1116 
1117  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->write))
1118  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->mymodule_advance->validate))))
1119  {
1120  $this->error='Permission denied';
1121  return -1;
1122  }*/
1123 
1124  return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'MRP_MO_CANCEL');
1125  }
1126 
1134  public function reopen($user, $notrigger = 0)
1135  {
1136  // Protection
1137  if ($this->status != self::STATUS_PRODUCED && $this->status != self::STATUS_CANCELED) {
1138  return 0;
1139  }
1140 
1141  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->write))
1142  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->mymodule_advance->validate))))
1143  {
1144  $this->error='Permission denied';
1145  return -1;
1146  }*/
1147 
1148  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'MRP_MO_REOPEN');
1149  }
1150 
1158  public function getTooltipContentArray($params)
1159  {
1160  global $conf, $langs;
1161 
1162  $langs->loadLangs(['mrp', 'products']);
1163  $nofetch = isset($params['nofetch']) ? true : false;
1164 
1165  $datas = [];
1166 
1167  $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("ManufacturingOrder").'</u>';
1168  if (isset($this->status)) {
1169  $datas['picto'] .= ' '.$this->getLibStatut(5);
1170  }
1171  $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
1172  if (isset($this->label)) {
1173  $datas['label'] = '<br><b>'.$langs->trans('Label').':</b> '.$this->label;
1174  }
1175  if (isset($this->mrptype)) {
1176  $datas['type'] = '<br><b>'.$langs->trans('Type').':</b> '.$this->fields['mrptype']['arrayofkeyval'][$this->mrptype];
1177  }
1178  if (isset($this->qty)) {
1179  $datas['qty'] = '<br><b>'.$langs->trans('QtyToProduce').':</b> '.$this->qty;
1180  }
1181  if (!$nofetch && isset($this->fk_product)) {
1182  require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
1183  $product = new Product($this->db);
1184  $product->fetch($this->fk_product);
1185  $datas['product'] = '<br><b>'.$langs->trans('Product').':</b> '.$product->getNomUrl(1, '', 0, -1, 1);
1186  }
1187  if (!$nofetch && isset($this->fk_warehouse)) {
1188  require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php';
1189  $warehouse = new Entrepot($this->db);
1190  $warehouse->fetch($this->fk_warehouse);
1191  $datas['warehouse'] = '<br><b>'.$langs->trans('WarehouseForProduction').':</b> '.$warehouse->getNomUrl(1, '', 0, 1);
1192  }
1193 
1194  return $datas;
1195  }
1196 
1207  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
1208  {
1209  global $conf, $langs, $hookmanager;
1210 
1211  if (!empty($conf->dol_no_mouse_hover)) {
1212  $notooltip = 1; // Force disable tooltips
1213  }
1214 
1215  $result = '';
1216  $params = [
1217  'id' => $this->id,
1218  'objecttype' => $this->element,
1219  'option' => $option,
1220  'nofetch' => 1,
1221  ];
1222  $classfortooltip = 'classfortooltip';
1223  $dataparams = '';
1224  if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1225  $classfortooltip = 'classforajaxtooltip';
1226  $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1227  $label = '';
1228  } else {
1229  $label = implode($this->getTooltipContentArray($params));
1230  }
1231 
1232  $url = DOL_URL_ROOT.'/mrp/mo_card.php?id='.$this->id;
1233  if ($option == 'production') {
1234  $url = DOL_URL_ROOT.'/mrp/mo_production.php?id='.$this->id;
1235  }
1236 
1237  if ($option != 'nolink') {
1238  // Add param to save lastsearch_values or not
1239  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1240  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1241  $add_save_lastsearch_values = 1;
1242  }
1243  if ($add_save_lastsearch_values) {
1244  $url .= '&save_lastsearch_values=1';
1245  }
1246  }
1247 
1248  $linkclose = '';
1249  if (empty($notooltip)) {
1250  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
1251  $label = $langs->trans("ShowMo");
1252  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1253  }
1254  $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1255  $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1256  } else {
1257  $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1258  }
1259 
1260  $linkstart = '<a href="'.$url.'"';
1261  $linkstart .= $linkclose.'>';
1262  $linkend = '</a>';
1263 
1264  $result .= $linkstart;
1265  if ($withpicto) {
1266  $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (($withpicto != 2) ? 'class="paddingright"' : ''), 0, 0, $notooltip ? 0 : 1);
1267  }
1268  if ($withpicto != 2) {
1269  $result .= $this->ref;
1270  }
1271  $result .= $linkend;
1272  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
1273 
1274  global $action, $hookmanager;
1275  $hookmanager->initHooks(array('modao'));
1276  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
1277  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1278  if ($reshook > 0) {
1279  $result = $hookmanager->resPrint;
1280  } else {
1281  $result .= $hookmanager->resPrint;
1282  }
1283 
1284  return $result;
1285  }
1286 
1293  public function getLibStatut($mode = 0)
1294  {
1295  return $this->LibStatut($this->status, $mode);
1296  }
1297 
1298  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1306  public function LibStatut($status, $mode = 0)
1307  {
1308  // phpcs:enable
1309  if (empty($this->labelStatus)) {
1310  global $langs;
1311  //$langs->load("mrp");
1312  $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
1313  $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ValidatedToProduce');
1314  $this->labelStatus[self::STATUS_INPROGRESS] = $langs->transnoentitiesnoconv('InProgress');
1315  $this->labelStatus[self::STATUS_PRODUCED] = $langs->transnoentitiesnoconv('StatusMOProduced');
1316  $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
1317 
1318  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
1319  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
1320  $this->labelStatusShort[self::STATUS_INPROGRESS] = $langs->transnoentitiesnoconv('InProgress');
1321  $this->labelStatusShort[self::STATUS_PRODUCED] = $langs->transnoentitiesnoconv('StatusMOProduced');
1322  $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
1323  }
1324 
1325  $statusType = 'status'.$status;
1326  if ($status == self::STATUS_VALIDATED) {
1327  $statusType = 'status1';
1328  }
1329  if ($status == self::STATUS_INPROGRESS) {
1330  $statusType = 'status4';
1331  }
1332  if ($status == self::STATUS_PRODUCED) {
1333  $statusType = 'status6';
1334  }
1335  if ($status == self::STATUS_CANCELED) {
1336  $statusType = 'status9';
1337  }
1338 
1339  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
1340  }
1341 
1348  public function info($id)
1349  {
1350  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
1351  $sql .= ' fk_user_creat, fk_user_modif';
1352  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
1353  $sql .= ' WHERE t.rowid = '.((int) $id);
1354  $result = $this->db->query($sql);
1355  if ($result) {
1356  if ($this->db->num_rows($result)) {
1357  $obj = $this->db->fetch_object($result);
1358  $this->id = $obj->rowid;
1359 
1360  $this->user_creation_id = $obj->fk_user_creat;
1361  $this->user_modification_id = $obj->fk_user_modif;
1362  $this->date_creation = $this->db->jdate($obj->datec);
1363  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
1364  }
1365 
1366  $this->db->free($result);
1367  } else {
1368  dol_print_error($this->db);
1369  }
1370  }
1371 
1378  public function initAsSpecimen()
1379  {
1380  $this->initAsSpecimenCommon();
1381 
1382  $this->lines = array();
1383  }
1384 
1391  public function getLinesArray($rolefilter = '')
1392  {
1393  $this->lines = array();
1394 
1395  $objectline = new MoLine($this->db);
1396 
1397  $TFilters = array('customsql'=>'fk_mo = '.((int) $this->id));
1398  if (!empty($rolefilter)) $TFilters['role'] = $rolefilter;
1399  $result = $objectline->fetchAll('ASC', 'position', 0, 0, $TFilters);
1400 
1401  if (is_numeric($result)) {
1402  $this->error = $objectline->error;
1403  $this->errors = $objectline->errors;
1404  return $result;
1405  } else {
1406  $this->lines = $result;
1407  return $this->lines;
1408  }
1409  }
1410 
1422  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1423  {
1424  global $conf, $langs;
1425 
1426  $langs->load("mrp");
1427 
1428  if (!dol_strlen($modele)) {
1429  //$modele = 'standard';
1430  $modele = ''; // Remove this once a pdf_standard.php exists.
1431 
1432  if ($this->model_pdf) {
1433  $modele = $this->model_pdf;
1434  } elseif (!empty($conf->global->MO_ADDON_PDF)) {
1435  $modele = $conf->global->MO_ADDON_PDF;
1436  }
1437  }
1438 
1439  $modelpath = "core/modules/mrp/doc/";
1440 
1441  if (empty($modele)) {
1442  return 1; // Remove this once a pdf_standard.php exists.
1443  }
1444 
1445  return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1446  }
1447 
1455  public function doScheduledJob()
1456  {
1457  global $conf, $langs;
1458 
1459  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1460 
1461  $error = 0;
1462  $this->output = '';
1463  $this->error = '';
1464 
1465  dol_syslog(__METHOD__, LOG_DEBUG);
1466 
1467  $now = dol_now();
1468 
1469  $this->db->begin();
1470 
1471  // ...
1472 
1473  $this->db->commit();
1474 
1475  return $error;
1476  }
1477 
1488  public function printOriginLinesList($restrictlist = '', $selectedLines = array())
1489  {
1490  global $langs, $hookmanager, $conf, $form;
1491 
1492  $langs->load('stocks');
1493  $text_stock_options = $langs->trans("RealStockDesc").'<br>';
1494  $text_stock_options .= $langs->trans("RealStockWillAutomaticallyWhen").'<br>';
1495  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || !empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE) ? '- '.$langs->trans("DeStockOnShipment").'<br>' : '');
1496  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) ? '- '.$langs->trans("DeStockOnValidateOrder").'<br>' : '');
1497  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_BILL) ? '- '.$langs->trans("DeStockOnBill").'<br>' : '');
1498  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL) ? '- '.$langs->trans("ReStockOnBill").'<br>' : '');
1499  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER) ? '- '.$langs->trans("ReStockOnValidateOrder").'<br>' : '');
1500  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) ? '- '.$langs->trans("ReStockOnDispatchOrder").'<br>' : '');
1501  $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE) ? '- '.$langs->trans("StockOnReception").'<br>' : '');
1502 
1503  print '<tr class="liste_titre">';
1504  // Product or sub-bom
1505  print '<td class="linecoldescription">'.$langs->trans('Ref');
1506  if (!empty($conf->global->BOM_SUB_BOM)) {
1507  print ' &nbsp; <a id="show_all" href="#">'.img_picto('', 'folder-open', 'class="paddingright"').$langs->trans("ExpandAll").'</a>&nbsp;&nbsp;';
1508  print '<a id="hide_all" href="#">'.img_picto('', 'folder', 'class="paddingright"').$langs->trans("UndoExpandAll").'</a>&nbsp;';
1509  }
1510  print '</td>';
1511  // Qty
1512  print '<td class="right">'.$langs->trans('Qty');
1513  if ($this->bom->bomtype == 0) {
1514  print ' <span class="opacitymedium">('.$langs->trans("ForAQuantityOf", $this->bom->qty).')</span>';
1515  } else {
1516  print ' <span class="opacitymedium">('.$langs->trans("ForAQuantityToConsumeOf", $this->bom->qty).')</span>';
1517  }
1518  print '</td>';
1519  print '<td class="center">'.$form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1).'</td>';
1520  print '<td class="center">'.$form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc")).'</td>';
1521  print '<td class="center">'.$langs->trans('QtyFrozen').'</td>';
1522  print '<td class="center">'.$langs->trans('DisableStockChange').'</td>';
1523  print '<td class="center">'.$langs->trans('MoChildGenerate').'</td>';
1524  //print '<td class="center">'.$form->showCheckAddButtons('checkforselect', 1).'</td>';
1525  //print '<td class="center"></td>';
1526  print '</tr>';
1527  $i = 0;
1528 
1529  if (!empty($this->lines)) {
1530  foreach ($this->lines as $line) {
1531  $reshook = 0;
1532  if (is_object($hookmanager)) {
1533  $parameters = array('line'=>$line, 'i'=>$i, 'restrictlist'=>$restrictlist, 'selectedLines'=> $selectedLines);
1534  if (!empty($line->fk_parent_line)) { $parameters['fk_parent_line'] = $line->fk_parent_line; }
1535  $reshook = $hookmanager->executeHooks('printOriginObjectLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1536  }
1537  if (empty($reshook)) {
1538  $this->printOriginLine($line, '', $restrictlist, '/core/tpl', $selectedLines);
1539  }
1540 
1541  $i++;
1542  }
1543  }
1544  }
1545 
1546 
1560  public function printOriginLine($line, $var, $restrictlist = '', $defaulttpldir = '/core/tpl', $selectedLines = array())
1561  {
1562  global $langs, $conf;
1563 
1564  $this->tpl['id'] = $line->id;
1565 
1566  $this->tpl['label'] = '';
1567  if (!empty($line->fk_product)) {
1568  $productstatic = new Product($this->db);
1569  $productstatic->fetch($line->fk_product);
1570  $productstatic->load_virtual_stock();
1571  $this->tpl['label'] .= $productstatic->getNomUrl(1);
1572  //$this->tpl['label'].= ' - '.$productstatic->label;
1573  } else {
1574  // If origin MRP line is not a product, but another MRP
1575  // TODO
1576  }
1577 
1578  $this->tpl['qty_bom'] = 1;
1579  if (is_object($this->bom) && $this->bom->qty > 1) {
1580  $this->tpl['qty_bom'] = $this->bom->qty;
1581  }
1582 
1583  $this->tpl['stock'] = $productstatic->stock_reel;
1584  $this->tpl['seuil_stock_alerte'] = $productstatic->seuil_stock_alerte;
1585  $this->tpl['virtual_stock'] = $productstatic->stock_theorique;
1586  $this->tpl['qty'] = $line->qty;
1587  $this->tpl['qty_frozen'] = $line->qty_frozen;
1588  $this->tpl['disable_stock_change'] = $line->disable_stock_change;
1589  $this->tpl['efficiency'] = $line->efficiency;
1590 
1591  $tpl = DOL_DOCUMENT_ROOT.'/mrp/tpl/originproductline.tpl.php';
1592  $res = include $tpl;
1593  }
1594 
1603  public static function replaceThirdparty($db, $origin_id, $dest_id)
1604  {
1605  $tables = array('mrp_mo');
1606 
1607  return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
1608  }
1609 
1610 
1616  public function getMoChilds()
1617  {
1618 
1619  $TMoChilds = array();
1620  $error = 0;
1621 
1622  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."mrp_mo as mo_child";
1623  $sql.= " WHERE fk_parent_line IN ";
1624  $sql.= " (SELECT rowid FROM ".MAIN_DB_PREFIX."mrp_production as line_parent";
1625  $sql.= " WHERE fk_mo=".((int) $this->id).")";
1626 
1627  $resql = $this->db->query($sql);
1628 
1629  if ($resql) {
1630  if ($this->db->num_rows($resql) > 0) {
1631  while ($obj = $this->db->fetch_object($resql)) {
1632  $MoChild = new Mo($this->db);
1633  $res = $MoChild->fetch($obj->rowid);
1634  if ($res > 0) $TMoChilds[$MoChild->id] = $MoChild;
1635  else $error++;
1636  }
1637  }
1638  } else {
1639  $error++;
1640  }
1641 
1642  if ($error) {
1643  return -1;
1644  } else {
1645  return $TMoChilds;
1646  }
1647  }
1648 
1654  public function getMoParent()
1655  {
1656  $MoParent = new Mo($this->db);
1657  $error = 0;
1658 
1659  $sql = "SELECT lineparent.fk_mo as id_moparent FROM ".MAIN_DB_PREFIX."mrp_mo as mo";
1660  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."mrp_production lineparent ON mo.fk_parent_line = lineparent.rowid";
1661  $sql.= " WHERE mo.rowid = ".((int) $this->id);
1662 
1663  $resql = $this->db->query($sql);
1664 
1665  if ($resql) {
1666  if ($this->db->num_rows($resql) > 0) {
1667  $obj = $this->db->fetch_object($resql);
1668  $res = $MoParent->fetch($obj->id_moparent);
1669  if ($res < 0) $error++;
1670  } else {
1671  return 0;
1672  }
1673  } else {
1674  $error++;
1675  }
1676 
1677  if ($error) {
1678  return -1;
1679  } else {
1680  return $MoParent;
1681  }
1682  }
1683 
1691  public function getKanbanView($option = '', $arraydata = null)
1692  {
1693  global $langs;
1694 
1695  $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1696 
1697  $return = '<div class="box-flex-item box-flex-grow-zero">';
1698  $return .= '<div class="info-box info-box-sm">';
1699  $return .= '<span class="info-box-icon bg-infobox-action">';
1700  $return .= img_picto('', $this->picto);
1701  //$return .= '<i class="fa fa-dol-action"></i>'; // Can be image
1702  $return .= '</span>';
1703  $return .= '<div class="info-box-content">';
1704  $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
1705  $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1706  if (property_exists($this, 'fk_bom')) {
1707  $return .= '<br><span class="info-box-label opacitymedium">'.$this->fk_bom.'</span>';
1708  }
1709  if (property_exists($this, 'qty')) {
1710  $return .= '<br><span class="info-box-label">'.$langs->trans('Quantity').' : '.$this->qty.'</span>';
1711  }
1712  if (method_exists($this, 'getLibStatut')) {
1713  $return .= '<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).'</div>';
1714  }
1715  $return .= '</div>';
1716  $return .= '</div>';
1717  $return .= '</div>';
1718  return $return;
1719  }
1720 }
1721 
1726 {
1730  public $element = 'mrp_production';
1731 
1735  public $table_element = 'mrp_production';
1736 
1740  public $ismultientitymanaged = 0;
1741 
1745  public $isextrafieldmanaged = 0;
1746 
1747  public $fields = array(
1748  'rowid' =>array('type'=>'integer', 'label'=>'ID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
1749  'fk_mo' =>array('type'=>'integer', 'label'=>'Mo', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>15),
1750  'origin_id' =>array('type'=>'integer', 'label'=>'Origin', 'enabled'=>1, 'visible'=>-1, 'notnull'=>0, 'position'=>17),
1751  'origin_type' =>array('type'=>'varchar(10)', 'label'=>'Origin type', 'enabled'=>1, 'visible'=>-1, 'notnull'=>0, 'position'=>18),
1752  'position' =>array('type'=>'integer', 'label'=>'Position', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>20),
1753  'fk_product' =>array('type'=>'integer', 'label'=>'Product', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>25),
1754  'fk_warehouse' =>array('type'=>'integer', 'label'=>'Warehouse', 'enabled'=>1, 'visible'=>-1, 'position'=>30),
1755  'qty' =>array('type'=>'real', 'label'=>'Qty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35),
1756  'qty_frozen' => array('type'=>'smallint', 'label'=>'QuantityFrozen', 'enabled'=>1, 'visible'=>1, 'default'=>0, 'position'=>105, 'css'=>'maxwidth50imp', 'help'=>'QuantityConsumedInvariable'),
1757  'disable_stock_change' => array('type'=>'smallint', 'label'=>'DisableStockChange', 'enabled'=>1, 'visible'=>1, 'default'=>0, 'position'=>108, 'css'=>'maxwidth50imp', 'help'=>'DisableStockChangeHelp'),
1758  'batch' =>array('type'=>'varchar(30)', 'label'=>'Batch', 'enabled'=>1, 'visible'=>-1, 'position'=>140),
1759  'role' =>array('type'=>'varchar(10)', 'label'=>'Role', 'enabled'=>1, 'visible'=>-1, 'position'=>145),
1760  'fk_mrp_production' =>array('type'=>'integer', 'label'=>'Fk mrp production', 'enabled'=>1, 'visible'=>-1, 'position'=>150),
1761  'fk_stock_movement' =>array('type'=>'integer', 'label'=>'StockMovement', 'enabled'=>1, 'visible'=>-1, 'position'=>155),
1762  'date_creation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>160),
1763  'tms' =>array('type'=>'timestamp', 'label'=>'Tms', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>165),
1764  'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserCreation', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>170),
1765  'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModification', 'enabled'=>1, 'visible'=>-1, 'position'=>175),
1766  'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-1, 'position'=>180),
1767  'fk_default_workstation' =>array('type'=>'integer', 'label'=>'DefaultWorkstation', 'enabled'=>1, 'visible'=>1, 'notnull'=>0, 'position'=>185)
1768  );
1769 
1770  public $rowid;
1771  public $fk_mo;
1772  public $origin_id;
1773  public $origin_type;
1774  public $position;
1775  public $fk_product;
1776  public $fk_warehouse;
1777  public $qty;
1778  public $qty_frozen;
1779  public $disable_stock_change;
1780  public $efficiency;
1781  public $batch;
1782  public $role;
1783  public $fk_mrp_production;
1784  public $fk_stock_movement;
1785  public $date_creation;
1786  public $tms;
1787  public $fk_user_creat;
1788  public $fk_user_modif;
1789  public $import_key;
1790  public $fk_parent_line;
1791 
1795  public $fk_default_workstation;
1796 
1802  public function __construct(DoliDB $db)
1803  {
1804  global $conf, $langs;
1805 
1806  $this->db = $db;
1807 
1808  if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) {
1809  $this->fields['rowid']['visible'] = 0;
1810  }
1811  if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
1812  $this->fields['entity']['enabled'] = 0;
1813  }
1814 
1815  // Unset fields that are disabled
1816  foreach ($this->fields as $key => $val) {
1817  if (isset($val['enabled']) && empty($val['enabled'])) {
1818  unset($this->fields[$key]);
1819  }
1820  }
1821 
1822  // Translate some data of arrayofkeyval
1823  if (is_object($langs)) {
1824  foreach ($this->fields as $key => $val) {
1825  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
1826  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
1827  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
1828  }
1829  }
1830  }
1831  }
1832  }
1833 
1841  public function create(User $user, $notrigger = false)
1842  {
1843  if (empty($this->qty)) {
1844  $this->error = 'BadValueForQty';
1845  return -1;
1846  }
1847 
1848  return $this->createCommon($user, $notrigger);
1849  }
1850 
1858  public function fetch($id, $ref = null)
1859  {
1860  $result = $this->fetchCommon($id, $ref);
1861  return $result;
1862  }
1863 
1875  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
1876  {
1877  global $conf;
1878 
1879  dol_syslog(__METHOD__, LOG_DEBUG);
1880 
1881  $records = array();
1882 
1883  $sql = 'SELECT ';
1884  $sql .= $this->getFieldList();
1885  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
1886  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
1887  $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
1888  } else {
1889  $sql .= ' WHERE 1 = 1';
1890  }
1891  // Manage filter
1892  $sqlwhere = array();
1893  if (count($filter) > 0) {
1894  foreach ($filter as $key => $value) {
1895  if ($key == 't.rowid') {
1896  $sqlwhere[] = $key." = ".((int) $value);
1897  } elseif (strpos($key, 'date') !== false) {
1898  $sqlwhere[] = $key." = '".$this->db->idate($value)."'";
1899  } elseif ($key == 'customsql') {
1900  $sqlwhere[] = $value;
1901  } else {
1902  $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'";
1903  }
1904  }
1905  }
1906  if (count($sqlwhere) > 0) {
1907  $sql .= ' AND ('.implode(' '.$this->db->escape($filtermode).' ', $sqlwhere).')';
1908  }
1909 
1910  if (!empty($sortfield)) {
1911  $sql .= $this->db->order($sortfield, $sortorder);
1912  }
1913  if (!empty($limit)) {
1914  $sql .= $this->db->plimit($limit, $offset);
1915  }
1916 
1917  $resql = $this->db->query($sql);
1918  if ($resql) {
1919  $num = $this->db->num_rows($resql);
1920  $i = 0;
1921  while ($i < ($limit ? min($limit, $num) : $num)) {
1922  $obj = $this->db->fetch_object($resql);
1923 
1924  $record = new self($this->db);
1925  $record->setVarsFromFetchObj($obj);
1926 
1927  $records[$record->id] = $record;
1928 
1929  $i++;
1930  }
1931  $this->db->free($resql);
1932 
1933  return $records;
1934  } else {
1935  $this->errors[] = 'Error '.$this->db->lasterror();
1936  dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
1937 
1938  return -1;
1939  }
1940  }
1941 
1949  public function update(User $user, $notrigger = false)
1950  {
1951  return $this->updateCommon($user, $notrigger);
1952  }
1953 
1961  public function delete(User $user, $notrigger = false)
1962  {
1963  return $this->deleteCommon($user, $notrigger);
1964  //return $this->deleteCommon($user, $notrigger, 1);
1965  }
1966 }
CommonObject\deleteCommon
deleteCommon(User $user, $notrigger=false, $forcechilddeletion=0)
Delete object in database.
Definition: commonobject.class.php:9539
CommonObject\setStatusCommon
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
Definition: commonobject.class.php:9817
Mo\getNomUrl
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:1207
CommonObject\fetchCommon
fetchCommon($id, $ref=null, $morewhere='')
Load object in memory from the database.
Definition: commonobject.class.php:9329
dol_sanitizeFileName
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
Definition: functions.lib.php:1322
CommonObject\copy_linked_contact
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
Definition: commonobject.class.php:1099
Mo\doScheduledJob
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
Definition: mo.class.php:1455
MoLine\__construct
__construct(DoliDB $db)
Constructor.
Definition: mo.class.php:1802
DoliDB
Class to manage Dolibarr database access.
Definition: DoliDB.class.php:30
GETPOST
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Definition: functions.lib.php:607
dol_print_error
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
Definition: functions.lib.php:5096
Mo\printOriginLinesList
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:1488
MoLine
Class MoLine.
Definition: mo.class.php:1725
dol_buildpath
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
Definition: functions.lib.php:1157
dol_dir_list
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
CommonObject\fetchLinesCommon
fetchLinesCommon($morewhere='')
Load object in memory from the database.
Definition: commonobject.class.php:9385
$form
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
Mo\getNextNumRef
getNextNumRef($prod)
Returns the reference to the following non used MO depending on the active numbering module defined i...
Definition: mo.class.php:919
Mo\__construct
__construct(DoliDB $db)
Constructor.
Definition: mo.class.php:247
Mo\setDraft
setDraft($user, $notrigger=0)
Set draft status.
Definition: mo.class.php:1086
CommonObject\initAsSpecimenCommon
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
Definition: commonobject.class.php:9867
Mo\getMoParent
getMoParent()
Function used to return childs of Mo.
Definition: mo.class.php:1654
Mo
Class for Mo.
Definition: mo.class.php:33
CommonObjectLine
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Definition: commonobjectline.class.php:32
CommonObject
Parent class of all other business classes (invoices, contracts, proposals, orders,...
Definition: commonobject.class.php:45
Mo\fetchAll
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:467
BOM
Class for BOM.
Definition: bom.class.php:38
price2num
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
Definition: functions.lib.php:5943
img_picto
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
Definition: functions.lib.php:4125
CommonObject\commonGenerateDocument
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
Definition: commonobject.class.php:5334
Mo\getTooltipContentArray
getTooltipContentArray($params)
getTooltipContentArray
Definition: mo.class.php:1158
Mo\update
update(User $user, $notrigger=false)
Update object into database.
Definition: mo.class.php:627
CommonObject\createCommon
createCommon(User $user, $notrigger=false)
Create object into database.
Definition: commonobject.class.php:9162
Mo\getMoChilds
getMoChilds()
Function used to return childs of Mo.
Definition: mo.class.php:1616
MoLine\update
update(User $user, $notrigger=false)
Update object into database.
Definition: mo.class.php:1949
Mo\generateDocument
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
Definition: mo.class.php:1422
Mo\createFromClone
createFromClone(User $user, $fromid)
Clone an object into another one.
Definition: mo.class.php:342
MouvementStock
Class to manage stock movements.
Definition: mouvementstock.class.php:31
Mo\fetchLines
fetchLines()
Load object lines in memory from the database.
Definition: mo.class.php:447
Mo\getLinesArray
getLinesArray($rolefilter='')
Create an array of lines.
Definition: mo.class.php:1391
$sql
if(isModEnabled('facture') &&!empty($user->rights->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
Mo\updateProduction
updateProduction(User $user, $notrigger=true)
Update quantities in lines to consume and to produce.
Definition: mo.class.php:772
Mo\deleteLine
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
Definition: mo.class.php:834
dol_syslog
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Definition: functions.lib.php:1732
Mo\printOriginLine
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:1560
Mo\LibStatut
LibStatut($status, $mode=0)
Return the status.
Definition: mo.class.php:1306
Mo\getLibStatut
getLibStatut($mode=0)
Return label of the status.
Definition: mo.class.php:1293
setEventMessages
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
Definition: functions.lib.php:8644
Mo\replaceThirdparty
static replaceThirdparty($db, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
Definition: mo.class.php:1603
MoLine\fetch
fetch($id, $ref=null)
Load object in memory from the database.
Definition: mo.class.php:1858
CommonObject\updateCommon
updateCommon(User $user, $notrigger=false)
Update object into database.
Definition: commonobject.class.php:9435
dol_strlen
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
Definition: functions.lib.php:3987
MoLine\fetchAll
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:1875
isModEnabled
isModEnabled($module)
Is Dolibarr module enabled.
Definition: functions.lib.php:207
Mo\reopen
reopen($user, $notrigger=0)
Set back to validated status.
Definition: mo.class.php:1134
Mo\info
info($id)
Load the info information in the object.
Definition: mo.class.php:1348
ref
$object ref
Definition: info.php:78
getDolGlobalString
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
Definition: functions.lib.php:142
CommonObject\fetch_product
fetch_product()
Load the product with id $this->fk_product into this->product.
Definition: commonobject.class.php:1768
User
Class to manage Dolibarr users.
Definition: user.class.php:47
Mo\create
create(User $user, $notrigger=false)
Create object into database.
Definition: mo.class.php:284
Mo\validate
validate($user, $notrigger=0)
Validate Mo.
Definition: mo.class.php:967
Mo\fetchLinesLinked
fetchLinesLinked($role, $lineid=0)
Get list of lines linked to current line for a defined role.
Definition: mo.class.php:541
Product
Class to manage products or services.
Definition: product.class.php:46
Mo\getKanbanView
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually picto)
Definition: mo.class.php:1691
dolGetStatus
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
Definition: functions.lib.php:10932
Mo\fetch
fetch($id, $ref=null)
Load object in memory from the database.
Definition: mo.class.php:430
img_object
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
Definition: functions.lib.php:4462
Mo\cancel
cancel($user, $notrigger=0)
Set cancel status.
Definition: mo.class.php:1110
Entrepot
Class to manage warehouses.
Definition: entrepot.class.php:35
dol_now
dol_now($mode='auto')
Return date for now.
Definition: functions.lib.php:3046
Mo\countMovements
countMovements()
Count number of movement with origin of MO.
Definition: mo.class.php:592
CommonObject\deleteLineCommon
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
Definition: commonobject.class.php:9755
CommonObject\call_trigger
call_trigger($triggerName, $user)
Call trigger based on this instance.
Definition: commonobject.class.php:5743
MoLine\create
create(User $user, $notrigger=false)
Create object into database.
Definition: mo.class.php:1841
Mo\createProduction
createProduction(User $user, $notrigger=true)
Erase and update the line to consume and to produce.
Definition: mo.class.php:663
getDolGlobalInt
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
Definition: functions.lib.php:156
CommonObject\getFieldList
getFieldList($alias='')
Function to concat keys of fields.
Definition: commonobject.class.php:9114
CommonObject\commonReplaceThirdparty
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
Definition: commonobject.class.php:8469
Mo\initAsSpecimen
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
Definition: mo.class.php:1378