dolibarr  13.0.2
bom.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2019 Laurent Destailleur <eldy@users.sourceforge.net>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
24 // Put here all includes required by your class file
25 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
26 //require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
27 //require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
28 
32 class BOM extends CommonObject
33 {
37  public $element = 'bom';
38 
42  public $table_element = 'bom_bom';
43 
47  public $ismultientitymanaged = 1;
48 
52  public $isextrafieldmanaged = 1;
53 
57  public $picto = 'bom';
58 
59 
60  const STATUS_DRAFT = 0;
61  const STATUS_VALIDATED = 1;
62  const STATUS_CANCELED = 9;
63 
64 
86  // BEGIN MODULEBUILDER PROPERTIES
90  public $fields = array(
91  'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",),
92  'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=> 1, 'default'=>1, 'index'=>1, 'position'=>5),
93  'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'noteditable'=>1, 'visible'=>4, 'position'=>10, 'notnull'=>1, 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of BOM", 'showoncombobox'=>'1',),
94  'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'notnull'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'autofocusoncreate'=>1),
95  //'bomtype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>1, 'position'=>10, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing', 1=>'Disassembly')),
96  'bomtype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>-1, 'position'=>32, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing')),
97  'fk_product' => array('type'=>'integer:Product:product/class/product.class.php:1:(finished IS NULL or finished <> 0)', 'label'=>'Product', 'picto'=>'product', 'enabled'=>1, 'visible'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'help'=>'ProductBOMHelp', 'css'=>'maxwidth500'),
98  'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'notnull'=>-1,),
99  'qty' => array('type'=>'real', 'label'=>'Quantity', 'enabled'=>1, 'visible'=>1, 'default'=>1, 'position'=>55, 'notnull'=>1, 'isameasure'=>'1', 'css'=>'maxwidth75imp'),
100  //'efficiency' => array('type'=>'real', 'label'=>'ManufacturingEfficiency', 'enabled'=>1, 'visible'=>-1, 'default'=>1, 'position'=>100, 'notnull'=>0, 'css'=>'maxwidth50imp', 'help'=>'ValueOfMeansLossForProductProduced'),
101  'duration' => array('type'=>'duration', 'label'=>'EstimatedDuration', 'enabled'=>1, 'visible'=>-1, 'position'=>101, 'notnull'=>-1, 'css'=>'maxwidth50imp', 'help'=>'EstimatedDurationDesc'),
102  'fk_warehouse' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php:0', 'label'=>'WarehouseForProduction', 'picto'=>'stock', 'enabled'=>1, 'visible'=>-1, 'position'=>102, 'css'=>'maxwidth500'),
103  'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>-2, 'position'=>161, 'notnull'=>-1,),
104  'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>-2, 'position'=>162, 'notnull'=>-1,),
105  'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>300, 'notnull'=>1,),
106  'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'position'=>501, 'notnull'=>1,),
107  'date_valid' => array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-2, 'position'=>502, 'notnull'=>0,),
108  'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserCreation', 'picto'=>'user', 'enabled'=>1, 'visible'=>-2, 'position'=>510, 'notnull'=>1, 'foreignkey'=>'user.rowid',),
109  'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'picto'=>'user', 'enabled'=>1, 'visible'=>-2, 'position'=>511, 'notnull'=>-1,),
110  'fk_user_valid' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'picto'=>'user', 'enabled'=>1, 'visible'=>-2, 'position'=>512, 'notnull'=>0,),
111  'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>1000, 'notnull'=>-1,),
112  'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>1010),
113  'status' => array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>2, 'position'=>1000, 'notnull'=>1, 'default'=>0, 'index'=>1, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Enabled', 9=>'Disabled')),
114  );
115 
119  public $rowid;
120 
124  public $ref;
125 
129  public $label;
130 
134  public $bomtype;
135 
139  public $description;
140 
144  public $date_creation;
145 
146 
147  public $tms;
148 
152  public $fk_user_creat;
153 
157  public $fk_user_modif;
158 
162  public $import_key;
163 
167  public $status;
168 
172  public $fk_product;
173  public $qty;
174  public $efficiency;
175  // END MODULEBUILDER PROPERTIES
176 
177 
178  // If this object has a subtable with lines
179 
183  public $table_element_line = 'bom_bomline';
184 
188  public $fk_element = 'fk_bom';
189 
193  public $class_element_line = 'BOMLine';
194 
195  // /**
196  // * @var array List of child tables. To test if we can delete object.
197  // */
198  // protected $childtables=array();
199 
203  protected $childtablesoncascade = array('bom_bomline');
204 
208  public $lines = array();
209 
213  public $total_cost = 0;
214 
218  public $unit_cost = 0;
219 
220 
221 
227  public function __construct(DoliDB $db)
228  {
229  global $conf, $langs;
230 
231  $this->db = $db;
232 
233  if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) $this->fields['rowid']['visible'] = 0;
234  if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) $this->fields['entity']['enabled'] = 0;
235 
236  // Unset fields that are disabled
237  foreach ($this->fields as $key => $val)
238  {
239  if (isset($val['enabled']) && empty($val['enabled']))
240  {
241  unset($this->fields[$key]);
242  }
243  }
244 
245  // Translate some data of arrayofkeyval
246  foreach ($this->fields as $key => $val)
247  {
248  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval']))
249  {
250  foreach ($val['arrayofkeyval'] as $key2 => $val2)
251  {
252  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
253  }
254  }
255  }
256  }
257 
265  public function create(User $user, $notrigger = false)
266  {
267  if ($this->efficiency <= 0 || $this->efficiency > 1) $this->efficiency = 1;
268 
269  return $this->createCommon($user, $notrigger);
270  }
271 
279  public function createFromClone(User $user, $fromid)
280  {
281  global $langs, $hookmanager, $extrafields;
282  $error = 0;
283 
284  dol_syslog(__METHOD__, LOG_DEBUG);
285 
286  $object = new self($this->db);
287 
288  $this->db->begin();
289 
290  // Load source object
291  $result = $object->fetchCommon($fromid);
292  if ($result > 0 && !empty($object->table_element_line)) $object->fetchLines();
293 
294  // Get lines so they will be clone
295  //foreach ($object->lines as $line)
296  // $line->fetch_optionals();
297 
298  // Reset some properties
299  unset($object->id);
300  unset($object->fk_user_creat);
301  unset($object->import_key);
302 
303  // Clear fields
304  $object->ref = empty($this->fields['ref']['default']) ? $langs->trans("copy_of_").$object->ref : $this->fields['ref']['default'];
305  $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
306  $object->status = self::STATUS_DRAFT;
307  // ...
308  // Clear extrafields that are unique
309  if (is_array($object->array_options) && count($object->array_options) > 0)
310  {
311  $extrafields->fetch_name_optionals_label($object->table_element);
312  foreach ($object->array_options as $key => $option)
313  {
314  $shortkey = preg_replace('/options_/', '', $key);
315  if (!empty($extrafields->attributes[$this->element]['unique'][$shortkey]))
316  {
317  //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
318  unset($object->array_options[$key]);
319  }
320  }
321  }
322 
323  // Create clone
324  $object->context['createfromclone'] = 'createfromclone';
325  $result = $object->createCommon($user);
326  if ($result < 0) {
327  $error++;
328  $this->error = $object->error;
329  $this->errors = $object->errors;
330  }
331 
332  if (!$error)
333  {
334  // copy internal contacts
335  if ($this->copy_linked_contact($object, 'internal') < 0)
336  {
337  $error++;
338  }
339  }
340 
341  if (!$error)
342  {
343  // copy external contacts if same company
344  if (property_exists($this, 'socid') && $this->socid == $object->socid)
345  {
346  if ($this->copy_linked_contact($object, 'external') < 0)
347  $error++;
348  }
349  }
350 
351  // If there is lines, create lines too
352 
353 
354 
355  unset($object->context['createfromclone']);
356 
357  // End
358  if (!$error) {
359  $this->db->commit();
360  return $object;
361  } else {
362  $this->db->rollback();
363  return -1;
364  }
365  }
366 
374  public function fetch($id, $ref = null)
375  {
376  $result = $this->fetchCommon($id, $ref);
377 
378  if ($result > 0 && !empty($this->table_element_line)) $this->fetchLines();
379  $this->calculateCosts();
380 
381  return $result;
382  }
383 
389  public function fetchLines()
390  {
391  $this->lines = array();
392 
393  $result = $this->fetchLinesCommon();
394  return $result;
395  }
396 
408  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
409  {
410  global $conf;
411 
412  dol_syslog(__METHOD__, LOG_DEBUG);
413 
414  $records = array();
415 
416  $sql = 'SELECT ';
417  $sql .= $this->getFieldList();
418  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
419  if ($this->ismultientitymanaged) $sql .= ' WHERE t.entity IN ('.getEntity($this->table_element).')';
420  else $sql .= ' WHERE 1 = 1';
421  // Manage filter
422  $sqlwhere = array();
423  if (count($filter) > 0) {
424  foreach ($filter as $key => $value) {
425  if ($key == 't.rowid') {
426  $sqlwhere[] = $key.'='.$value;
427  } elseif (strpos($key, 'date') !== false) {
428  $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\'';
429  } elseif ($key == 'customsql') {
430  $sqlwhere[] = $value;
431  } else {
432  $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\'';
433  }
434  }
435  }
436  if (count($sqlwhere) > 0) {
437  $sql .= ' AND ('.implode(' '.$filtermode.' ', $sqlwhere).')';
438  }
439 
440  if (!empty($sortfield)) {
441  $sql .= $this->db->order($sortfield, $sortorder);
442  }
443  if (!empty($limit)) {
444  $sql .= ' '.$this->db->plimit($limit, $offset);
445  }
446 
447  $resql = $this->db->query($sql);
448  if ($resql) {
449  $num = $this->db->num_rows($resql);
450 
451  while ($obj = $this->db->fetch_object($resql))
452  {
453  $record = new self($this->db);
454  $record->setVarsFromFetchObj($obj);
455 
456  $records[$record->id] = $record;
457  }
458  $this->db->free($resql);
459 
460  return $records;
461  } else {
462  $this->errors[] = 'Error '.$this->db->lasterror();
463  dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
464 
465  return -1;
466  }
467  }
468 
476  public function update(User $user, $notrigger = false)
477  {
478  if ($this->efficiency <= 0 || $this->efficiency > 1) $this->efficiency = 1;
479 
480  return $this->updateCommon($user, $notrigger);
481  }
482 
490  public function delete(User $user, $notrigger = false)
491  {
492  return $this->deleteCommon($user, $notrigger);
493  //return $this->deleteCommon($user, $notrigger, 1);
494  }
495 
504  public function deleteLine(User $user, $idline, $notrigger = false)
505  {
506  if ($this->status < 0)
507  {
508  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
509  return -2;
510  }
511 
512  return $this->deleteLineCommon($user, $idline, $notrigger);
513  }
514 
522  public function getNextNumRef($prod)
523  {
524  global $langs, $conf;
525  $langs->load("mrp");
526 
527  if (!empty($conf->global->BOM_ADDON))
528  {
529  $mybool = false;
530 
531  $file = $conf->global->BOM_ADDON.".php";
532  $classname = $conf->global->BOM_ADDON;
533 
534  // Include file with class
535  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
536  foreach ($dirmodels as $reldir)
537  {
538  $dir = dol_buildpath($reldir."core/modules/bom/");
539 
540  // Load file with numbering class (if found)
541  $mybool |= @include_once $dir.$file;
542  }
543 
544  if ($mybool === false)
545  {
546  dol_print_error('', "Failed to include file ".$file);
547  return '';
548  }
549 
550  $obj = new $classname();
551  $numref = $obj->getNextValue($prod, $this);
552 
553  if ($numref != "")
554  {
555  return $numref;
556  } else {
557  $this->error = $obj->error;
558  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
559  return "";
560  }
561  } else {
562  print $langs->trans("Error")." ".$langs->trans("Error_BOM_ADDON_NotDefined");
563  return "";
564  }
565  }
566 
574  public function validate($user, $notrigger = 0)
575  {
576  global $conf, $langs;
577 
578  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
579 
580  $error = 0;
581 
582  // Protection
583  if ($this->status == self::STATUS_VALIDATED)
584  {
585  dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
586  return 0;
587  }
588 
589  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->bom->create))
590  || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->bom->bom_advance->validate))))
591  {
592  $this->error='NotEnoughPermissions';
593  dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
594  return -1;
595  }*/
596 
597  $now = dol_now();
598 
599  $this->db->begin();
600 
601  // Define new ref
602  if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life
603  {
604  $this->fetch_product();
605  $num = $this->getNextNumRef($this->product);
606  } else {
607  $num = $this->ref;
608  }
609  $this->newref = dol_sanitizeFileName($num);
610 
611  // Validate
612  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
613  $sql .= " SET ref = '".$this->db->escape($num)."',";
614  $sql .= " status = ".self::STATUS_VALIDATED.",";
615  $sql .= " date_valid='".$this->db->idate($now)."',";
616  $sql .= " fk_user_valid = ".$user->id;
617  $sql .= " WHERE rowid = ".$this->id;
618 
619  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
620  $resql = $this->db->query($sql);
621  if (!$resql)
622  {
623  dol_print_error($this->db);
624  $this->error = $this->db->lasterror();
625  $error++;
626  }
627 
628  if (!$error && !$notrigger)
629  {
630  // Call trigger
631  $result = $this->call_trigger('BOM_VALIDATE', $user);
632  if ($result < 0) $error++;
633  // End call triggers
634  }
635 
636  if (!$error)
637  {
638  $this->oldref = $this->ref;
639 
640  // Rename directory if dir was a temporary ref
641  if (preg_match('/^[\(]?PROV/i', $this->ref))
642  {
643  // Now we rename also files into index
644  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'bom/".$this->db->escape($this->newref)."'";
645  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'bom/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
646  $resql = $this->db->query($sql);
647  if (!$resql) { $error++; $this->error = $this->db->lasterror(); }
648 
649  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
650  $oldref = dol_sanitizeFileName($this->ref);
651  $newref = dol_sanitizeFileName($num);
652  $dirsource = $conf->bom->dir_output.'/'.$oldref;
653  $dirdest = $conf->bom->dir_output.'/'.$newref;
654  if (!$error && file_exists($dirsource))
655  {
656  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
657 
658  if (@rename($dirsource, $dirdest))
659  {
660  dol_syslog("Rename ok");
661  // Rename docs starting with $oldref with $newref
662  $listoffiles = dol_dir_list($conf->bom->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
663  foreach ($listoffiles as $fileentry)
664  {
665  $dirsource = $fileentry['name'];
666  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
667  $dirsource = $fileentry['path'].'/'.$dirsource;
668  $dirdest = $fileentry['path'].'/'.$dirdest;
669  @rename($dirsource, $dirdest);
670  }
671  }
672  }
673  }
674  }
675 
676  // Set new ref and current status
677  if (!$error)
678  {
679  $this->ref = $num;
680  $this->status = self::STATUS_VALIDATED;
681  }
682 
683  if (!$error)
684  {
685  $this->db->commit();
686  return 1;
687  } else {
688  $this->db->rollback();
689  return -1;
690  }
691  }
692 
700  public function setDraft($user, $notrigger = 0)
701  {
702  // Protection
703  if ($this->status <= self::STATUS_DRAFT)
704  {
705  return 0;
706  }
707 
708  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->bom->write))
709  || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->bom->bom_advance->validate))))
710  {
711  $this->error='Permission denied';
712  return -1;
713  }*/
714 
715  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'BOM_UNVALIDATE');
716  }
717 
725  public function cancel($user, $notrigger = 0)
726  {
727  // Protection
728  if ($this->status != self::STATUS_VALIDATED)
729  {
730  return 0;
731  }
732 
733  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->bom->write))
734  || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->bom->bom_advance->validate))))
735  {
736  $this->error='Permission denied';
737  return -1;
738  }*/
739 
740  return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'BOM_CLOSE');
741  }
742 
750  public function reopen($user, $notrigger = 0)
751  {
752  // Protection
753  if ($this->status != self::STATUS_CANCELED)
754  {
755  return 0;
756  }
757 
758  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->bom->write))
759  || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->bom->bom_advance->validate))))
760  {
761  $this->error='Permission denied';
762  return -1;
763  }*/
764 
765  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'BOM_REOPEN');
766  }
767 
768 
779  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
780  {
781  global $db, $conf, $langs, $hookmanager;
782 
783  if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips
784 
785  $result = '';
786 
787  $label = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("BillOfMaterials").'</u>';
788  if (isset($this->status)) {
789  $label .= ' '.$this->getLibStatut(5);
790  }
791  $label .= '<br>';
792  $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
793 
794  $url = dol_buildpath('/bom/bom_card.php', 1).'?id='.$this->id;
795 
796  if ($option != 'nolink')
797  {
798  // Add param to save lastsearch_values or not
799  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
800  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1;
801  if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1';
802  }
803 
804  $linkclose = '';
805  if (empty($notooltip))
806  {
807  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
808  {
809  $label = $langs->trans("ShowBillOfMaterials");
810  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
811  }
812  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
813  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
814 
815  /*
816  $hookmanager->initHooks(array('bomdao'));
817  $parameters=array('id'=>$this->id);
818  $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
819  if ($reshook > 0) $linkclose = $hookmanager->resPrint;
820  */
821  } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
822 
823  $linkstart = '<a href="'.$url.'"';
824  $linkstart .= $linkclose.'>';
825  $linkend = '</a>';
826 
827  $result .= $linkstart;
828  if ($withpicto) $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
829  if ($withpicto != 2) $result .= $this->ref;
830  $result .= $linkend;
831  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
832 
833  global $action, $hookmanager;
834  $hookmanager->initHooks(array('bomdao'));
835  $parameters = array('id'=>$this->id, 'getnomurl'=>$result);
836  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
837  if ($reshook > 0) $result = $hookmanager->resPrint;
838  else $result .= $hookmanager->resPrint;
839 
840  return $result;
841  }
842 
849  public function getLibStatut($mode = 0)
850  {
851  return $this->LibStatut($this->status, $mode);
852  }
853 
854  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
862  public function LibStatut($status, $mode = 0)
863  {
864  // phpcs:enable
865  if (empty($this->labelStatus))
866  {
867  global $langs;
868  //$langs->load("mrp");
869  $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
870  $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
871  $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
872  }
873 
874  $statusType = 'status'.$status;
875  if ($status == self::STATUS_VALIDATED) $statusType = 'status4';
876  if ($status == self::STATUS_CANCELED) $statusType = 'status6';
877 
878  return dolGetStatus($this->labelStatus[$status], $this->labelStatus[$status], '', $statusType, $mode);
879  }
880 
887  public function info($id)
888  {
889  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
890  $sql .= ' fk_user_creat, fk_user_modif';
891  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
892  $sql .= ' WHERE t.rowid = '.$id;
893  $result = $this->db->query($sql);
894  if ($result)
895  {
896  if ($this->db->num_rows($result))
897  {
898  $obj = $this->db->fetch_object($result);
899  $this->id = $obj->rowid;
900  if ($obj->fk_user_author)
901  {
902  $cuser = new User($this->db);
903  $cuser->fetch($obj->fk_user_author);
904  $this->user_creation = $cuser;
905  }
906 
907  if ($obj->fk_user_valid)
908  {
909  $vuser = new User($this->db);
910  $vuser->fetch($obj->fk_user_valid);
911  $this->user_validation = $vuser;
912  }
913 
914  if ($obj->fk_user_cloture)
915  {
916  $cluser = new User($this->db);
917  $cluser->fetch($obj->fk_user_cloture);
918  $this->user_cloture = $cluser;
919  }
920 
921  $this->date_creation = $this->db->jdate($obj->datec);
922  $this->date_modification = $this->db->jdate($obj->datem);
923  $this->date_validation = $this->db->jdate($obj->datev);
924  }
925 
926  $this->db->free($result);
927  } else {
928  dol_print_error($this->db);
929  }
930  }
931 
937  public function getLinesArray()
938  {
939  $this->lines = array();
940 
941  $objectline = new BOMLine($this->db);
942  $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_bom = '.$this->id));
943 
944  if (is_numeric($result))
945  {
946  $this->error = $this->error;
947  $this->errors = $this->errors;
948  return $result;
949  } else {
950  $this->lines = $result;
951  return $this->lines;
952  }
953  }
954 
966  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
967  {
968  global $conf, $langs;
969 
970  $langs->load("mrp");
971  $outputlangs->load("products");
972 
973  if (!dol_strlen($modele)) {
974  $modele = 'standard';
975 
976  if ($this->model_pdf) {
977  $modele = $this->model_pdf;
978  } elseif (!empty($conf->global->BOM_ADDON_PDF)) {
979  $modele = $conf->global->BOM_ADDON_PDF;
980  }
981  }
982 
983  $modelpath = "core/modules/bom/doc/";
984 
985  return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
986  }
987 
994  public function initAsSpecimen()
995  {
996  $this->initAsSpecimenCommon();
997  $this->ref = 'BOM-123';
998  $this->date = $this->date_creation;
999  }
1000 
1001 
1008  public function doScheduledJob()
1009  {
1010  global $conf, $langs;
1011 
1012  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1013 
1014  $error = 0;
1015  $this->output = '';
1016  $this->error = '';
1017 
1018  dol_syslog(__METHOD__, LOG_DEBUG);
1019 
1020  $now = dol_now();
1021 
1022  $this->db->begin();
1023 
1024  // ...
1025 
1026  $this->db->commit();
1027 
1028  return $error;
1029  }
1030 
1036  public function calculateCosts()
1037  {
1038  include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1039  $this->unit_cost = 0;
1040  $this->total_cost = 0;
1041 
1042  require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
1043  $productFournisseur = new ProductFournisseur($this->db);
1044 
1045  foreach ($this->lines as &$line) {
1046  $tmpproduct = new Product($this->db);
1047  $result = $tmpproduct->fetch($line->fk_product);
1048  if ($result < 0) {
1049  $this->error = $tmpproduct->error;
1050  return -1;
1051  }
1052  $line->unit_cost = price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp);
1053  if (empty($line->unit_cost)) {
1054  if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0)
1055  {
1056  $line->unit_cost = $productFournisseur->fourn_unitprice;
1057  }
1058  }
1059 
1060  $line->total_cost = price2num($line->qty * $line->unit_cost, 'MT');
1061  $this->total_cost += $line->total_cost;
1062  }
1063 
1064  $this->total_cost = price2num($this->total_cost, 'MT');
1065  if ($this->qty) {
1066  $this->unit_cost = price2num($this->total_cost / $this->qty, 'MU');
1067  }
1068  }
1069 }
1070 
1071 
1076 {
1080  public $element = 'bomline';
1081 
1085  public $table_element = 'bom_bomline';
1086 
1090  public $ismultientitymanaged = 0;
1091 
1095  public $isextrafieldmanaged = 1;
1096 
1100  public $picto = 'bomline';
1101 
1102 
1122  // BEGIN MODULEBUILDER PROPERTIES
1126  public $fields = array(
1127  'rowid' => array('type'=>'integer', 'label'=>'LineID', 'enabled'=>1, 'visible'=>-1, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",),
1128  'fk_bom' => array('type'=>'integer:BillOfMaterials:societe/class/bom.class.php', 'label'=>'BillOfMaterials', 'enabled'=>1, 'visible'=>1, 'position'=>10, 'notnull'=>1, 'index'=>1,),
1129  'fk_product' => array('type'=>'integer:Product:product/class/product.class.php', 'label'=>'Product', 'enabled'=>1, 'visible'=>1, 'position'=>20, 'notnull'=>1, 'index'=>1,),
1130  'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'notnull'=>-1,),
1131  'qty' => array('type'=>'double(24,8)', 'label'=>'Quantity', 'enabled'=>1, 'visible'=>1, 'position'=>100, 'notnull'=>1, 'isameasure'=>'1',),
1132  'qty_frozen' => array('type'=>'smallint', 'label'=>'QuantityFrozen', 'enabled'=>1, 'visible'=>1, 'default'=>0, 'position'=>105, 'css'=>'maxwidth50imp', 'help'=>'QuantityConsumedInvariable'),
1133  'disable_stock_change' => array('type'=>'smallint', 'label'=>'DisableStockChange', 'enabled'=>1, 'visible'=>1, 'default'=>0, 'position'=>108, 'css'=>'maxwidth50imp', 'help'=>'DisableStockChangeHelp'),
1134  'efficiency' => array('type'=>'double(24,8)', 'label'=>'ManufacturingEfficiency', 'enabled'=>1, 'visible'=>0, 'default'=>1, 'position'=>110, 'notnull'=>1, 'css'=>'maxwidth50imp', 'help'=>'ValueOfEfficiencyConsumedMeans'),
1135  'position' => array('type'=>'integer', 'label'=>'Rank', 'enabled'=>1, 'visible'=>0, 'default'=>0, 'position'=>200, 'notnull'=>1,),
1136  'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>1000, 'notnull'=>-1,),
1137  );
1138 
1142  public $rowid;
1143 
1147  public $fk_bom;
1148 
1152  public $fk_product;
1153 
1157  public $description;
1158  public $qty;
1159 
1163  public $qty_frozen;
1164  public $disable_stock_change;
1165  public $efficiency;
1166 
1170  public $position;
1171 
1175  public $import_key;
1176  // END MODULEBUILDER PROPERTIES
1177 
1181  public $total_cost = 0;
1182 
1186  public $unit_cost = 0;
1187 
1188 
1194  public function __construct(DoliDB $db)
1195  {
1196  global $conf, $langs;
1197 
1198  $this->db = $db;
1199 
1200  if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) $this->fields['rowid']['visible'] = 0;
1201  if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) $this->fields['entity']['enabled'] = 0;
1202 
1203  // Unset fields that are disabled
1204  foreach ($this->fields as $key => $val)
1205  {
1206  if (isset($val['enabled']) && empty($val['enabled']))
1207  {
1208  unset($this->fields[$key]);
1209  }
1210  }
1211 
1212  // Translate some data of arrayofkeyval
1213  foreach ($this->fields as $key => $val)
1214  {
1215  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval']))
1216  {
1217  foreach ($val['arrayofkeyval'] as $key2 => $val2)
1218  {
1219  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
1220  }
1221  }
1222  }
1223  }
1224 
1232  public function create(User $user, $notrigger = false)
1233  {
1234  if ($this->efficiency < 0 || $this->efficiency > 1) $this->efficiency = 1;
1235 
1236  return $this->createCommon($user, $notrigger);
1237  }
1238 
1246  public function fetch($id, $ref = null)
1247  {
1248  $result = $this->fetchCommon($id, $ref);
1249  //if ($result > 0 && ! empty($this->table_element_line)) $this->fetchLines();
1250  return $result;
1251  }
1252 
1264  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
1265  {
1266  global $conf;
1267 
1268  dol_syslog(__METHOD__, LOG_DEBUG);
1269 
1270  $records = array();
1271 
1272  $sql = 'SELECT ';
1273  $sql .= $this->getFieldList();
1274  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
1275  if ($this->ismultientitymanaged) $sql .= ' WHERE t.entity IN ('.getEntity($this->table_element).')';
1276  else $sql .= ' WHERE 1 = 1';
1277  // Manage filter
1278  $sqlwhere = array();
1279  if (count($filter) > 0) {
1280  foreach ($filter as $key => $value) {
1281  if ($key == 't.rowid') {
1282  $sqlwhere[] = $key.'='.$value;
1283  } elseif (strpos($key, 'date') !== false) {
1284  $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\'';
1285  } elseif ($key == 'customsql') {
1286  $sqlwhere[] = $value;
1287  } else {
1288  $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\'';
1289  }
1290  }
1291  }
1292  if (count($sqlwhere) > 0) {
1293  $sql .= ' AND ('.implode(' '.$filtermode.' ', $sqlwhere).')';
1294  }
1295 
1296  if (!empty($sortfield)) {
1297  $sql .= $this->db->order($sortfield, $sortorder);
1298  }
1299  if (!empty($limit)) {
1300  $sql .= ' '.$this->db->plimit($limit, $offset);
1301  }
1302 
1303  $resql = $this->db->query($sql);
1304  if ($resql) {
1305  $num = $this->db->num_rows($resql);
1306 
1307  while ($obj = $this->db->fetch_object($resql))
1308  {
1309  $record = new self($this->db);
1310  $record->setVarsFromFetchObj($obj);
1311 
1312  $records[$record->id] = $record;
1313  }
1314  $this->db->free($resql);
1315 
1316  return $records;
1317  } else {
1318  $this->errors[] = 'Error '.$this->db->lasterror();
1319  dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
1320 
1321  return -1;
1322  }
1323  }
1324 
1332  public function update(User $user, $notrigger = false)
1333  {
1334  if ($this->efficiency < 0 || $this->efficiency > 1) $this->efficiency = 1;
1335 
1336  return $this->updateCommon($user, $notrigger);
1337  }
1338 
1346  public function delete(User $user, $notrigger = false)
1347  {
1348  return $this->deleteCommon($user, $notrigger);
1349  //return $this->deleteCommon($user, $notrigger, 1);
1350  }
1351 
1362  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
1363  {
1364  global $db, $conf, $langs, $hookmanager;
1365 
1366  if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips
1367 
1368  $result = '';
1369 
1370  $label = '<u>'.$langs->trans("BillOfMaterialsLine").'</u>';
1371  $label .= '<br>';
1372  $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
1373 
1374  $url = dol_buildpath('/bom/bomline_card.php', 1).'?id='.$this->id;
1375 
1376  if ($option != 'nolink')
1377  {
1378  // Add param to save lastsearch_values or not
1379  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1380  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1;
1381  if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1';
1382  }
1383 
1384  $linkclose = '';
1385  if (empty($notooltip))
1386  {
1387  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
1388  {
1389  $label = $langs->trans("ShowBillOfMaterialsLine");
1390  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1391  }
1392  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
1393  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
1394 
1395  /*
1396  $hookmanager->initHooks(array('bomlinedao'));
1397  $parameters=array('id'=>$this->id);
1398  $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
1399  if ($reshook > 0) $linkclose = $hookmanager->resPrint;
1400  */
1401  } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1402 
1403  $linkstart = '<a href="'.$url.'"';
1404  $linkstart .= $linkclose.'>';
1405  $linkend = '</a>';
1406 
1407  $result .= $linkstart;
1408  if ($withpicto) $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
1409  if ($withpicto != 2) $result .= $this->ref;
1410  $result .= $linkend;
1411  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
1412 
1413  global $action, $hookmanager;
1414  $hookmanager->initHooks(array('bomlinedao'));
1415  $parameters = array('id'=>$this->id, 'getnomurl'=>$result);
1416  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1417  if ($reshook > 0) $result = $hookmanager->resPrint;
1418  else $result .= $hookmanager->resPrint;
1419 
1420  return $result;
1421  }
1422 
1429  public function getLibStatut($mode = 0)
1430  {
1431  return $this->LibStatut($this->status, $mode);
1432  }
1433 
1434  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1442  public function LibStatut($status, $mode = 0)
1443  {
1444  // phpcs:enable
1445  return '';
1446  }
1447 
1454  public function info($id)
1455  {
1456  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
1457  $sql .= ' fk_user_creat, fk_user_modif';
1458  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
1459  $sql .= ' WHERE t.rowid = '.$id;
1460  $result = $this->db->query($sql);
1461  if ($result)
1462  {
1463  if ($this->db->num_rows($result))
1464  {
1465  $obj = $this->db->fetch_object($result);
1466  $this->id = $obj->rowid;
1467  if ($obj->fk_user_author)
1468  {
1469  $cuser = new User($this->db);
1470  $cuser->fetch($obj->fk_user_author);
1471  $this->user_creation = $cuser;
1472  }
1473 
1474  if ($obj->fk_user_valid)
1475  {
1476  $vuser = new User($this->db);
1477  $vuser->fetch($obj->fk_user_valid);
1478  $this->user_validation = $vuser;
1479  }
1480 
1481  if ($obj->fk_user_cloture)
1482  {
1483  $cluser = new User($this->db);
1484  $cluser->fetch($obj->fk_user_cloture);
1485  $this->user_cloture = $cluser;
1486  }
1487 
1488  $this->date_creation = $this->db->jdate($obj->datec);
1489  $this->date_modification = $this->db->jdate($obj->datem);
1490  $this->date_validation = $this->db->jdate($obj->datev);
1491  }
1492 
1493  $this->db->free($result);
1494  } else {
1495  dol_print_error($this->db);
1496  }
1497  }
1498 
1505  public function initAsSpecimen()
1506  {
1507  $this->initAsSpecimenCommon();
1508  }
1509 }
create(User $user, $notrigger=false)
Create object into database.
Definition: bom.class.php:265
deleteCommon(User $user, $notrigger=false, $forcechilddeletion=0)
Delete object in database.
getLibStatut($mode=0)
Return label of the status.
Definition: bom.class.php:849
fetch($id, $ref=null)
Load object in memory from the database.
Definition: bom.class.php:1246
calculateCosts()
BOM costs calculation based on cost_price or pmp of each BOM line.
Definition: bom.class.php:1036
getNextNumRef($prod)
Returns the reference to the following non used BOM depending on the active numbering module defined ...
Definition: bom.class.php:522
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
Definition: bom.class.php:994
fetchLinesCommon($morewhere= '')
Load object in memory from the database.
foreach($object->fields as $key=> $val) if(is_array($extrafields->attributes[$object->table_element]['label'])&&count($extrafields->attributes[$object->table_element]['label']) > 0) $object fields
Class for BOM.
Definition: bom.class.php:32
Class to manage products or services.
dol_now($mode= 'auto')
Return date for now.
createFromClone(User $user, $fromid)
Clone an object into another one.
Definition: bom.class.php:279
reopen($user, $notrigger=0)
Set cancel status.
Definition: bom.class.php:750
Class to manage Dolibarr users.
Definition: user.class.php:44
cancel($user, $notrigger=0)
Set cancel status.
Definition: bom.class.php:725
__construct(DoliDB $db)
Constructor.
Definition: bom.class.php:1194
Class to manage Dolibarr database access.
getLibStatut($mode=0)
Return label of the status.
Definition: bom.class.php:1429
LibStatut($status, $mode=0)
Return the status.
Definition: bom.class.php:1442
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
createCommon(User $user, $notrigger=false)
Create object into database.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
Definition: bom.class.php:1505
fetchAll($sortorder= '', $sortfield= '', $limit=0, $offset=0, array $filter=array(), $filtermode= 'AND')
Load list of objects in memory from the database.
Definition: bom.class.php:408
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
$conf db
API class for accounts.
Definition: inc.php:54
__construct(DoliDB $db)
Constructor.
Definition: bom.class.php:227
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
validate($user, $notrigger=0)
Validate bom.
Definition: bom.class.php:574
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
Definition: bom.class.php:1008
Class for BOMLine.
Definition: bom.class.php:1075
create(User $user, $notrigger=false)
Create object into database.
Definition: bom.class.php:1232
update(User $user, $notrigger=false)
Update object into database.
Definition: bom.class.php:1332
dol_strlen($string, $stringencoding= 'UTF-8')
Make a strlen call.
price2num($amount, $rounding= '', $option=0)
Function that return a number with universal decimal format (decimal separator is &#39;...
update(User $user, $notrigger=false)
Update object into database.
Definition: bom.class.php:476
setDraft($user, $notrigger=0)
Set draft status.
Definition: bom.class.php:700
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt= '', $morecss= '', $marginleftonlyshort=2)
Show picto whatever it&#39;s its name (generic function)
info($id)
Load the info information in the object.
Definition: bom.class.php:1454
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
LibStatut($status, $mode=0)
Return the status.
Definition: bom.class.php:862
img_object($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
updateCommon(User $user, $notrigger=false)
Update object into database.
dol_sanitizeFileName($str, $newstr= '_', $unaccent=1)
Clean a string to use it as a file name.
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:60
getNomUrl($withpicto=0, $option= '', $notooltip=0, $morecss= '', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
Definition: bom.class.php:1362
fetchLines()
Load object lines in memory from the database.
Definition: bom.class.php:389
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
Definition: bom.class.php:966
info($id)
Load the info information in the object.
Definition: bom.class.php:887
print $_SERVER["PHP_SELF"]
Edit parameters.
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
copy_linked_contact($objFrom, $source= 'internal')
Copy contact from one element to current.
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
Definition: bom.class.php:504
print
Draft customers invoices.
Definition: index.php:89
call_trigger($triggerName, $user)
Call trigger based on this instance.
fetch($id, $ref=null)
Load object in memory from the database.
Definition: bom.class.php:374
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->don->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1232
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getLinesArray()
Create an array of lines.
Definition: bom.class.php:937
setStatusCommon($user, $status, $notrigger=0, $triggercode= '')
Set to a status.
getFieldList()
Function to concat keys of fields.
getNomUrl($withpicto=0, $option= '', $notooltip=0, $morecss= '', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
Definition: bom.class.php:779
dolGetStatus($statusLabel= '', $statusLabelShort= '', $html= '', $statusType= 'status0', $displayMode=0, $url= '', $params=array())
Output the badge of a status.
fetch_product()
Load the product with id $this-&gt;fk_product into this-&gt;product.
fetchAll($sortorder= '', $sortfield= '', $limit=0, $offset=0, array $filter=array(), $filtermode= 'AND')
Load list of objects in memory from the database.
Definition: bom.class.php:1264
Parent class of all other business classes (invoices, contracts, proposals, orders, ...)
Class to manage predefined suppliers products.
fetchCommon($id, $ref=null, $morewhere= '')
Load object in memory from the database.