25 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
26 require_once DOL_DOCUMENT_ROOT.
'/workstation/class/workstation.class.php';
27 require_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
40 public $element =
'bom';
45 public $table_element =
'bom_bom';
50 public $ismultientitymanaged = 1;
55 public $isextrafieldmanaged = 1;
60 public $picto =
'bom';
63 const STATUS_DRAFT = 0;
64 const STATUS_VALIDATED = 1;
65 const STATUS_CANCELED = 9;
98 public $fields = array(
99 'rowid' => array(
'type'=>
'integer',
'label'=>
'TechnicalID',
'enabled'=>1,
'visible'=>-2,
'position'=>1,
'notnull'=>1,
'index'=>1,
'comment'=>
"Id",),
100 'entity' => array(
'type'=>
'integer',
'label'=>
'Entity',
'enabled'=>1,
'visible'=>0,
'notnull'=> 1,
'default'=>1,
'index'=>1,
'position'=>5),
101 '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',
'csslist'=>
'nowraponall'),
102 'label' => array(
'type'=>
'varchar(255)',
'label'=>
'Label',
'enabled'=>1,
'visible'=>1,
'position'=>30,
'notnull'=>1,
'searchall'=>1,
'showoncombobox'=>
'2',
'autofocusoncreate'=>1,
'css'=>
'minwidth300 maxwidth400',
'csslist'=>
'tdoverflowmax200'),
103 'bomtype' => array(
'type'=>
'integer',
'label'=>
'Type',
'enabled'=>1,
'visible'=>1,
'position'=>33,
'notnull'=>1,
'default'=>
'0',
'arrayofkeyval'=>array(0=>
'Manufacturing', 1=>
'Disassemble'),
'css'=>
'minwidth175',
'csslist'=>
'minwidth175 center'),
105 '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',
'csslist'=>
'tdoverflowmax100'),
106 'description' => array(
'type'=>
'text',
'label'=>
'Description',
'enabled'=>1,
'visible'=>-1,
'position'=>60,
'notnull'=>-1,),
107 'qty' => array(
'type'=>
'real',
'label'=>
'Quantity',
'enabled'=>1,
'visible'=>1,
'default'=>1,
'position'=>55,
'notnull'=>1,
'isameasure'=>
'1',
'css'=>
'maxwidth75imp'),
109 'duration' => array(
'type'=>
'duration',
'label'=>
'EstimatedDuration',
'enabled'=>1,
'visible'=>-1,
'position'=>101,
'notnull'=>-1,
'css'=>
'maxwidth50imp',
'help'=>
'EstimatedDurationDesc'),
110 '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',
'csslist'=>
'tdoverflowmax100'),
111 'note_public' => array(
'type'=>
'html',
'label'=>
'NotePublic',
'enabled'=>1,
'visible'=>-2,
'position'=>161,
'notnull'=>-1,),
112 'note_private' => array(
'type'=>
'html',
'label'=>
'NotePrivate',
'enabled'=>1,
'visible'=>-2,
'position'=>162,
'notnull'=>-1,),
113 'date_creation' => array(
'type'=>
'datetime',
'label'=>
'DateCreation',
'enabled'=>1,
'visible'=>-2,
'position'=>300,
'notnull'=>1,),
114 'tms' => array(
'type'=>
'timestamp',
'label'=>
'DateModification',
'enabled'=>1,
'visible'=>-2,
'position'=>501,
'notnull'=>1,),
115 'date_valid' => array(
'type'=>
'datetime',
'label'=>
'DateValidation',
'enabled'=>1,
'visible'=>-2,
'position'=>502,
'notnull'=>0,),
116 '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',
'csslist'=>
'tdoverflowmax100'),
117 'fk_user_modif' => array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserModif',
'picto'=>
'user',
'enabled'=>1,
'visible'=>-2,
'position'=>511,
'notnull'=>-1,
'csslist'=>
'tdoverflowmax100'),
118 'fk_user_valid' => array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserValidation',
'picto'=>
'user',
'enabled'=>1,
'visible'=>-2,
'position'=>512,
'notnull'=>0,
'csslist'=>
'tdoverflowmax100'),
119 'import_key' => array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>-2,
'position'=>1000,
'notnull'=>-1,),
120 'model_pdf' =>array(
'type'=>
'varchar(255)',
'label'=>
'Model pdf',
'enabled'=>1,
'visible'=>0,
'position'=>1010),
121 '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')),
152 public $date_creation;
160 public $fk_user_creat;
165 public $fk_user_modif;
191 public $table_element_line =
'bom_bomline';
196 public $fk_element =
'fk_bom';
201 public $class_element_line =
'BOMLine';
211 protected $childtablesoncascade = array(
'bom_bomline');
216 public $lines = array();
221 public $total_cost = 0;
226 public $unit_cost = 0;
237 global $conf, $langs;
241 if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields[
'rowid'])) {
242 $this->fields[
'rowid'][
'visible'] = 0;
244 if (!
isModEnabled(
'multicompany') && isset($this->fields[
'entity'])) {
245 $this->fields[
'entity'][
'enabled'] = 0;
249 foreach ($this->fields as $key => $val) {
250 if (isset($val[
'enabled']) && empty($val[
'enabled'])) {
251 unset($this->fields[$key]);
256 foreach ($this->fields as $key => $val) {
257 if (!empty($val[
'arrayofkeyval']) && is_array($val[
'arrayofkeyval'])) {
258 foreach ($val[
'arrayofkeyval'] as $key2 => $val2) {
259 $this->fields[$key][
'arrayofkeyval'][$key2] = $langs->trans($val2);
274 if ($this->efficiency <= 0 || $this->efficiency > 1) {
275 $this->efficiency = 1;
290 global $langs, $hookmanager, $extrafields;
295 $object =
new self($this->db);
300 $result = $object->fetchCommon($fromid);
301 if ($result > 0 && !empty($object->table_element_line)) {
302 $object->fetchLines();
311 unset($object->fk_user_creat);
312 unset($object->import_key);
315 $object->ref = empty($this->fields[
'ref'][
'default']) ? $langs->trans(
"copy_of_").$object->ref : $this->fields[
'ref'][
'default'];
316 $object->label = empty($this->fields[
'label'][
'default']) ? $langs->trans(
"CopyOf").
" ".$object->label : $this->fields[
'label'][
'default'];
317 $object->status = self::STATUS_DRAFT;
320 if (is_array($object->array_options) && count($object->array_options) > 0) {
321 $extrafields->fetch_name_optionals_label($object->table_element);
322 foreach ($object->array_options as $key => $option) {
323 $shortkey = preg_replace(
'/options_/',
'', $key);
324 if (!empty($extrafields->attributes[$this->element][
'unique'][$shortkey])) {
326 unset($object->array_options[$key]);
332 $object->context[
'createfromclone'] =
'createfromclone';
333 $result = $object->createCommon($user);
336 $this->error = $object->error;
337 $this->errors = $object->errors;
349 if (property_exists($this,
'socid') && $this->socid == $object->socid) {
360 unset($object->context[
'createfromclone']);
367 $this->
db->rollback();
379 public function fetch($id, $ref =
null)
383 if ($result > 0 && !empty($this->table_element_line)) {
398 $this->lines = array();
413 $this->lines = array();
415 $objectlineclassname = get_class($this).
'Line';
416 if (!class_exists($objectlineclassname)) {
417 $this->error =
'Error, class '.$objectlineclassname.
' not found during call of fetchLinesCommon';
421 $objectline =
new $objectlineclassname($this->
db);
423 $sql =
"SELECT ".$objectline->getFieldList(
'l');
424 $sql .=
" FROM ".$this->db->prefix().$objectline->table_element.
" as l";
425 $sql .=
" LEFT JOIN ".$this->db->prefix().
"product as p ON p.rowid = l.fk_product";
426 $sql .=
" WHERE l.fk_".$this->db->escape($this->element).
" = ".((int) $this->
id);
427 $sql .=
" AND p.fk_product_type = ". ((int) $typeproduct);
428 if (isset($objectline->fields[
'position'])) {
429 $sql .= $this->
db->order(
'position',
'ASC');
434 $num_rows = $this->
db->num_rows(
$resql);
436 while ($i < $num_rows) {
437 $obj = $this->
db->fetch_object(
$resql);
439 $newline =
new $objectlineclassname($this->
db);
440 $newline->setVarsFromFetchObj($obj);
442 $this->lines[] = $newline;
449 $this->error = $this->
db->lasterror();
450 $this->errors[] = $this->error;
467 public function fetchAll($sortorder =
'', $sortfield =
'', $limit = 0, $offset = 0, array $filter = array(), $filtermode =
'AND')
477 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element.
' as t';
478 if ($this->ismultientitymanaged) {
479 $sql .=
' WHERE t.entity IN ('.getEntity($this->table_element).
')';
481 $sql .=
' WHERE 1 = 1';
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;
494 $sqlwhere[] = $key.
" LIKE '%".$this->
db->escape($value).
"%'";
498 if (count($sqlwhere) > 0) {
499 $sql .=
" AND (".implode(
" ".$filtermode.
" ", $sqlwhere).
")";
502 if (!empty($sortfield)) {
503 $sql .= $this->
db->order($sortfield, $sortorder);
505 if (!empty($limit)) {
506 $sql .= $this->
db->plimit($limit, $offset);
513 while ($obj = $this->
db->fetch_object(
$resql)) {
514 $record =
new self($this->db);
515 $record->setVarsFromFetchObj($obj);
517 $records[$record->id] = $record;
523 $this->errors[] =
'Error '.$this->db->lasterror();
524 dol_syslog(__METHOD__.
' '.join(
',', $this->errors), LOG_ERR);
539 if ($this->efficiency <= 0 || $this->efficiency > 1) {
540 $this->efficiency = 1;
553 public function delete(
User $user, $notrigger =
false)
574 public function addLine($fk_product, $qty, $qty_frozen = 0, $disable_stock_change = 0, $efficiency = 1.0, $position = -1, $fk_bom_child =
null, $import_key =
null, $fk_unit =
'', $array_options = 0)
576 global $mysoc, $conf, $langs, $user;
578 $logtext =
"::addLine bomid=$this->id, qty=$qty, fk_product=$fk_product, qty_frozen=$qty_frozen, disable_stock_change=$disable_stock_change, efficiency=$efficiency";
579 $logtext .=
", fk_bom_child=$fk_bom_child, import_key=$import_key";
580 dol_syslog(get_class($this).$logtext, LOG_DEBUG);
582 if ($this->statut == self::STATUS_DRAFT) {
583 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
589 if (empty($qty_frozen)) {
592 if (empty($disable_stock_change)) {
593 $disable_stock_change = 0;
595 if (empty($efficiency)) {
598 if (empty($fk_bom_child)) {
599 $fk_bom_child =
null;
601 if (empty($import_key)) {
604 if (empty($position)) {
616 $rankToUse = $position;
617 if ($rankToUse <= 0 or $rankToUse > $rangMax) {
618 $rankToUse = $rangMax + 1;
620 foreach ($this->lines as $bl) {
621 if ($bl->position >= $rankToUse) {
631 $this->line->context = $this->context;
633 $this->line->fk_bom = $this->id;
634 $this->line->fk_product = $fk_product;
635 $this->line->qty = $qty;
636 $this->line->qty_frozen = $qty_frozen;
637 $this->line->disable_stock_change = $disable_stock_change;
638 $this->line->efficiency = $efficiency;
639 $this->line->fk_bom_child = $fk_bom_child;
640 $this->line->import_key = $import_key;
641 $this->line->position = $rankToUse;
642 $this->line->fk_unit = $fk_unit;
644 if (is_array($array_options) && count($array_options) > 0) {
645 $this->line->array_options = $array_options;
648 $result = $this->line->create($user);
655 $this->error = $this->line->error;
656 dol_syslog(get_class($this).
"::addLine error=".$this->error, LOG_ERR);
657 $this->
db->rollback();
661 dol_syslog(get_class($this).
"::addLine status of BOM must be Draft to allow use of ->addLine()", LOG_ERR);
680 public function updateLine($rowid, $qty, $qty_frozen = 0, $disable_stock_change = 0, $efficiency = 1.0, $position = -1, $import_key =
null, $fk_unit = 0, $array_options = 0)
682 global $mysoc, $conf, $langs, $user;
684 $logtext =
"::updateLine bomid=$this->id, qty=$qty, qty_frozen=$qty_frozen, disable_stock_change=$disable_stock_change, efficiency=$efficiency";
685 $logtext .=
", import_key=$import_key";
686 dol_syslog(get_class($this).$logtext, LOG_DEBUG);
688 if ($this->statut == self::STATUS_DRAFT) {
689 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
695 if (empty($qty_frozen)) {
698 if (empty($disable_stock_change)) {
699 $disable_stock_change = 0;
701 if (empty($efficiency)) {
704 if (empty($import_key)) {
707 if (empty($position)) {
719 $line->fetch($rowid);
720 $line->fetch_optionals();
722 $staticLine = clone $line;
723 $line->oldcopy = $staticLine;
725 $this->line->context = $this->context;
728 $rankToUse = (int) $position;
729 if ($rankToUse != $line->oldcopy->position) {
730 foreach ($this->lines as $bl) {
731 if ($bl->position >= $rankToUse AND $bl->position < ($line->oldcopy->position + 1)) {
735 if ($bl->position <= $rankToUse AND $bl->position > ($line->oldcopy->position)) {
743 $this->line->fk_bom = $this->id;
744 $this->line->qty = $qty;
745 $this->line->qty_frozen = $qty_frozen;
746 $this->line->disable_stock_change = $disable_stock_change;
747 $this->line->efficiency = $efficiency;
748 $this->line->import_key = $import_key;
749 $this->line->position = $rankToUse;
750 if (!empty($fk_unit)) {
751 $this->line->fk_unit = $fk_unit;
754 if (is_array($array_options) && count($array_options) > 0) {
756 foreach ($array_options as $key => $value) {
757 $this->line->array_options[$key] = $array_options[$key];
761 $result = $this->line->update($user);
768 $this->error = $this->line->error;
769 dol_syslog(get_class($this).
"::addLine error=".$this->error, LOG_ERR);
770 $this->
db->rollback();
774 dol_syslog(get_class($this).
"::addLine status of BOM must be Draft to allow use of ->addLine()", LOG_ERR);
789 if ($this->status < 0) {
790 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
798 $line->fetch($idline);
799 $line->fetch_optionals();
801 $staticLine = clone $line;
802 $line->oldcopy = $staticLine;
804 $this->line->context = $this->context;
806 $result = $this->line->delete($user, $notrigger);
809 foreach ($this->lines as $bl) {
810 if ($bl->position > ($line->oldcopy->position)) {
821 $this->error = $this->line->error;
822 dol_syslog(get_class($this).
"::addLine error=".$this->error, LOG_ERR);
823 $this->
db->rollback();
837 global $langs, $conf;
840 if (!empty($conf->global->BOM_ADDON)) {
843 $file = $conf->global->BOM_ADDON.
".php";
844 $classname = $conf->global->BOM_ADDON;
847 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
848 foreach ($dirmodels as $reldir) {
852 $mybool |= @include_once $dir.$file;
855 if ($mybool ===
false) {
860 $obj =
new $classname();
861 $numref = $obj->getNextValue($prod, $this);
866 $this->error = $obj->error;
871 print $langs->trans(
"Error").
" ".$langs->trans(
"Error_BOM_ADDON_NotDefined");
885 global $conf, $langs;
887 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
892 if ($this->status == self::STATUS_VALIDATED) {
893 dol_syslog(get_class($this).
"::validate action abandonned: already validated", LOG_WARNING);
910 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
919 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
920 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
921 $sql .=
" status = ".self::STATUS_VALIDATED.
",";
922 $sql .=
" date_valid='".$this->db->idate($now).
"',";
923 $sql .=
" fk_user_valid = ".((int) $user->id);
924 $sql .=
" WHERE rowid = ".((int) $this->
id);
926 dol_syslog(get_class($this).
"::validate()", LOG_DEBUG);
930 $this->error = $this->
db->lasterror();
934 if (!$error && !$notrigger) {
944 $this->oldref = $this->ref;
947 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
949 $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).
"'";
950 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'bom/".$this->
db->escape($this->
ref).
"' and entity = ".$conf->entity;
953 $error++; $this->error = $this->
db->lasterror();
959 $dirsource = $conf->bom->dir_output.
'/'.$oldref;
960 $dirdest = $conf->bom->dir_output.
'/'.$newref;
961 if (!$error && file_exists($dirsource)) {
962 dol_syslog(get_class($this).
"::validate() rename dir ".$dirsource.
" into ".$dirdest);
964 if (@rename($dirsource, $dirdest)) {
967 $listoffiles =
dol_dir_list($conf->bom->dir_output.
'/'.$newref,
'files', 1,
'^'.preg_quote($oldref,
'/'));
968 foreach ($listoffiles as $fileentry) {
969 $dirsource = $fileentry[
'name'];
970 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
971 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
972 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
973 @rename($dirsource, $dirdest);
983 $this->status = self::STATUS_VALIDATED;
990 $this->
db->rollback();
1005 if ($this->status <= self::STATUS_DRAFT) {
1016 return $this->
setStatusCommon($user, self::STATUS_DRAFT, $notrigger,
'BOM_UNVALIDATE');
1026 public function cancel($user, $notrigger = 0)
1029 if ($this->status != self::STATUS_VALIDATED) {
1040 return $this->
setStatusCommon($user, self::STATUS_CANCELED, $notrigger,
'BOM_CLOSE');
1050 public function reopen($user, $notrigger = 0)
1053 if ($this->status != self::STATUS_CANCELED) {
1064 return $this->
setStatusCommon($user, self::STATUS_VALIDATED, $notrigger,
'BOM_REOPEN');
1078 public function getNomUrl($withpicto = 0, $option =
'', $notooltip = 0, $morecss =
'', $save_lastsearch_value = -1)
1080 global $db, $conf, $langs, $hookmanager;
1082 if (!empty($conf->dol_no_mouse_hover)) {
1088 $label =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"BillOfMaterials").
'</u>';
1089 if (isset($this->status)) {
1090 $label .=
' '.$this->getLibStatut(5);
1093 $label .=
'<b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1094 if (isset($this->label)) {
1095 $label .=
'<br><b>'.$langs->trans(
'Label').
':</b> '.$this->label;
1097 if (!empty($this->fk_product) && $this->fk_product > 0) {
1098 include_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
1100 $resultFetch = $product->fetch($this->fk_product);
1101 if ($resultFetch > 0) {
1102 $label .=
"<br><b>".$langs->trans(
"Product").
'</b>: '.$product->ref.
' - '.$product->label;
1107 $url = DOL_URL_ROOT.
'/bom/bom_card.php?id='.$this->id;
1109 if ($option !=
'nolink') {
1111 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1112 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1113 $add_save_lastsearch_values = 1;
1115 if ($add_save_lastsearch_values) {
1116 $url .=
'&save_lastsearch_values=1';
1121 if (empty($notooltip)) {
1122 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
1123 $label = $langs->trans(
"ShowBillOfMaterials");
1124 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
1126 $linkclose .=
' title="'.dol_escape_htmltag($label, 1).
'"';
1127 $linkclose .=
' class="classfortooltip'.($morecss ?
' '.$morecss :
'').
'"';
1129 $linkclose = ($morecss ?
' class="'.$morecss.
'"' :
'');
1132 $linkstart =
'<a href="'.$url.
'"';
1133 $linkstart .= $linkclose.
'>';
1136 $result .= $linkstart;
1138 $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);
1140 if ($withpicto != 2) {
1141 $result .= $this->ref;
1143 $result .= $linkend;
1146 global $action, $hookmanager;
1147 $hookmanager->initHooks(array(
'bomdao'));
1148 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
1149 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1151 $result = $hookmanager->resPrint;
1153 $result .= $hookmanager->resPrint;
1167 return $this->
LibStatut($this->status, $mode);
1181 if (empty($this->labelStatus)) {
1184 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv(
'Draft');
1185 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv(
'Enabled');
1186 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv(
'Disabled');
1189 $statusType =
'status'.$status;
1190 if ($status == self::STATUS_VALIDATED) {
1191 $statusType =
'status4';
1193 if ($status == self::STATUS_CANCELED) {
1194 $statusType =
'status6';
1197 return dolGetStatus($this->labelStatus[$status], $this->labelStatus[$status],
'', $statusType, $mode);
1208 $sql =
'SELECT rowid, date_creation as datec, tms as datem,';
1209 $sql .=
' fk_user_creat, fk_user_modif';
1210 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element.
' as t';
1211 $sql .=
' WHERE t.rowid = '.((int) $id);
1212 $result = $this->
db->query($sql);
1214 if ($this->
db->num_rows($result)) {
1215 $obj = $this->
db->fetch_object($result);
1216 $this->
id = $obj->rowid;
1218 $this->user_creation_id = $obj->fk_user_creat;
1219 $this->user_modification_id = $obj->fk_user_modif;
1220 $this->date_creation = $this->
db->jdate($obj->datec);
1221 $this->date_modification = empty($obj->datem) ?
'' : $this->
db->jdate($obj->datem);
1224 $this->
db->free($result);
1237 $this->lines = array();
1240 $result = $objectline->fetchAll(
'ASC',
'position', 0, 0, array(
'customsql'=>
'fk_bom = '.((
int) $this->
id)));
1242 if (is_numeric($result)) {
1243 $this->error = $objectline->error;
1244 $this->errors = $objectline->errors;
1247 $this->lines = $result;
1248 return $this->lines;
1263 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
1265 global $conf, $langs;
1267 $langs->load(
"mrp");
1268 $outputlangs->load(
"products");
1271 $modele =
'standard';
1273 if ($this->model_pdf) {
1274 $modele = $this->model_pdf;
1275 } elseif (!empty($conf->global->BOM_ADDON_PDF)) {
1276 $modele = $conf->global->BOM_ADDON_PDF;
1280 $modelpath =
"core/modules/bom/doc/";
1282 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1294 $this->
ref =
'BOM-123';
1295 $this->date = $this->date_creation;
1307 global $conf, $langs;
1323 $this->
db->commit();
1336 global $conf, $hookmanager;
1338 include_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
1339 $this->unit_cost = 0;
1340 $this->total_cost = 0;
1342 $parameters=array();
1343 $reshook = $hookmanager->executeHooks(
'calculateCostsBom', $parameters, $this);
1346 return $hookmanager->resPrint;
1349 if (is_array($this->lines) && count($this->lines)) {
1350 require_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.product.class.php';
1354 foreach ($this->lines as &$line) {
1355 $tmpproduct->cost_price = 0;
1356 $tmpproduct->pmp = 0;
1357 $result = $tmpproduct->fetch($line->fk_product,
'',
'',
'', 0, 1, 1);
1359 if ($tmpproduct->type == $tmpproduct::TYPE_PRODUCT) {
1360 if (empty($line->fk_bom_child)) {
1362 $this->error = $tmpproduct->error;
1365 $line->unit_cost =
price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp);
1366 if (empty($line->unit_cost)) {
1367 if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) {
1368 $line->unit_cost = $productFournisseur->fourn_unitprice;
1372 $line->total_cost =
price2num($line->qty * $line->unit_cost,
'MT');
1374 $this->total_cost += $line->total_cost;
1376 $bom_child =
new BOM($this->
db);
1377 $res = $bom_child->fetch($line->fk_bom_child);
1379 $bom_child->calculateCosts();
1380 $line->childBom[] = $bom_child;
1381 $this->total_cost += $bom_child->total_cost * $line->qty;
1383 $this->error = $bom_child->error;
1392 if (
isModEnabled(
'workstation') && !empty($tmpproduct->fk_default_workstation)) {
1394 $res = $workstation->fetch($tmpproduct->fk_default_workstation);
1396 if ($res > 0) $line->total_cost =
price2num($qty * ($workstation->thm_operator_estimated + $workstation->thm_machine_estimated),
'MT');
1398 $this->error = $workstation->error;
1402 $line->total_cost =
price2num($qty * $tmpproduct->cost_price,
'MT');
1405 $this->total_cost += $line->total_cost;
1409 $this->total_cost =
price2num($this->total_cost,
'MT');
1411 if ($this->qty > 0) {
1412 $this->unit_cost =
price2num($this->total_cost / $this->qty,
'MU');
1413 } elseif ($this->qty < 0) {
1414 $this->unit_cost =
price2num($this->total_cost * $this->qty,
'MU');
1447 if (!empty($this->lines)) {
1448 foreach ($this->lines as $line) {
1449 if (!empty($line->childBom)) {
1450 foreach ($line->childBom as $childBom) $childBom->getNetNeeds($TNetNeeds, $line->qty*$qty);
1452 if (empty($TNetNeeds[$line->fk_product])) {
1453 $TNetNeeds[$line->fk_product] = 0;
1455 $TNetNeeds[$line->fk_product] += $line->qty*$qty;
1471 if (!empty($this->lines)) {
1472 foreach ($this->lines as $line) {
1473 if (!empty($line->childBom)) {
1474 foreach ($line->childBom as $childBom) {
1475 $TNetNeeds[$childBom->id][
'bom'] = $childBom;
1476 $TNetNeeds[$childBom->id][
'parentid'] = $this->id;
1477 $TNetNeeds[$childBom->id][
'qty'] = $line->qty*$qty;
1478 $TNetNeeds[$childBom->id][
'level'] = $level;
1479 $childBom->getNetNeedsTree($TNetNeeds, $line->qty*$qty, $level+1);
1482 $TNetNeeds[$this->id][
'product'][$line->fk_product][
'qty'] += $line->qty * $qty;
1483 $TNetNeeds[$this->id][
'product'][$line->fk_product][
'level'] = $level;
1501 if ($level > 1000) {
1505 if (empty($bom_id)) $bom_id=$this->id;
1507 $sql =
'SELECT l.fk_bom, b.label
1508 FROM '.MAIN_DB_PREFIX.
'bom_bomline l
1509 INNER JOIN '.MAIN_DB_PREFIX.$this->table_element.
' b ON b.rowid = l.fk_bom
1510 WHERE fk_bom_child = '.((int) $bom_id);
1514 while ($res = $this->
db->fetch_object(
$resql)) {
1515 $TParentBom[$res->fk_bom] = $res->fk_bom;
1531 $prod->fetch($this->fk_product);
1533 $return =
'<div class="box-flex-item box-flex-grow-zero">';
1534 $return .=
'<div class="info-box info-box-sm">';
1535 $return .=
'<span class="info-box-icon bg-infobox-action">';
1537 $return .=
'</span>';
1538 $return .=
'<div class="info-box-content">';
1539 $return .=
'<span class="info-box-ref">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl() :
'').
'</span>';
1540 if (property_exists($this,
'fields') && !empty($this->fields[
'bomtype'][
'arrayofkeyval'])) {
1541 $return .=
'<br><span class="info-box-label opacitymedium">'.$langs->trans(
"Type").
' : </span>';
1542 if ($this->bomtype == 0) {
1543 $return .=
'<span class="info-box-label">'.$this->fields[
'bomtype'][
'arrayofkeyval'][0].
'</span>';
1545 $return .=
'<span class="info-box-label">'.$this->fields[
'bomtype'][
'arrayofkeyval'][1].
'</span>';
1548 if (property_exists($this,
'fk_product') && !is_null($this->fk_product)) {
1549 $return .=
'<br><span class="info-box-label">'.$prod->getNomUrl(1).
'</span>';
1551 if (method_exists($this,
'getLibStatut')) {
1552 $return .=
'<br><div class="info-box-status margintoponly">'.$this->getLibStatut(5).
'</div>';
1555 $return .=
'</div>';
1556 $return .=
'</div>';
1557 $return .=
'</div>';
1571 public $element =
'bomline';
1576 public $table_element =
'bom_bomline';
1581 public $ismultientitymanaged = 0;
1586 public $isextrafieldmanaged = 1;
1591 public $picto =
'bomline';
1617 public $fields = array(
1618 'rowid' => array(
'type'=>
'integer',
'label'=>
'LineID',
'enabled'=>1,
'visible'=>-1,
'position'=>1,
'notnull'=>1,
'index'=>1,
'comment'=>
"Id",),
1619 'fk_bom' => array(
'type'=>
'integer:BillOfMaterials:societe/class/bom.class.php',
'label'=>
'BillOfMaterials',
'enabled'=>1,
'visible'=>1,
'position'=>10,
'notnull'=>1,
'index'=>1,),
1620 'fk_product' => array(
'type'=>
'integer:Product:product/class/product.class.php',
'label'=>
'Product',
'enabled'=>1,
'visible'=>1,
'position'=>20,
'notnull'=>1,
'index'=>1,),
1621 'fk_bom_child' => array(
'type'=>
'integer:BOM:bom/class/bom.class.php',
'label'=>
'BillOfMaterials',
'enabled'=>1,
'visible'=>-1,
'position'=>40,
'notnull'=>-1,),
1622 'description' => array(
'type'=>
'text',
'label'=>
'Description',
'enabled'=>1,
'visible'=>-1,
'position'=>60,
'notnull'=>-1,),
1623 'qty' => array(
'type'=>
'double(24,8)',
'label'=>
'Quantity',
'enabled'=>1,
'visible'=>1,
'position'=>100,
'notnull'=>1,
'isameasure'=>
'1',),
1624 'qty_frozen' => array(
'type'=>
'smallint',
'label'=>
'QuantityFrozen',
'enabled'=>1,
'visible'=>1,
'default'=>0,
'position'=>105,
'css'=>
'maxwidth50imp',
'help'=>
'QuantityConsumedInvariable'),
1625 'disable_stock_change' => array(
'type'=>
'smallint',
'label'=>
'DisableStockChange',
'enabled'=>1,
'visible'=>1,
'default'=>0,
'position'=>108,
'css'=>
'maxwidth50imp',
'help'=>
'DisableStockChangeHelp'),
1626 'efficiency' => array(
'type'=>
'double(24,8)',
'label'=>
'ManufacturingEfficiency',
'enabled'=>1,
'visible'=>0,
'default'=>1,
'position'=>110,
'notnull'=>1,
'css'=>
'maxwidth50imp',
'help'=>
'ValueOfEfficiencyConsumedMeans'),
1627 'fk_unit' => array(
'type'=>
'integer',
'label'=>
'Unit',
'enabled'=>1,
'visible'=>1,
'position'=>120,
'notnull'=>-1,),
1628 'position' => array(
'type'=>
'integer',
'label'=>
'Rank',
'enabled'=>1,
'visible'=>0,
'default'=>0,
'position'=>200,
'notnull'=>1,),
1629 'import_key' => array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>-2,
'position'=>1000,
'notnull'=>-1,),
1650 public $fk_bom_child;
1655 public $description;
1662 public $disable_stock_change;
1679 public $total_cost = 0;
1684 public $unit_cost = 0;
1690 public $childBom = array();
1700 global $conf, $langs;
1704 if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields[
'rowid'])) {
1705 $this->fields[
'rowid'][
'visible'] = 0;
1707 if (!
isModEnabled(
'multicompany') && isset($this->fields[
'entity'])) {
1708 $this->fields[
'entity'][
'enabled'] = 0;
1712 foreach ($this->fields as $key => $val) {
1713 if (isset($val[
'enabled']) && empty($val[
'enabled'])) {
1714 unset($this->fields[$key]);
1719 foreach ($this->fields as $key => $val) {
1720 if (!empty($val[
'arrayofkeyval']) && is_array($val[
'arrayofkeyval'])) {
1721 foreach ($val[
'arrayofkeyval'] as $key2 => $val2) {
1722 $this->fields[$key][
'arrayofkeyval'][$key2] = $langs->trans($val2);
1737 if ($this->efficiency < 0 || $this->efficiency > 1) {
1738 $this->efficiency = 1;
1769 public function fetchAll($sortorder =
'', $sortfield =
'', $limit = 0, $offset = 0, array $filter = array(), $filtermode =
'AND')
1779 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element.
' as t';
1780 if ($this->ismultientitymanaged) {
1781 $sql .=
' WHERE t.entity IN ('.getEntity($this->table_element).
')';
1783 $sql .=
' WHERE 1 = 1';
1786 $sqlwhere = array();
1787 if (count($filter) > 0) {
1788 foreach ($filter as $key => $value) {
1789 if ($key ==
't.rowid') {
1790 $sqlwhere[] = $key.
" = ".((int) $value);
1791 } elseif (strpos($key,
'date') !==
false) {
1792 $sqlwhere[] = $key.
" = '".$this->
db->idate($value).
"'";
1793 } elseif ($key ==
'customsql') {
1794 $sqlwhere[] = $value;
1796 $sqlwhere[] = $key.
" LIKE '%".$this->
db->escape($value).
"%'";
1800 if (count($sqlwhere) > 0) {
1801 $sql .=
' AND ('.implode(
' '.$this->
db->escape($filtermode).
' ', $sqlwhere).
')';
1804 if (!empty($sortfield)) {
1805 $sql .= $this->
db->order($sortfield, $sortorder);
1807 if (!empty($limit)) {
1808 $sql .= $this->
db->plimit($limit, $offset);
1813 $num = $this->
db->num_rows(
$resql);
1815 while ($obj = $this->
db->fetch_object(
$resql)) {
1816 $record =
new self($this->db);
1817 $record->setVarsFromFetchObj($obj);
1819 $records[$record->id] = $record;
1825 $this->errors[] =
'Error '.$this->db->lasterror();
1826 dol_syslog(__METHOD__.
' '.join(
',', $this->errors), LOG_ERR);
1841 if ($this->efficiency < 0 || $this->efficiency > 1) {
1842 $this->efficiency = 1;
1855 public function delete(
User $user, $notrigger =
false)
1871 public function getNomUrl($withpicto = 0, $option =
'', $notooltip = 0, $morecss =
'', $save_lastsearch_value = -1)
1873 global $db, $conf, $langs, $hookmanager;
1875 if (!empty($conf->dol_no_mouse_hover)) {
1881 $label =
'<u>'.$langs->trans(
"BillOfMaterialsLine").
'</u>';
1883 $label .=
'<b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1885 $url = DOL_URL_ROOT.
'/bom/bomline_card.php?id='.$this->id;
1887 if ($option !=
'nolink') {
1889 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1890 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1891 $add_save_lastsearch_values = 1;
1893 if ($add_save_lastsearch_values) {
1894 $url .=
'&save_lastsearch_values=1';
1899 if (empty($notooltip)) {
1900 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
1901 $label = $langs->trans(
"ShowBillOfMaterialsLine");
1902 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
1904 $linkclose .=
' title="'.dol_escape_htmltag($label, 1).
'"';
1905 $linkclose .=
' class="classfortooltip'.($morecss ?
' '.$morecss :
'').
'"';
1907 $linkclose = ($morecss ?
' class="'.$morecss.
'"' :
'');
1910 $linkstart =
'<a href="'.$url.
'"';
1911 $linkstart .= $linkclose.
'>';
1914 $result .= $linkstart;
1916 $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);
1918 if ($withpicto != 2) {
1919 $result .= $this->ref;
1921 $result .= $linkend;
1924 global $action, $hookmanager;
1925 $hookmanager->initHooks(array(
'bomlinedao'));
1926 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
1927 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1929 $result = $hookmanager->resPrint;
1931 $result .= $hookmanager->resPrint;
1945 return $this->
LibStatut($this->status, $mode);
1970 $sql =
'SELECT rowid, date_creation as datec, tms as datem,';
1971 $sql .=
' fk_user_creat, fk_user_modif';
1972 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element.
' as t';
1973 $sql .=
' WHERE t.rowid = '.((int) $id);
1974 $result = $this->
db->query($sql);
1976 if ($this->
db->num_rows($result)) {
1977 $obj = $this->
db->fetch_object($result);
1978 $this->
id = $obj->rowid;
1979 $this->user_creation_id = $obj->fk_user_creat;
1980 $this->user_modification_id = $obj->fk_user_modif;
1981 $this->date_creation = $this->
db->jdate($obj->datec);
1982 $this->date_modification = empty($obj->datem) ?
'' : $this->
db->jdate($obj->datem);
1984 $this->
db->free($result);
getKanbanView($option='')
Return clicable link of object (with eventually picto)
static replaceProduct(DoliDB $db, $origin_id, $dest_id)
Function used to replace a product id with another one.
fetchLines()
Load object lines in memory from the database.
__construct(DoliDB $db)
Constructor.
calculateCosts()
BOM costs calculation based on cost_price or pmp of each BOM line.
info($id)
Load the info information in the object.
getLibStatut($mode=0)
Return label of the status.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
validate($user, $notrigger=0)
Validate bom.
reopen($user, $notrigger=0)
Set cancel status.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter=array(), $filtermode='AND')
Load list of objects in memory from the database.
addLine($fk_product, $qty, $qty_frozen=0, $disable_stock_change=0, $efficiency=1.0, $position=-1, $fk_bom_child=null, $import_key=null, $fk_unit='', $array_options=0)
Add an BOM line into database (linked to BOM)
cancel($user, $notrigger=0)
Set cancel status.
create(User $user, $notrigger=false)
Create object into database.
LibStatut($status, $mode=0)
Return the status.
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
fetchLinesbytypeproduct($typeproduct=0)
Load object lines in memory from the database by type of product.
createFromClone(User $user, $fromid)
Clone an object into another one.
fetch($id, $ref=null)
Load object in memory from the database.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
getNetNeeds(&$TNetNeeds=array(), $qty=0)
Get Net needs by product.
getNextNumRef($prod)
Returns the reference to the following non used BOM depending on the active numbering module defined ...
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
getLinesArray()
Create an array of lines.
setDraft($user, $notrigger=0)
Set draft status.
updateLine($rowid, $qty, $qty_frozen=0, $disable_stock_change=0, $efficiency=1.0, $position=-1, $import_key=null, $fk_unit=0, $array_options=0)
Update an BOM line into database.
update(User $user, $notrigger=false)
Update object into database.
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
getParentBomTreeRecursive(&$TParentBom, $bom_id='', $level=1)
Recursively retrieves all parent bom in the tree that leads to the $bom_id bom.
getNetNeedsTree(&$TNetNeeds=array(), $qty=0, $level=0)
Get Net needs Tree by product or bom.
create(User $user, $notrigger=false)
Create object into database.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter=array(), $filtermode='AND')
Load list of objects in memory from the database.
fetch($id, $ref=null)
Load object in memory from the database.
getLibStatut($mode=0)
Return label of the status.
update(User $user, $notrigger=false)
Update object into database.
__construct(DoliDB $db)
Constructor.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
info($id)
Load the info information in the object.
LibStatut($status, $mode=0)
Return the status.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
getFieldList($alias='')
Function to concat keys of fields.
fetchCommon($id, $ref=null, $morewhere='')
Load object in memory from the database.
createCommon(User $user, $notrigger=false)
Create object into database.
deleteCommon(User $user, $notrigger=false, $forcechilddeletion=0)
Delete object in database.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
fetch_product()
Load the product with id $this->fk_product into this->product.
updateCommon(User $user, $notrigger=false)
Update object into database.
static commonReplaceProduct(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a product id with another one.
line_max($fk_parent_line=0)
Get max value used for position of line (rang)
fetchLinesCommon($morewhere='')
Load object in memory from the database.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Dolibarr database access.
Class to manage predefined suppliers products.
Class to manage products or services.
Class to manage Dolibarr users.
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') &&!empty($user->rights->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)) $resql
Social contributions to pay.
convertDurationtoHour($duration_value, $duration_unit)
Convert duration to hour.
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.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_now($mode='auto')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
measuringUnitString($unit, $measuring_style='', $scale='', $use_short_label=0, $outputlangs=null)
Return translation label of a unit key.
$conf db
API class for accounts.