73 public $errors = array();
83 public $table_element;
88 public $table_element_line =
'';
98 public $array_options = array();
103 public $array_languages = null;
108 public $linkedObjectsIds;
113 public $linkedObjects;
123 protected $table_ref_field =
'';
132 public $context = array();
206 public $ref_previous;
246 public $country_code;
288 public $barcode_type;
294 public $barcode_type_code;
300 public $barcode_type_label;
306 public $barcode_type_coder;
312 public $mode_reglement_id;
318 public $cond_reglement_id;
323 public $demand_reason_id;
329 public $transport_mode_id;
336 public $cond_reglement;
343 public $fk_delivery_address;
349 public $shipping_method_id;
361 public $last_main_doc;
391 public $note_private;
415 public $total_localtax1;
421 public $total_localtax2;
438 public $comments = array();
464 public $date_creation;
469 public $date_validation;
474 public $date_modification;
476 public $next_prev_filter;
481 public $specimen = 0;
496 protected $childtables = array();
503 protected $childtablesoncascade = array();
521 $sql =
"SELECT rowid, ref, ref_ext";
522 $sql .=
" FROM ".MAIN_DB_PREFIX.$element;
523 $sql .=
" WHERE entity IN (".getEntity($element).
")";
525 if ($id > 0) $sql .=
" AND rowid = ".$db->escape($id);
526 elseif ($ref) $sql .=
" AND ref = '".$db->escape($ref).
"'";
527 elseif ($ref_ext) $sql .=
" AND ref_ext = '".$db->escape($ref_ext).
"'";
529 $error =
'ErrorWrongParameters';
533 if ($ref || $ref_ext) $sql .=
" AND entity = ".$conf->entity;
535 dol_syslog(get_class().
"::isExistingObject", LOG_DEBUG);
536 $resql = $db->query($sql);
539 $num = $db->num_rows(
$resql);
540 if ($num > 0)
return 1;
553 return $this->error.(is_array($this->errors) ? (($this->error !=
'' ?
', ' :
'').join(
', ', $this->errors)) :
'');
567 $parameters = array(
'objref'=>$objref);
569 $reshook = $hookmanager->executeHooks(
'getFormatedCustomerRef', $parameters, $this, $action);
572 return $hookmanager->resArray[
'objref'];
574 return $objref.(isset($hookmanager->resArray[
'objref']) ? $hookmanager->resArray[
'objref'] :
'');
587 $parameters = array(
'objref'=>$objref);
589 $reshook = $hookmanager->executeHooks(
'getFormatedSupplierRef', $parameters, $this, $action);
592 return $hookmanager->resArray[
'objref'];
594 return $objref.(isset($hookmanager->resArray[
'objref']) ? $hookmanager->resArray[
'objref'] :
'');
606 public function getFullName($langs, $option = 0, $nameorder = -1, $maxlen = 0)
609 $lastname = $this->lastname;
610 $firstname = $this->firstname;
611 if (empty($lastname)) $lastname = (isset($this->lastname) ? $this->lastname : (isset($this->
name) ? $this->
name : (isset($this->
nom) ? $this->
nom : (isset($this->societe) ? $this->societe : (isset($this->company) ? $this->company :
'')))));
614 if ($option && $this->civility_code)
616 if ($langs->transnoentitiesnoconv(
"Civility".$this->civility_code) !=
"Civility".$this->civility_code) $ret .= $langs->transnoentitiesnoconv(
"Civility".$this->civility_code).
' ';
617 else $ret .= $this->civility_code.
' ';
633 if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) {
638 if (!empty($conf->global->MAIN_ALL_TO_UPPER)) {
642 if (!empty($conf->global->MAIN_ALL_TOWN_TO_UPPER)) {
655 $return =
'<div class="box-flex-item">';
656 $return .=
'<div class="info-box info-box-sm">';
657 $return .=
'<span class="info-box-icon bg-infobox-action">';
658 $return .=
'<i class="fa fa-dol-action"></i>';
659 $return .=
'</span>';
660 $return .=
'<div class="info-box-content">';
661 $return .=
'<span class="info-box-title">'.(method_exists($this,
'getNomUrl') ? $this->getNomUrl() : $this->ref).
'</span>';
678 public function getFullAddress($withcountry = 0, $sep =
"\n", $withregion = 0, $extralangcode =
'')
680 if ($withcountry && $this->country_id && (empty($this->country_code) || empty($this->country)))
682 require_once DOL_DOCUMENT_ROOT.
'/core/lib/company.lib.php';
683 $tmparray =
getCountry($this->country_id,
'all');
684 $this->country_code = $tmparray[
'code'];
685 $this->country = $tmparray[
'label'];
688 if ($withregion && $this->state_id && (empty($this->state_code) || empty($this->state) || empty($this->region) || empty($this->region_code)))
690 require_once DOL_DOCUMENT_ROOT.
'/core/lib/company.lib.php';
691 $tmparray =
getState($this->state_id,
'all', 0, 1);
692 $this->state_code = $tmparray[
'code'];
693 $this->state = $tmparray[
'label'];
694 $this->region_code = $tmparray[
'region_code'];
695 $this->region = $tmparray[
'region'];
711 global $conf, $langs, $form, $extralanguages;
713 $countriesusingstate = array(
'AU',
'US',
'IN',
'GB',
'ES',
'UK',
'TR');
717 $elementforaltlanguage = $this->element;
718 if ($this->element ==
'societe') {
719 $thirdpartyid = $this->id;
721 if ($this->element ==
'contact') {
722 $contactid = $this->id;
723 $thirdpartyid = $object->fk_soc;
725 if ($this->element ==
'user') {
726 $contactid = $this->contact_id;
727 $thirdpartyid = $object->fk_soc;
733 $coords = $this->
getFullAddress(1,
', ', $conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT);
736 if (!empty($conf->use_javascript_ajax))
740 if ($this->element ==
'contact' && !empty($conf->global->MAIN_SHOW_COMPANY_NAME_IN_BANNER_ADDRESS))
742 $namecoords .= $object->name.
'<br>';
744 $namecoords .= $this->
getFullName($langs, 1).
'<br>'.$coords;
746 $out .=
'<a href="#" class="hideonsmartphone" onclick="return copyToClipboard(\''.dol_escape_js($namecoords).
'\',\
''.dol_escape_js($langs->trans(
"HelpCopyToClipboard")).
'\');
">';
747 $out .= img_picto($langs->trans("Address
"), 'map-marker-alt');
750 $out .= dol_print_address($coords, 'address_'.$htmlkey.'_'.$this->id, $this->element, $this->id, 1, ', '); $outdone++;
753 // List of extra languages
754 $arrayoflangcode = array();
755 if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE)) $arrayoflangcode[] = $conf->global->PDF_USE_ALSO_LANGUAGE_CODE;
757 if (is_array($arrayoflangcode) && count($arrayoflangcode)) {
758 if (!is_object($extralanguages)) {
759 include_once DOL_DOCUMENT_ROOT.'/core/class/extralanguages.class.php';
760 $extralanguages = new ExtraLanguages($this->db);
762 $extralanguages->fetch_name_extralanguages($elementforaltlanguage);
764 if (!empty($extralanguages->attributes[$elementforaltlanguage]['address']) || !empty($extralanguages->attributes[$elementforaltlanguage]['town']))
766 $out .= "<!-- alternatelanguage
for '".$elementforaltlanguage."' set to
fields '".join(',
', $extralanguages->attributes[$elementforaltlanguage])."' -->\n
";
767 $this->fetchValuesForExtraLanguages();
768 if (!is_object($form)) $form = new Form($this->db);
770 // If there is extra languages
771 foreach ($arrayoflangcode as $extralangcode) {
772 $s = picto_from_langcode($extralangcode, 'class="pictoforlang paddingright
"');
773 $coords = $this->getFullAddress(1, ', ', $conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT, $extralangcode);
774 $htmltext .= $s.dol_print_address($coords, 'address_'.$htmlkey.'_'.$this->id, $this->element, $this->id, 1, ', ');
776 $out .= $form->textwithpicto('', $htmltext, -1, 'language', 'opacitymedium paddingleft');
781 if (!in_array($this->country_code, $countriesusingstate) && empty($conf->global->MAIN_FORCE_STATE_INTO_ADDRESS) // If MAIN_FORCE_STATE_INTO_ADDRESS is on, state is already returned previously with getFullAddress
782 && empty($conf->global->SOCIETE_DISABLE_STATE) && $this->state)
784 if (!empty($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT) && $conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 1 && $this->region) {
785 $out .= ($outdone ? ' - ' : '').$this->region.' - '.$this->state;
787 $out .= ($outdone ? ' - ' : '').$this->state;
792 if (!empty($this->phone) || !empty($this->phone_pro) || !empty($this->phone_mobile) || !empty($this->phone_perso) || !empty($this->fax) || !empty($this->office_phone) || !empty($this->user_mobile) || !empty($this->office_fax)) $out .= ($outdone ? '<br>' : '');
793 if (!empty($this->phone) && empty($this->phone_pro)) { // For objects that store pro phone into ->phone
794 $out .= dol_print_phone($this->phone, $this->country_code, $contactid, $thirdpartyid, 'AC_TEL', ' ', 'phone', $langs->trans("PhonePro
"));
797 if (!empty($this->phone_pro)) {
798 $out .= dol_print_phone($this->phone_pro, $this->country_code, $contactid, $thirdpartyid, 'AC_TEL', ' ', 'phone', $langs->trans("PhonePro
"));
801 if (!empty($this->phone_mobile)) {
802 $out .= dol_print_phone($this->phone_mobile, $this->country_code, $contactid, $thirdpartyid, 'AC_TEL', ' ', 'mobile', $langs->trans("PhoneMobile
"));
805 if (!empty($this->phone_perso)) {
806 $out .= dol_print_phone($this->phone_perso, $this->country_code, $contactid, $thirdpartyid, 'AC_TEL', ' ', 'phone', $langs->trans("PhonePerso
"));
809 if (!empty($this->office_phone)) {
810 $out .= dol_print_phone($this->office_phone, $this->country_code, $contactid, $thirdpartyid, 'AC_TEL', ' ', 'phone', $langs->trans("PhonePro
"));
813 if (!empty($this->user_mobile)) {
814 $out .= dol_print_phone($this->user_mobile, $this->country_code, $contactid, $thirdpartyid, 'AC_TEL', ' ', 'mobile', $langs->trans("PhoneMobile
"));
817 if (!empty($this->fax)) {
818 $out .= dol_print_phone($this->fax, $this->country_code, $contactid, $thirdpartyid, 'AC_FAX', ' ', 'fax', $langs->trans("Fax
"));
821 if (!empty($this->office_fax)) {
822 $out .= dol_print_phone($this->office_fax, $this->country_code, $contactid, $thirdpartyid, 'AC_FAX', ' ', 'fax', $langs->trans("Fax
"));
826 if ($out) $out .= '<div style="clear: both;
"></div>';
828 if (!empty($this->email)) {
829 $out .= dol_print_email($this->email, $this->id, $object->id, 'AC_EMAIL', 0, 0, 1);
832 if (!empty($this->url)) {
833 //$out.=dol_print_url($this->url,'_goout',0,1);//steve changed to blank
834 $out .= dol_print_url($this->url, '_blank', 0, 1);
838 if (!empty($conf->socialnetworks->enabled)) {
839 $outsocialnetwork = '';
841 if (is_array($this->socialnetworks) && count($this->socialnetworks) > 0) {
842 $socialnetworksdict = getArrayOfSocialNetworks();
843 foreach ($this->socialnetworks as $key => $value) {
845 $outsocialnetwork .= dol_print_socialnetworks($value, $this->id, $object->id, $key, $socialnetworksdict);
849 } else { // Old code to remove
850 if ($this->skype) $outsocialnetwork .= dol_print_socialnetworks($this->skype, $this->id, $object->id, 'skype');
852 if ($this->jabberid) $outsocialnetwork .= dol_print_socialnetworks($this->jabberid, $this->id, $object->id, 'jabber');
854 if ($this->twitter) $outsocialnetwork .= dol_print_socialnetworks($this->twitter, $this->id, $object->id, 'twitter');
856 if ($this->facebook) $outsocialnetwork .= dol_print_socialnetworks($this->facebook, $this->id, $object->id, 'facebook');
858 if ($this->linkedin) $outsocialnetwork .= dol_print_socialnetworks($this->linkedin, $this->id, $object->id, 'linkedin');
862 if ($outsocialnetwork) {
863 $out .= '<div style="clear: both;
">'.$outsocialnetwork.'</div>';
867 if ($out) return '<!-- BEGIN part to show address block -->'."\n".$out.'<!-- END Part to show address block -->'."\n";
879 public function getLastMainDocLink($modulepart, $initsharekey = 0, $relativelink = 0)
881 global $user, $dolibarr_main_url_root;
883 if (empty($this->last_main_doc))
885 return ''; // No way to known which document name to use
888 include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
889 $ecmfile = new EcmFiles($this->db);
890 $result = $ecmfile->fetch(0, '', $this->last_main_doc);
893 $this->error = $ecmfile->error;
894 $this->errors = $ecmfile->errors;
898 if (empty($ecmfile->id))
900 // Add entry into index
903 require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
904 // TODO We can't, we dont' have full path of file, only last_main_doc adn ->element, so we must rebuild full path first
906 $ecmfile->filepath = $rel_dir;
907 $ecmfile->filename = $filename;
908 $ecmfile->label = md5_file(dol_osencode($destfull)); // hash of file content
909 $ecmfile->fullpath_orig = '';
910 $ecmfile->gen_or_uploaded = 'generated';
911 $ecmfile->description = ''; // indexed content
912 $ecmfile->keyword = ''; // keyword content
913 $ecmfile->share = getRandomPassword(true);
914 $result = $ecmfile->create($user);
917 $this->error = $ecmfile->error;
918 $this->errors = $ecmfile->errors;
922 } elseif (empty($ecmfile->share))
924 // Add entry into index
927 require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
928 $ecmfile->share = getRandomPassword(true);
929 $ecmfile->update($user);
932 // Define $urlwithroot
933 $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
934 // This is to use external domain name found into config file
935 //if (DOL_URL_ROOT && ! preg_match('/\/$/', $urlwithouturlroot) && ! preg_match('/^\//', DOL_URL_ROOT)) $urlwithroot=$urlwithouturlroot.'/'.DOL_URL_ROOT;
937 $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT;
938 //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
943 //if (! empty($modulepart)) $paramlink.=($paramlink?'&':'').'modulepart='.$modulepart; // For sharing with hash (so public files), modulepart is not required.
944 //if (! empty($ecmfile->entity)) $paramlink.='&entity='.$ecmfile->entity; // For sharing with hash (so public files), entity is not required.
945 //$paramlink.=($paramlink?'&':'').'file='.urlencode($filepath); // No need of name of file for public link, we will use the hash
946 if (!empty($ecmfile->share)) $paramlink .= ($paramlink ? '&' : '').'hashp='.$ecmfile->share; // Hash for public share
947 if ($forcedownload) $paramlink .= ($paramlink ? '&' : '').'attachment=1';
951 $linktoreturn = 'document.php'.($paramlink ? '?'.$paramlink : '');
953 $linktoreturn = $urlwithroot.'/document.php'.($paramlink ? '?'.$paramlink : '');
956 // Here $ecmfile->share is defined
957 return $linktoreturn;
961 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
971 public function add_contact($fk_socpeople, $type_contact, $source = 'external', $notrigger = 0)
974 global $user, $langs;
977 dol_syslog(get_class($this)."::add_contact $fk_socpeople, $type_contact, $source, $notrigger
");
980 if ($fk_socpeople <= 0)
982 $langs->load("errors
");
983 $this->error = $langs->trans("ErrorWrongValueForParameterX
", "1
");
984 dol_syslog(get_class($this)."::add_contact ".$this->error, LOG_ERR);
989 $langs->load("errors
");
990 $this->error = $langs->trans("ErrorWrongValueForParameterX
", "2
");
991 dol_syslog(get_class($this)."::add_contact ".$this->error, LOG_ERR);
995 $id_type_contact = 0;
996 if (is_numeric($type_contact))
998 $id_type_contact = $type_contact;
1000 // We look for id type_contact
1001 $sql = "SELECT tc.rowid
";
1002 $sql .= " FROM
".MAIN_DB_PREFIX."c_type_contact as tc
";
1003 $sql .= " WHERE tc.element=
'".$this->db->escape($this->element)."'";
1004 $sql .= " AND tc.source=
'".$this->db->escape($source)."'";
1005 $sql .= " AND tc.code=
'".$this->db->escape($type_contact)."' AND tc.active=1
";
1007 $resql = $this->db->query($sql);
1010 $obj = $this->db->fetch_object($resql);
1011 if ($obj) $id_type_contact = $obj->rowid;
1015 if ($id_type_contact == 0)
1017 $this->error = 'CODE_NOT_VALID_FOR_THIS_ELEMENT';
1018 dol_syslog("CODE_NOT_VALID_FOR_THIS_ELEMENT: Code
type of contact
'".$type_contact."' does not exists or is not active
for element
".$this->element.", we can ignore it
");
1022 $datecreate = dol_now();
1024 // Socpeople must have already been added by some trigger, then we have to check it to avoid DB_ERROR_RECORD_ALREADY_EXISTS error
1025 $TListeContacts = $this->liste_contact(-1, $source);
1026 $already_added = false;
1027 if (is_array($TListeContacts) && !empty($TListeContacts)) {
1028 foreach ($TListeContacts as $array_contact) {
1029 if ($array_contact['status'] == 4 && $array_contact['id'] == $fk_socpeople && $array_contact['fk_c_type_contact'] == $id_type_contact) {
1030 $already_added = true;
1036 if (!$already_added) {
1039 // Insert into database
1040 $sql = "INSERT INTO
".MAIN_DB_PREFIX."element_contact
";
1041 $sql .= " (element_id, fk_socpeople, datecreate,
statut, fk_c_type_contact)
";
1042 $sql .= " VALUES (
".$this->id.",
".$fk_socpeople." ,
";
1043 $sql .= "'".$this->db->idate($datecreate)."'";
1044 $sql .= ", 4,
".$id_type_contact;
1047 $resql = $this->db->query($sql);
1052 $result = $this->call_trigger(strtoupper($this->element).'_ADD_CONTACT', $user);
1055 $this->db->rollback();
1060 $this->db->commit();
1063 if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS')
1065 $this->error = $this->db->errno();
1066 $this->db->rollback();
1069 $this->error = $this->db->error();
1070 $this->db->rollback();
1077 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1085 public function copy_linked_contact($objFrom, $source = 'internal')
1088 $contacts = $objFrom->liste_contact(-1, $source);
1089 foreach ($contacts as $contact)
1091 if ($this->add_contact($contact['id'], $contact['fk_c_type_contact'], $contact['source']) < 0)
1093 $this->error = $this->db->lasterror();
1100 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1110 public function update_contact($rowid, $statut, $type_contact_id = 0, $fk_socpeople = 0)
1113 // Insert into database
1114 $sql = "UPDATE
".MAIN_DB_PREFIX."element_contact set
";
1115 $sql .= " statut =
".$statut;
1116 if ($type_contact_id) $sql .= ", fk_c_type_contact =
".((int) $type_contact_id);
1117 if ($fk_socpeople) $sql .= ", fk_socpeople =
".((int) $fk_socpeople);
1118 $sql .= " where
rowid =
".$rowid;
1119 $resql = $this->db->query($sql);
1124 $this->error = $this->db->lasterror();
1129 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1137 public function delete_contact($rowid, $notrigger = 0)
1145 $sql = "DELETE FROM
".MAIN_DB_PREFIX."element_contact
";
1146 $sql .= " WHERE rowid =
".$rowid;
1149 if ($this->db->query($sql))
1153 $result = $this->call_trigger(strtoupper($this->element).'_DELETE_CONTACT', $user);
1154 if ($result < 0) { $this->db->rollback(); return -1; }
1157 $this->db->commit();
1160 $this->error = $this->db->lasterror();
1161 $this->db->rollback();
1166 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1174 public function delete_linked_contact($source = '', $code = '')
1178 $typeContact = $this->liste_type_contact($source, '', 0, 0, $code);
1180 foreach ($typeContact as $key => $value)
1182 array_push($temp, $key);
1184 $listId = implode(",
", $temp);
1186 $sql = "DELETE FROM
".MAIN_DB_PREFIX."element_contact
";
1187 $sql .= " WHERE element_id =
".$this->id;
1189 $sql .= " AND fk_c_type_contact IN (
".$listId.")
";
1192 if ($this->db->query($sql))
1196 $this->error = $this->db->lasterror();
1201 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1211 public function liste_contact($status = -1, $source = 'external', $list = 0, $code = '')
1218 $sql = "SELECT ec.rowid, ec.statut as statuslink, ec.fk_socpeople as id, ec.fk_c_type_contact
"; // This field contains id of llx_socpeople or id of llx_user
1219 if ($source == 'internal') $sql .= ",
'-1' as socid, t.statut as statuscontact, t.login, t.photo
";
1220 if ($source == 'external' || $source == 'thirdparty') $sql .= ", t.fk_soc as socid, t.statut as statuscontact
";
1221 $sql .= ", t.civility as civility, t.lastname as lastname, t.firstname, t.email
";
1222 $sql .= ", tc.source, tc.element, tc.code, tc.libelle
";
1223 $sql .= " FROM
".MAIN_DB_PREFIX."c_type_contact tc
";
1224 $sql .= ",
".MAIN_DB_PREFIX."element_contact ec
";
1225 if ($source == 'internal') $sql .= " LEFT JOIN
".MAIN_DB_PREFIX."user t on ec.fk_socpeople = t.rowid
";
1226 if ($source == 'external' || $source == 'thirdparty') $sql .= " LEFT JOIN
".MAIN_DB_PREFIX."socpeople t on ec.fk_socpeople = t.rowid
";
1227 $sql .= " WHERE ec.element_id =
".$this->id;
1228 $sql .= " AND ec.fk_c_type_contact=tc.rowid
";
1229 $sql .= " AND tc.element=
'".$this->db->escape($this->element)."'";
1230 if ($code) $sql .= " AND tc.code =
'".$this->db->escape($code)."'";
1231 if ($source == 'internal') $sql .= " AND tc.source =
'internal'";
1232 if ($source == 'external' || $source == 'thirdparty') $sql .= " AND tc.source =
'external'";
1233 $sql .= " AND tc.active=1
";
1234 if ($status >= 0) $sql .= " AND ec.statut =
".$status;
1235 $sql .= " ORDER BY t.lastname ASC
";
1238 $resql = $this->db->query($sql);
1241 $num = $this->db->num_rows($resql);
1245 $obj = $this->db->fetch_object($resql);
1249 $transkey = "TypeContact_
".$obj->element."_
".$obj->source."_
".$obj->code;
1250 $libelle_type = ($langs->trans($transkey) != $transkey ? $langs->trans($transkey) : $obj->libelle);
1251 $tab[$i] = array('source'=>$obj->source, 'socid'=>$obj->socid, 'id'=>$obj->id,
1252 'nom'=>$obj->lastname, // For backward compatibility
1253 'civility'=>$obj->civility, 'lastname'=>$obj->lastname, 'firstname'=>$obj->firstname, 'email'=>$obj->email, 'login'=>$obj->login, 'photo'=>$obj->photo, 'statuscontact'=>$obj->statuscontact,
1254 'rowid'=>$obj->rowid, 'code'=>$obj->code, 'libelle'=>$libelle_type, 'status'=>$obj->statuslink, 'fk_c_type_contact'=>$obj->fk_c_type_contact);
1256 $tab[$i] = $obj->id;
1264 $this->error = $this->db->lasterror();
1265 dol_print_error($this->db);
1277 public function swapContactStatus($rowid)
1279 $sql = "SELECT ec.datecreate, ec.statut, ec.fk_socpeople, ec.fk_c_type_contact,
";
1280 $sql .= " tc.code, tc.libelle
";
1281 $sql .= " FROM (
".MAIN_DB_PREFIX."element_contact as ec,
".MAIN_DB_PREFIX."c_type_contact as tc)
";
1282 $sql .= " WHERE ec.rowid =
".$rowid;
1283 $sql .= " AND ec.fk_c_type_contact=tc.rowid
";
1284 $sql .= " AND tc.element =
'".$this->db->escape($this->element)."'";
1287 $resql = $this->db->query($sql);
1290 $obj = $this->db->fetch_object($resql);
1291 $newstatut = ($obj->statut == 4) ? 5 : 4;
1292 $result = $this->update_contact($rowid, $newstatut);
1293 $this->db->free($resql);
1296 $this->error = $this->db->error();
1297 dol_print_error($this->db);
1302 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1313 public function liste_type_contact($source = 'internal', $order = 'position', $option = 0, $activeonly = 0, $code = '')
1318 if (empty($order)) $order = 'position';
1319 if ($order == 'position') $order .= ',code';
1322 $sql = "SELECT DISTINCT tc.rowid, tc.code, tc.libelle, tc.position
";
1323 $sql .= " FROM
".MAIN_DB_PREFIX."c_type_contact as tc
";
1324 $sql .= " WHERE tc.element=
'".$this->db->escape($this->element)."'";
1325 if ($activeonly == 1) $sql .= " AND tc.active=1
"; // only the active types
1326 if (!empty($source) && $source != 'all') $sql .= " AND tc.source=
'".$this->db->escape($source)."'";
1327 if (!empty($code)) $sql .= " AND tc.code=
'".$this->db->escape($code)."'";
1328 $sql .= $this->db->order($order, 'ASC');
1330 //print "sql=
".$sql;
1331 $resql = $this->db->query($sql);
1334 $num = $this->db->num_rows($resql);
1338 $obj = $this->db->fetch_object($resql);
1340 $transkey = "TypeContact_
".$this->element."_
".$source."_
".$obj->code;
1341 $libelle_type = ($langs->trans($transkey) != $transkey ? $langs->trans($transkey) : $obj->libelle);
1342 if (empty($option)) $tab[$obj->rowid] = $libelle_type;
1343 else $tab[$obj->code] = $libelle_type;
1348 $this->error = $this->db->lasterror();
1349 //dol_print_error($this->db);
1354 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1366 public function listeTypeContacts($source = 'internal', $option = 0, $activeonly = 0, $code = '', $element = '', $excludeelement = '')
1369 global $langs, $conf;
1371 $langs->loadLangs(array('bills', 'contracts', 'interventions', 'orders', 'projects', 'propal', 'ticket', 'agenda'));
1375 $sql = "SELECT DISTINCT tc.rowid, tc.code, tc.libelle, tc.position, tc.element
";
1376 $sql .= " FROM
".MAIN_DB_PREFIX."c_type_contact as tc
";
1378 $sqlWhere = array();
1379 if (!empty($element)) {
1380 $sqlWhere[] = " tc.element=
'".$this->db->escape($element)."'";
1382 if (!empty($excludeelement)) {
1383 $sqlWhere[] = " tc.element <>
'".$this->db->escape($excludeelement)."'";
1386 if ($activeonly == 1)
1387 $sqlWhere[] = " tc.active=1
"; // only the active types
1389 if (!empty($source) && $source != 'all')
1390 $sqlWhere[] = " tc.source=
'".$this->db->escape($source)."'";
1393 $sqlWhere[] = " tc.code=
'".$this->db->escape($code)."'";
1395 if (count($sqlWhere) > 0) {
1396 $sql .= " WHERE
".implode(' AND ', $sqlWhere);
1399 $sql .= $this->db->order('tc.element, tc.position', 'ASC');
1401 dol_syslog(__METHOD__, LOG_DEBUG);
1402 $resql = $this->db->query($sql);
1404 $num = $this->db->num_rows($resql);
1406 $langs->loadLangs(array("propal
", "orders
", "bills
", "suppliers
", "contracts
", "supplier_proposal
"));
1408 while ($obj = $this->db->fetch_object($resql)) {
1409 $modulename = $obj->element;
1410 if (strpos($obj->element, 'project') !== false) {
1411 $modulename = 'projet';
1412 } elseif ($obj->element == 'contrat') {
1413 $element = 'contract';
1414 } elseif ($obj->element == 'action') {
1415 $modulename = 'agenda';
1416 } elseif (strpos($obj->element, 'supplier') !== false && $obj->element != 'supplier_proposal') {
1417 $modulename = 'fournisseur';
1418 } elseif (strpos($obj->element, 'supplier') !== false && $obj->element != 'supplier_proposal') {
1419 $modulename = 'fournisseur';
1421 if ($conf->{$modulename}->enabled) {
1422 $libelle_element = $langs->trans('ContactDefault_'.$obj->element);
1423 $tmpelement = $obj->element;
1424 $transkey = "TypeContact_
".$tmpelement."_
".$source."_
".$obj->code;
1425 $libelle_type = ($langs->trans($transkey) != $transkey ? $langs->trans($transkey) : $obj->libelle);
1426 if (empty($option)) {
1427 $tab[$obj->rowid] = $libelle_element.' - '.$libelle_type;
1430 $tab[$obj->rowid] = $libelle_element.' - '.$libelle_type;
1437 $this->error = $this->db->lasterror();
1453 public function getIdContact($source, $code, $status = 0)
1459 //cas particulier pour les expeditions
1460 if ($this->element == 'shipping' && $this->origin_id != 0) {
1461 $id = $this->origin_id;
1462 $element = 'commande';
1463 } elseif ($this->element == 'reception' && $this->origin_id != 0) {
1464 $id = $this->origin_id;
1465 $element = 'order_supplier';
1468 $element = $this->element;
1471 $sql = "SELECT ec.fk_socpeople
";
1472 $sql .= " FROM
".MAIN_DB_PREFIX."element_contact as ec,
";
1473 if ($source == 'internal') $sql .= " ".MAIN_DB_PREFIX."user as c,
";
1474 if ($source == 'external') $sql .= " ".MAIN_DB_PREFIX."socpeople as c,
";
1475 $sql .= " ".MAIN_DB_PREFIX."c_type_contact as tc
";
1476 $sql .= " WHERE ec.element_id =
".$id;
1477 $sql .= " AND ec.fk_socpeople = c.rowid
";
1478 if ($source == 'internal') $sql .= " AND c.entity IN (
".getEntity('user').")
";
1479 if ($source == 'external') $sql .= " AND c.entity IN (
".getEntity('societe').")
";
1480 $sql .= " AND ec.fk_c_type_contact = tc.rowid
";
1481 $sql .= " AND tc.element =
'".$this->db->escape($element)."'";
1482 $sql .= " AND tc.source =
'".$this->db->escape($source)."'";
1483 if ($code) $sql .= " AND tc.code =
'".$this->db->escape($code)."'";
1484 $sql .= " AND tc.active = 1
";
1485 if ($status) $sql .= " AND ec.statut =
".$status;
1488 $resql = $this->db->query($sql);
1491 while ($obj = $this->db->fetch_object($resql))
1493 $result[$i] = $obj->fk_socpeople;
1497 $this->error = $this->db->error();
1504 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1511 public function fetch_contact($contactid = null)
1514 if (empty($contactid)) $contactid = $this->contact_id;
1516 if (empty($contactid)) return 0;
1518 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
1519 $contact = new Contact($this->db);
1520 $result = $contact->fetch($contactid);
1521 $this->contact = $contact;
1525 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1532 public function fetch_thirdparty($force_thirdparty_id = 0)
1537 if (empty($this->socid) && empty($this->fk_soc) && empty($this->fk_thirdparty) && empty($force_thirdparty_id))
1540 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1542 $idtofetch = isset($this->socid) ? $this->socid : (isset($this->fk_soc) ? $this->fk_soc : $this->fk_thirdparty);
1543 if ($force_thirdparty_id)
1544 $idtofetch = $force_thirdparty_id;
1547 $thirdparty = new Societe($this->db);
1548 $result = $thirdparty->fetch($idtofetch);
1549 $this->thirdparty = $thirdparty;
1551 // Use first price level if level not defined for third party
1552 if (!empty($conf->global->PRODUIT_MULTIPRICES) && empty($this->thirdparty->price_level)) {
1553 $this->thirdparty->price_level = 1;
1568 public function fetchOneLike($ref)
1570 if (!$this->table_ref_field) {
1574 $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE '.$this->table_ref_field.' LIKE "'.$this->db->escape($ref).'" LIMIT 1';
1576 $query = $this->db->query($sql);
1578 if (!$this->db->num_rows($query)) {
1582 $result = $this->db->fetch_object($query);
1584 return $this->fetch($result->rowid);
1587 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1595 public function fetch_barcode()
1600 dol_syslog(get_class($this).'::fetch_barcode this->element='.$this->element.' this->barcode_type='.$this->barcode_type);
1602 $idtype = $this->barcode_type;
1603 if (empty($idtype) && $idtype != '0') // If type of barcode no set, we try to guess. If set to '0' it means we forced to have type remain not defined
1605 if ($this->element == 'product') $idtype = $conf->global->PRODUIT_DEFAULT_BARCODE_TYPE;
1606 elseif ($this->element == 'societe') $idtype = $conf->global->GENBARCODE_BARCODETYPE_THIRDPARTY;
1607 else dol_syslog('Call fetch_barcode with barcode_type not defined and cant be guessed', LOG_WARNING);
1612 if (empty($this->barcode_type) || empty($this->barcode_type_code) || empty($this->barcode_type_label) || empty($this->barcode_type_coder)) // If data not already loaded
1614 $sql = "SELECT
rowid,
code, libelle as label, coder
";
1615 $sql .= " FROM
".MAIN_DB_PREFIX."c_barcode_type
";
1616 $sql .= " WHERE rowid =
".$idtype;
1617 dol_syslog(get_class($this).'::fetch_barcode', LOG_DEBUG);
1618 $resql = $this->db->query($sql);
1621 $obj = $this->db->fetch_object($resql);
1622 $this->barcode_type = $obj->rowid;
1623 $this->barcode_type_code = $obj->code;
1624 $this->barcode_type_label = $obj->label;
1625 $this->barcode_type_coder = $obj->coder;
1628 dol_print_error($this->db);
1636 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1642 public function fetch_projet()
1645 include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
1647 if (empty($this->fk_project) && !empty($this->fk_projet)) $this->fk_project = $this->fk_projet; // For backward compatibility
1648 if (empty($this->fk_project)) return 0;
1650 $project = new Project($this->db);
1651 $result = $project->fetch($this->fk_project);
1653 $this->projet = $project; // deprecated
1654 $this->project = $project;
1658 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1664 public function fetch_product()
1667 include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1669 if (empty($this->fk_product)) return 0;
1671 $product = new Product($this->db);
1672 $result = $product->fetch($this->fk_product);
1674 $this->product = $product;
1678 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1685 public function fetch_user($userid)
1688 $user = new User($this->db);
1689 $result = $user->fetch($userid);
1690 $this->user = $user;
1694 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1700 public function fetch_origin()
1703 if ($this->origin == 'shipping') $this->origin = 'expedition';
1704 if ($this->origin == 'delivery') $this->origin = 'livraison';
1705 if ($this->origin == 'order_supplier') $this->origin = 'commandeFournisseur';
1707 $origin = $this->origin;
1709 $classname = ucfirst($origin);
1710 $this->$origin = new $classname($this->db);
1711 $this->$origin->fetch($this->origin_id);
1723 public function fetchObjectFrom($table, $field, $key, $element = null)
1729 $sql = "SELECT rowid FROM
".MAIN_DB_PREFIX.$table;
1730 $sql .= " WHERE
".$field." =
'".$key."'";
1731 if (!empty($element)) {
1732 $sql .= " AND entity IN (
".getEntity($element).")
";
1734 $sql .= " AND entity =
".$conf->entity;
1737 dol_syslog(get_class($this).'::fetchObjectFrom', LOG_DEBUG);
1738 $resql = $this->db->query($sql);
1741 $row = $this->db->fetch_row($resql);
1742 // Test for avoid error -1
1744 $result = $this->fetch($row[0]);
1759 public function getValueFrom($table, $id, $field)
1762 if (!empty($id) && !empty($field) && !empty($table)) {
1763 $sql = "SELECT
".$field." FROM
".MAIN_DB_PREFIX.$table;
1764 $sql .= " WHERE rowid =
".$id;
1766 dol_syslog(get_class($this).'::getValueFrom', LOG_DEBUG);
1767 $resql = $this->db->query($sql);
1770 $row = $this->db->fetch_row($resql);
1793 public function setValueFrom($field, $value, $table = '', $id = null, $format = '', $id_field = '', $fuser = null, $trigkey = '', $fk_user_field = 'fk_user_modif')
1795 global $user, $langs, $conf;
1797 if (empty($table)) $table = $this->table_element;
1798 if (empty($id)) $id = $this->id;
1799 if (empty($format)) $format = 'text';
1800 if (empty($id_field)) $id_field = 'rowid';
1807 if ($table == 'product' && $field == 'note_private') $field = 'note';
1808 if (in_array($table, array('actioncomm', 'adherent', 'advtargetemailing', 'cronjob', 'establishment'))) $fk_user_field = 'fk_user_mod';
1810 $sql = "UPDATE
".MAIN_DB_PREFIX.$table." SET
";
1812 if ($format == 'text') $sql .= $field." =
'".$this->db->escape($value)."'";
1813 elseif ($format == 'int') $sql .= $field." =
".$this->db->escape($value);
1814 elseif ($format == 'date') $sql .= $field." =
".($value ? "'".$this->db->idate($value)."'" : "null
");
1818 if (!empty($fuser) && is_object($fuser)) $sql .= ",
".$fk_user_field." =
".$fuser->id;
1819 elseif (empty($fuser) || $fuser != 'none') $sql .= ",
".$fk_user_field." =
".$user->id;
1822 $sql .= " WHERE
".$id_field." =
".$id;
1824 dol_syslog(__METHOD__."", LOG_DEBUG);
1825 $resql = $this->db->query($sql);
1830 // call trigger with updated object values
1831 if (empty($this->fields) && method_exists($this, 'fetch'))
1833 $result = $this->fetch($id);
1835 $result = $this->fetchCommon($id);
1837 if ($result >= 0) $result = $this->call_trigger($trigkey, (!empty($fuser) && is_object($fuser)) ? $fuser : $user); // This may set this->errors
1838 if ($result < 0) $error++;
1843 if (property_exists($this, $field)) $this->$field = $value;
1844 $this->db->commit();
1847 $this->db->rollback();
1851 if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1852 $this->error = 'DB_ERROR_RECORD_ALREADY_EXISTS';
1854 $this->error = $this->db->lasterror();
1856 $this->db->rollback();
1861 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1870 public function load_previous_next_ref($filter, $fieldid, $nodbprefix = 0)
1873 global $conf, $user;
1875 if (!$this->table_element)
1877 dol_print_error('', get_class($this)."::load_previous_next_ref was called on objet with
property table_element not defined
");
1880 if ($fieldid == 'none') return 1;
1882 // Security on socid
1884 if ($user->socid > 0) $socid = $user->socid;
1886 // this->ismultientitymanaged contains
1887 // 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table
1888 $aliastablesociete = 's';
1889 if ($this->element == 'societe') $aliastablesociete = 'te'; // te as table_element
1891 $sql = "SELECT MAX(te.
".$fieldid.")
";
1892 $sql .= " FROM
".(empty($nodbprefix) ?MAIN_DB_PREFIX:'').$this->table_element." as te
";
1893 if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1894 $sql .= ",
".MAIN_DB_PREFIX."usergroup_user as ug
";
1896 if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged)) {
1897 $tmparray = explode('@', $this->ismultientitymanaged);
1898 $sql .= ",
".MAIN_DB_PREFIX.$tmparray[1]." as
".($tmparray[1] == 'societe' ? 's' : 'parenttable'); // If we need to link to this table to limit select to entity
1899 } elseif ($this->restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= ",
".MAIN_DB_PREFIX."societe as s
"; // If we need to link to societe to limit select to socid
1900 elseif ($this->restrictiononfksoc == 2 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN
".MAIN_DB_PREFIX."societe as s ON te.fk_soc = s.rowid
"; // If we need to link to societe to limit select to socid
1901 if ($this->restrictiononfksoc && !$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN
".MAIN_DB_PREFIX."societe_commerciaux as sc ON
".$aliastablesociete.".rowid = sc.fk_soc
";
1902 $sql .= " WHERE te.
".$fieldid." <
'".$this->db->escape($fieldid == 'rowid
' ? $this->id : $this->ref)."'"; // ->ref must always be defined (set to id if field does not exists)
1903 if ($this->restrictiononfksoc == 1 && !$user->rights->societe->client->voir && !$socid) $sql .= " AND sc.fk_user =
".$user->id;
1904 if ($this->restrictiononfksoc == 2 && !$user->rights->societe->client->voir && !$socid) $sql .= " AND (sc.fk_user =
".$user->id.' OR te.fk_soc IS NULL)';
1905 if (!empty($filter))
1907 if (!preg_match('/^\s*AND/i', $filter)) $sql .= " AND
"; // For backward compatibility
1910 if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged)) {
1911 $tmparray = explode('@', $this->ismultientitymanaged);
1912 $sql .= ' AND te.'.$tmparray[0].' = '.($tmparray[1] == 'societe' ? 's' : 'parenttable').'.rowid'; // If we need to link to this table to limit select to entity
1913 } elseif ($this->restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to socid
1914 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
1915 if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1916 if (!empty($user->admin) && empty($user->entity) && $conf->entity == 1) {
1917 $sql .= " AND te.entity IS NOT NULL
"; // Show all users
1919 $sql .= " AND ug.fk_user = te.rowid
";
1920 $sql .= " AND ug.entity IN (
".getEntity($this->element).")
";
1923 $sql .= ' AND te.entity IN ('.getEntity($this->element).')';
1926 if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged) && $this->element != 'societe') {
1927 $tmparray = explode('@', $this->ismultientitymanaged);
1928 $sql .= ' AND parenttable.entity IN ('.getEntity($tmparray[1]).')';
1930 if ($this->restrictiononfksoc == 1 && $socid && $this->element != 'societe') $sql .= ' AND te.fk_soc = '.$socid;
1931 if ($this->restrictiononfksoc == 2 && $socid && $this->element != 'societe') $sql .= ' AND (te.fk_soc = '.$socid.' OR te.fk_soc IS NULL)';
1932 if ($this->restrictiononfksoc && $socid && $this->element == 'societe') $sql .= ' AND te.rowid = '.$socid;
1933 //print 'socid='.$socid.' restrictiononfksoc='.$this->restrictiononfksoc.' ismultientitymanaged = '.$this->ismultientitymanaged.' filter = '.$filter.' -> '.$sql."<br>
";
1935 $result = $this->db->query($sql);
1938 $this->error = $this->db->lasterror();
1941 $row = $this->db->fetch_row($result);
1942 $this->ref_previous = $row[0];
1944 $sql = "SELECT MIN(te.
".$fieldid.")
";
1945 $sql .= " FROM
".(empty($nodbprefix) ?MAIN_DB_PREFIX:'').$this->table_element." as te
";
1946 if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1947 $sql .= ",
".MAIN_DB_PREFIX."usergroup_user as ug
";
1949 if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged)) {
1950 $tmparray = explode('@', $this->ismultientitymanaged);
1951 $sql .= ",
".MAIN_DB_PREFIX.$tmparray[1]." as
".($tmparray[1] == 'societe' ? 's' : 'parenttable'); // If we need to link to this table to limit select to entity
1952 } elseif ($this->restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= ",
".MAIN_DB_PREFIX."societe as s
"; // If we need to link to societe to limit select to socid
1953 elseif ($this->restrictiononfksoc == 2 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN
".MAIN_DB_PREFIX."societe as s ON te.fk_soc = s.rowid
"; // If we need to link to societe to limit select to socid
1954 if ($this->restrictiononfksoc && !$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN
".MAIN_DB_PREFIX."societe_commerciaux as sc ON
".$aliastablesociete.".rowid = sc.fk_soc
";
1955 $sql .= " WHERE te.
".$fieldid." >
'".$this->db->escape($fieldid == 'rowid
' ? $this->id : $this->ref)."'"; // ->ref must always be defined (set to id if field does not exists)
1956 if ($this->restrictiononfksoc == 1 && !$user->rights->societe->client->voir && !$socid) $sql .= " AND sc.fk_user =
".$user->id;
1957 if ($this->restrictiononfksoc == 2 && !$user->rights->societe->client->voir && !$socid) $sql .= " AND (sc.fk_user =
".$user->id.' OR te.fk_soc IS NULL)';
1958 if (!empty($filter))
1960 if (!preg_match('/^\s*AND/i', $filter)) $sql .= " AND
"; // For backward compatibility
1963 if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged)) {
1964 $tmparray = explode('@', $this->ismultientitymanaged);
1965 $sql .= ' AND te.'.$tmparray[0].' = '.($tmparray[1] == 'societe' ? 's' : 'parenttable').'.rowid'; // If we need to link to this table to limit select to entity
1966 } elseif ($this->restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to socid
1967 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
1968 if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1969 if (!empty($user->admin) && empty($user->entity) && $conf->entity == 1) {
1970 $sql .= " AND te.entity IS NOT NULL
"; // Show all users
1972 $sql .= " AND ug.fk_user = te.rowid
";
1973 $sql .= " AND ug.entity IN (
".getEntity($this->element).")
";
1976 $sql .= ' AND te.entity IN ('.getEntity($this->element).')';
1979 if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged) && $this->element != 'societe') {
1980 $tmparray = explode('@', $this->ismultientitymanaged);
1981 $sql .= ' AND parenttable.entity IN ('.getEntity($tmparray[1]).')';
1983 if ($this->restrictiononfksoc == 1 && $socid && $this->element != 'societe') $sql .= ' AND te.fk_soc = '.$socid;
1984 if ($this->restrictiononfksoc == 2 && $socid && $this->element != 'societe') $sql .= ' AND (te.fk_soc = '.$socid.' OR te.fk_soc IS NULL)';
1985 if ($this->restrictiononfksoc && $socid && $this->element == 'societe') $sql .= ' AND te.rowid = '.$socid;
1986 //print 'socid='.$socid.' restrictiononfksoc='.$this->restrictiononfksoc.' ismultientitymanaged = '.$this->ismultientitymanaged.' filter = '.$filter.' -> '.$sql."<br>
";
1987 // Rem: Bug in some mysql version: SELECT MIN(rowid) FROM llx_socpeople WHERE rowid > 1 when one row in database with rowid=1, returns 1 instead of null
1989 $result = $this->db->query($sql);
1992 $this->error = $this->db->lasterror();
1995 $row = $this->db->fetch_row($result);
1996 $this->ref_next = $row[0];
2009 public function getListContactId($source = 'external')
2011 $contactAlreadySelected = array();
2012 $tab = $this->liste_contact(-1, $source);
2017 if ($source == 'thirdparty') $contactAlreadySelected[$i] = $tab[$i]['socid'];
2018 else $contactAlreadySelected[$i] = $tab[$i]['id'];
2021 return $contactAlreadySelected;
2031 public function setProject($projectid)
2033 if (!$this->table_element)
2035 dol_syslog(get_class($this)."::
setProject was called on objet with property table_element not defined
", LOG_ERR);
2039 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
2040 if (!empty($this->fields['fk_project'])) // Common case
2042 if ($projectid) $sql .= ' SET fk_project = '.$projectid;
2043 else $sql .= ' SET fk_project = NULL';
2044 $sql .= ' WHERE rowid = '.$this->id;
2045 } elseif ($this->table_element == 'actioncomm') // Special case for actioncomm
2047 if ($projectid) $sql .= ' SET fk_project = '.$projectid;
2048 else $sql .= ' SET fk_project = NULL';
2049 $sql .= ' WHERE id = '.$this->id;
2050 } else // Special case for old architecture objects
2052 if ($projectid) $sql .= ' SET fk_projet = '.$projectid;
2053 else $sql .= ' SET fk_projet = NULL';
2054 $sql .= ' WHERE rowid = '.$this->id;
2057 dol_syslog(get_class($this)."::
setProject", LOG_DEBUG);
2058 if ($this->db->query($sql))
2060 $this->fk_project = $projectid;
2063 dol_print_error($this->db);
2074 public function setPaymentMethods($id)
2076 dol_syslog(get_class($this).'::setPaymentMethods('.$id.')');
2077 if ($this->statut >= 0 || $this->element == 'societe')
2079 // TODO uniformize field name
2080 $fieldname = 'fk_mode_reglement';
2081 if ($this->element == 'societe') $fieldname = 'mode_reglement';
2082 if (get_class($this) == 'Fournisseur') $fieldname = 'mode_reglement_supplier';
2084 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
2085 $sql .= ' SET '.$fieldname.' = '.(($id > 0 || $id == '0') ? $id : 'NULL');
2086 $sql .= ' WHERE rowid='.$this->id;
2088 if ($this->db->query($sql))
2090 $this->mode_reglement_id = $id;
2092 if (get_class($this) == 'Fournisseur') $this->mode_reglement_supplier_id = $id;
2095 dol_syslog(get_class($this).'::setPaymentMethods Error '.$sql.' - '.$this->db->error());
2096 $this->error = $this->db->error();
2100 dol_syslog(get_class($this).'::setPaymentMethods, status of the object is incompatible');
2101 $this->error = 'Status of the object is incompatible '.$this->statut;
2112 public function setMulticurrencyCode($code)
2114 dol_syslog(get_class($this).'::setMulticurrencyCode('.$code.')');
2115 if ($this->statut >= 0 || $this->element == 'societe')
2117 $fieldname = 'multicurrency_code';
2119 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
2120 $sql .= ' SET '.$fieldname." =
'".$this->db->escape($code)."'";
2121 $sql .= ' WHERE rowid='.$this->id;
2123 if ($this->db->query($sql))
2125 $this->multicurrency_code = $code;
2127 list($fk_multicurrency, $rate) = MultiCurrency::getIdAndTxFromCode($this->db, $code);
2128 if ($rate) $this->setMulticurrencyRate($rate, 2);
2132 dol_syslog(get_class($this).'::setMulticurrencyCode Error '.$sql.' - '.$this->db->error());
2133 $this->error = $this->db->error();
2137 dol_syslog(get_class($this).'::setMulticurrencyCode, status of the object is incompatible');
2138 $this->error = 'Status of the object is incompatible '.$this->statut;
2150 public function setMulticurrencyRate($rate, $mode = 1)
2152 dol_syslog(get_class($this).'::setMulticurrencyRate('.$rate.','.$mode.')');
2153 if ($this->statut >= 0 || $this->element == 'societe')
2155 $fieldname = 'multicurrency_tx';
2157 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
2158 $sql .= ' SET '.$fieldname.' = '.$rate;
2159 $sql .= ' WHERE rowid='.$this->id;
2161 if ($this->db->query($sql))
2163 $this->multicurrency_tx = $rate;
2165 // Update line price
2166 if (!empty($this->lines))
2168 foreach ($this->lines as &$line)
2170 // Amounts in company currency will be recalculated
2172 $line->subprice = 0;
2175 // Amounts in foreign currency will be recalculated
2177 $line->multicurrency_subprice = 0;
2180 switch ($this->element) {
2183 $line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx,
2184 ($line->description ? $line->description : $line->desc), 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line,
2185 $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->date_start,
2186 $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice
2191 $line->id, ($line->description ? $line->description : $line->desc), $line->subprice, $line->qty, $line->remise_percent,
2192 $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->date_start, $line->date_end,
2193 $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label,
2194 $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice
2199 $line->id, ($line->description ? $line->description : $line->desc), $line->subprice, $line->qty, $line->remise_percent,
2200 $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits,
2201 $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label,
2202 $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit, $line->multicurrency_subprice
2205 case 'supplier_proposal':
2207 $line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx,
2208 ($line->description ? $line->description : $line->desc), 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line,
2209 $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->array_options,
2210 $line->ref_fourn, $line->multicurrency_subprice
2213 case 'order_supplier':
2215 $line->id, ($line->description ? $line->description : $line->desc), $line->subprice, $line->qty, $line->remise_percent,
2216 $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, false,
2217 $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice,
2221 case 'invoice_supplier':
2223 $line->id, ($line->description ? $line->description : $line->desc), $line->subprice, $line->tva_tx, $line->localtax1_tx,
2224 $line->localtax2_tx, $line->qty, 0, 'HT', $line->info_bits, $line->product_type, $line->remise_percent, false,
2225 $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice,
2230 dol_syslog(get_class($this).'::setMulticurrencyRate no updateline defined', LOG_DEBUG);
2238 dol_syslog(get_class($this).'::setMulticurrencyRate Error '.$sql.' - '.$this->db->error());
2239 $this->error = $this->db->error();
2243 dol_syslog(get_class($this).'::setMulticurrencyRate, status of the object is incompatible');
2244 $this->error = 'Status of the object is incompatible '.$this->statut;
2255 public function setPaymentTerms($id)
2257 dol_syslog(get_class($this).'::setPaymentTerms('.$id.')');
2258 if ($this->statut >= 0 || $this->element == 'societe')
2260 // TODO uniformize field name
2261 $fieldname = 'fk_cond_reglement';
2262 if ($this->element == 'societe') $fieldname = 'cond_reglement';
2263 if (get_class($this) == 'Fournisseur') $fieldname = 'cond_reglement_supplier';
2265 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
2266 $sql .= ' SET '.$fieldname.' = '.(($id > 0 || $id == '0') ? $id : 'NULL');
2267 $sql .= ' WHERE rowid='.$this->id;
2269 if ($this->db->query($sql))
2271 $this->cond_reglement_id = $id;
2273 if (get_class($this) == 'Fournisseur') $this->cond_reglement_supplier_id = $id;
2274 $this->cond_reglement = $id; // for compatibility
2277 dol_syslog(get_class($this).'::setPaymentTerms Error '.$sql.' - '.$this->db->error());
2278 $this->error = $this->db->error();
2282 dol_syslog(get_class($this).'::setPaymentTerms, status of the object is incompatible');
2283 $this->error = 'Status of the object is incompatible '.$this->statut;
2294 public function setTransportMode($id)
2296 dol_syslog(get_class($this).'::setTransportMode('.$id.')');
2297 if ($this->statut >= 0 || $this->element == 'societe')
2299 $fieldname = 'fk_transport_mode';
2300 if ($this->element == 'societe') $fieldname = 'transport_mode';
2301 if (get_class($this) == 'Fournisseur') $fieldname = 'transport_mode_supplier';
2303 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
2304 $sql .= ' SET '.$fieldname.' = '.(($id > 0 || $id == '0') ? $id : 'NULL');
2305 $sql .= ' WHERE rowid='.$this->id;
2307 if ($this->db->query($sql))
2309 $this->transport_mode_id = $id;
2311 if (get_class($this) == 'Fournisseur') $this->transport_mode_supplier_id = $id;
2314 dol_syslog(get_class($this).'::setTransportMode Error '.$sql.' - '.$this->db->error());
2315 $this->error = $this->db->error();
2319 dol_syslog(get_class($this).'::setTransportMode, status of the object is incompatible');
2320 $this->error = 'Status of the object is incompatible '.$this->statut;
2331 public function setRetainedWarrantyPaymentTerms($id)
2333 dol_syslog(get_class($this).'::setRetainedWarrantyPaymentTerms('.$id.')');
2334 if ($this->statut >= 0 || $this->element == 'societe')
2336 $fieldname = 'retained_warranty_fk_cond_reglement';
2338 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
2339 $sql .= ' SET '.$fieldname.' = '.$id;
2340 $sql .= ' WHERE rowid='.$this->id;
2342 if ($this->db->query($sql))
2344 $this->retained_warranty_fk_cond_reglement = $id;
2347 dol_syslog(get_class($this).'::setRetainedWarrantyPaymentTerms Error '.$sql.' - '.$this->db->error());
2348 $this->error = $this->db->error();
2352 dol_syslog(get_class($this).'::setRetainedWarrantyPaymentTerms, status of the object is incompatible');
2353 $this->error = 'Status of the object is incompatible '.$this->statut;
2365 public function setDeliveryAddress($id)
2367 $fieldname = 'fk_delivery_address';
2368 if ($this->element == 'delivery' || $this->element == 'shipping') $fieldname = 'fk_address';
2370 $sql = "UPDATE
".MAIN_DB_PREFIX.$this->table_element." SET
".$fieldname." =
".$id;
2371 $sql .= " WHERE rowid =
".$this->id." AND fk_statut = 0
";
2373 if ($this->db->query($sql))
2375 $this->fk_delivery_address = $id;
2378 $this->error = $this->db->error();
2379 dol_syslog(get_class($this).'::setDeliveryAddress Error '.$sql.' - '.$this->error);
2394 public function setShippingMethod($shipping_method_id, $notrigger = false, $userused = null)
2398 if (empty($userused)) $userused = $user;
2402 if (!$this->table_element) {
2403 dol_syslog(get_class($this)."::
setShippingMethod was called on objet with property table_element not defined
", LOG_ERR);
2409 if ($shipping_method_id < 0) $shipping_method_id = 'NULL';
2410 dol_syslog(get_class($this).'::setShippingMethod('.$shipping_method_id.')');
2412 $sql = "UPDATE
".MAIN_DB_PREFIX.$this->table_element;
2413 $sql .= " SET fk_shipping_method =
".$shipping_method_id;
2414 $sql .= " WHERE rowid=
".$this->id;
2415 $resql = $this->db->query($sql);
2417 dol_syslog(get_class($this).'::setShippingMethod Error ', LOG_DEBUG);
2418 $this->error = $this->db->lasterror();
2424 $this->context = array('shippingmethodupdate'=>1);
2425 $result = $this->call_trigger(strtoupper(get_class($this)).'_MODIFY', $userused);
2426 if ($result < 0) $error++;
2432 $this->db->rollback();
2435 $this->shipping_method_id = ($shipping_method_id == 'NULL') ?null:$shipping_method_id;
2436 $this->db->commit();
2448 public function setWarehouse($warehouse_id)
2450 if (!$this->table_element) {
2451 dol_syslog(get_class($this)."::
setWarehouse was called on objet with property table_element not defined
", LOG_ERR);
2454 if ($warehouse_id < 0) $warehouse_id = 'NULL';
2455 dol_syslog(get_class($this).'::setWarehouse('.$warehouse_id.')');
2457 $sql = "UPDATE
".MAIN_DB_PREFIX.$this->table_element;
2458 $sql .= " SET fk_warehouse =
".$warehouse_id;
2459 $sql .= " WHERE rowid=
".$this->id;
2461 if ($this->db->query($sql)) {
2462 $this->warehouse_id = ($warehouse_id == 'NULL') ?null:$warehouse_id;
2465 dol_syslog(get_class($this).'::setWarehouse Error ', LOG_DEBUG);
2466 $this->error = $this->db->error();
2479 public function setDocModel($user, $modelpdf)
2481 if (!$this->table_element)
2483 dol_syslog(get_class($this)."::
setDocModel was called on objet with property table_element not defined
", LOG_ERR);
2487 $newmodelpdf = dol_trunc($modelpdf, 255);
2489 $sql = "UPDATE
".MAIN_DB_PREFIX.$this->table_element;
2490 $sql .= " SET model_pdf =
'".$this->db->escape($newmodelpdf)."'";
2491 $sql .= " WHERE rowid =
".$this->id;
2493 dol_syslog(get_class($this)."::
setDocModel", LOG_DEBUG);
2494 $resql = $this->db->query($sql);
2497 $this->model_pdf = $modelpdf;
2498 $this->modelpdf = $modelpdf; // For bakward compatibility
2501 dol_print_error($this->db);
2515 public function setBankAccount($fk_account, $notrigger = false, $userused = null)
2519 if (empty($userused)) $userused = $user;
2523 if (!$this->table_element) {
2524 dol_syslog(get_class($this)."::
setBankAccount was called on objet with property table_element not defined
", LOG_ERR);
2529 if ($fk_account < 0) $fk_account = 'NULL';
2530 dol_syslog(get_class($this).'::setBankAccount('.$fk_account.')');
2532 $sql = "UPDATE
".MAIN_DB_PREFIX.$this->table_element;
2533 $sql .= " SET fk_account =
".$fk_account;
2534 $sql .= " WHERE rowid=
".$this->id;
2536 $resql = $this->db->query($sql);
2539 dol_syslog(get_class($this).'::setBankAccount Error '.$sql.' - '.$this->db->error());
2540 $this->error = $this->db->lasterror();
2546 $this->context = array('bankaccountupdate'=>1);
2547 $result = $this->call_trigger(strtoupper(get_class($this)).'_MODIFY', $userused);
2548 if ($result < 0) $error++;
2554 $this->db->rollback();
2557 $this->fk_account = ($fk_account == 'NULL') ?null:$fk_account;
2558 $this->db->commit();
2564 // TODO: Move line related operations to CommonObjectLine?
2566 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2576 public function line_order($renum = false, $rowidorder = 'ASC', $fk_parent_line = true)
2579 if (!$this->table_element_line)
2581 dol_syslog(get_class($this)."::
line_order was called on objet with property table_element_line not defined
", LOG_ERR);
2584 if (!$this->fk_element)
2586 dol_syslog(get_class($this)."::
line_order was called on objet with property fk_element not defined
", LOG_ERR);
2590 // Count number of lines to reorder (according to choice $renum)
2592 $sql = 'SELECT count(rowid) FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2593 $sql .= ' WHERE '.$this->fk_element.'='.$this->id;
2594 if (!$renum) $sql .= ' AND rang = 0';
2595 if ($renum) $sql .= ' AND rang <> 0';
2597 dol_syslog(get_class($this)."::
line_order", LOG_DEBUG);
2598 $resql = $this->db->query($sql);
2601 $row = $this->db->fetch_row($resql);
2603 } else dol_print_error($this->db);
2606 // The goal of this part is to reorder all lines, with all children lines sharing the same counter that parents.
2609 // We first search all lines that are parent lines (for multilevel details lines)
2610 $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2611 $sql .= ' WHERE '.$this->fk_element.' = '.$this->id;
2612 if ($fk_parent_line) $sql .= ' AND fk_parent_line IS NULL';
2613 $sql .= ' ORDER BY rang ASC, rowid '.$rowidorder;
2615 dol_syslog(get_class($this)."::
line_order search all parent lines
", LOG_DEBUG);
2616 $resql = $this->db->query($sql);
2620 $num = $this->db->num_rows($resql);
2623 $row = $this->db->fetch_row($resql);
2624 $rows[] = $row[0]; // Add parent line into array rows
2625 $childrens = $this->getChildrenOfLine($row[0]);
2626 if (!empty($childrens))
2628 foreach ($childrens as $child)
2630 array_push($rows, $child);
2636 // Now we set a new number for each lines (parent and children with children included into parent tree)
2639 foreach ($rows as $key => $row)
2641 $this->updateRangOfLine($row, ($key + 1));
2645 dol_print_error($this->db);
2658 public function getChildrenOfLine($id, $includealltree = 0)
2662 $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2663 $sql .= ' WHERE '.$this->fk_element.' = '.$this->id;
2664 $sql .= ' AND fk_parent_line = '.$id;
2665 $sql .= ' ORDER BY rang ASC';
2667 dol_syslog(get_class($this)."::
getChildrenOfLine search children lines
for line
".$id."", LOG_DEBUG);
2668 $resql = $this->db->query($sql);
2671 if ($this->db->num_rows($resql) > 0) {
2672 while ($row = $this->db->fetch_row($resql)) {
2674 if (!empty($includealltree)) $rows = array_merge($rows, $this->getChildrenOfLine($row[0]), $includealltree);
2681 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2689 public function line_up($rowid, $fk_parent_line = true)
2692 $this->line_order(false, 'ASC', $fk_parent_line);
2695 $rang = $this->getRangOfLine($rowid);
2697 // Update position of line
2698 $this->updateLineUp($rowid, $rang);
2701 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2709 public function line_down($rowid, $fk_parent_line = true)
2712 $this->line_order(false, 'ASC', $fk_parent_line);
2715 $rang = $this->getRangOfLine($rowid);
2717 // Get max value for rang
2718 $max = $this->line_max();
2720 // Update position of line
2721 $this->updateLineDown($rowid, $rang, $max);
2731 public function updateRangOfLine($rowid, $rang)
2733 $fieldposition = 'rang'; // @todo Rename 'rang' into 'position'
2734 if (in_array($this->table_element_line, array('bom_bomline', 'ecm_files', 'emailcollector_emailcollectoraction'))) $fieldposition = 'position';
2736 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET '.$fieldposition.' = '.$rang;
2737 $sql .= ' WHERE rowid = '.$rowid;
2740 if (!$this->db->query($sql))
2742 dol_print_error($this->db);
2746 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2753 public function line_ajaxorder($rows)
2756 $num = count($rows);
2757 for ($i = 0; $i < $num; $i++)
2759 $this->updateRangOfLine($rows[$i], ($i + 1));
2770 public function updateLineUp($rowid, $rang)
2774 $fieldposition = 'rang';
2775 if (in_array($this->table_element_line, array('ecm_files', 'emailcollector_emailcollectoraction'))) $fieldposition = 'position';
2777 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET '.$fieldposition.' = '.$rang;
2778 $sql .= ' WHERE '.$this->fk_element.' = '.$this->id;
2779 $sql .= ' AND rang = '.($rang - 1);
2780 if ($this->db->query($sql))
2782 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET '.$fieldposition.' = '.($rang - 1);
2783 $sql .= ' WHERE rowid = '.$rowid;
2784 if (!$this->db->query($sql))
2786 dol_print_error($this->db);
2789 dol_print_error($this->db);
2802 public function updateLineDown($rowid, $rang, $max)
2806 $fieldposition = 'rang';
2807 if (in_array($this->table_element_line, array('ecm_files', 'emailcollector_emailcollectoraction'))) $fieldposition = 'position';
2809 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET '.$fieldposition.' = '.$rang;
2810 $sql .= ' WHERE '.$this->fk_element.' = '.$this->id;
2811 $sql .= ' AND rang = '.($rang + 1);
2812 if ($this->db->query($sql))
2814 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET '.$fieldposition.' = '.($rang + 1);
2815 $sql .= ' WHERE rowid = '.$rowid;
2816 if (!$this->db->query($sql))
2818 dol_print_error($this->db);
2821 dol_print_error($this->db);
2832 public function getRangOfLine($rowid)
2834 $sql = 'SELECT rang FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2835 $sql .= ' WHERE rowid ='.$rowid;
2838 $resql = $this->db->query($sql);
2841 $row = $this->db->fetch_row($resql);
2852 public function getIdOfLine($rang)
2854 $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2855 $sql .= ' WHERE '.$this->fk_element.' = '.$this->id;
2856 $sql .= ' AND rang = '.$rang;
2857 $resql = $this->db->query($sql);
2860 $row = $this->db->fetch_row($resql);
2865 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2872 public function line_max($fk_parent_line = 0)
2875 $positionfield = 'rang';
2876 if ($this->table_element == 'bom_bom') $positionfield = 'position';
2878 // Search the last rang with fk_parent_line
2879 if ($fk_parent_line)
2881 $sql = 'SELECT max('.$positionfield.') FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2882 $sql .= ' WHERE '.$this->fk_element.' = '.$this->id;
2883 $sql .= ' AND fk_parent_line = '.$fk_parent_line;
2885 dol_syslog(get_class($this)."::
line_max", LOG_DEBUG);
2886 $resql = $this->db->query($sql);
2889 $row = $this->db->fetch_row($resql);
2890 if (!empty($row[0]))
2894 return $this->getRangOfLine($fk_parent_line);
2898 // If not, search the last rang of element
2900 $sql = 'SELECT max('.$positionfield.') FROM '.MAIN_DB_PREFIX.$this->table_element_line;
2901 $sql .= ' WHERE '.$this->fk_element.' = '.$this->id;
2903 dol_syslog(get_class($this)."::
line_max", LOG_DEBUG);
2904 $resql = $this->db->query($sql);
2907 $row = $this->db->fetch_row($resql);
2913 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2920 public function update_ref_ext($ref_ext)
2923 if (!$this->table_element)
2925 dol_syslog(get_class($this)."::
update_ref_ext was called on objet with property table_element not defined
", LOG_ERR);
2929 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
2930 $sql .= " SET ref_ext =
'".$this->db->escape($ref_ext)."'";
2931 $sql .= " WHERE
".(isset($this->table_rowid) ? $this->table_rowid : 'rowid')." =
".$this->id;
2934 if ($this->db->query($sql))
2936 $this->ref_ext = $ref_ext;
2939 $this->error = $this->db->error();
2944 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2952 public function update_note($note, $suffix = '')
2957 if (!$this->table_element)
2959 $this->error = 'update_note was called on objet with property table_element not defined';
2960 dol_syslog(get_class($this)."::
update_note was called on objet with property table_element not defined
", LOG_ERR);
2963 if (!in_array($suffix, array('', '_public', '_private')))
2965 $this->error = 'update_note Parameter suffix must be empty, \'_private\' or \'_public\'';
2966 dol_syslog(get_class($this)."::
update_note Parameter suffix must be empty,
'_private' or
'_public'", LOG_ERR);
2970 $newsuffix = $suffix;
2973 if ($this->table_element == 'product' && $newsuffix == '_private') $newsuffix = '';
2975 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
2976 $sql .= " SET
note".$newsuffix." =
".(!empty($note) ? ("'".$this->db->escape($note)."'") : "NULL
");
2977 $sql .= " ,
".(in_array($this->table_element, array('actioncomm', 'adherent', 'advtargetemailing', 'cronjob', 'establishment')) ? "fk_user_mod
" : "fk_user_modif
")." =
".$user->id;
2978 $sql .= " WHERE rowid =
".$this->id;
2980 dol_syslog(get_class($this)."::
update_note", LOG_DEBUG);
2981 if ($this->db->query($sql))
2983 if ($suffix == '_public') $this->note_public = $note;
2984 elseif ($suffix == '_private') $this->note_private = $note;
2986 $this->note = $note; // deprecated
2987 $this->note_private = $note;
2991 $this->error = $this->db->lasterror();
2996 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3005 public function update_note_public($note)
3008 return $this->update_note($note, '_public');
3011 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3022 public function update_price($exclspec = 0, $roundingadjust = 'none', $nodatabaseupdate = 0, $seller = null)
3025 global $conf, $hookmanager, $action;
3027 $parameters = array('exclspec' => $exclspec, 'roundingadjust' => $roundingadjust, 'nodatabaseupdate' => $nodatabaseupdate, 'seller' => $seller);
3028 $reshook = $hookmanager->executeHooks('updateTotalPrice', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
3030 return 1; // replacement code
3031 } elseif ($reshook < 0) {
3032 return -1; // failure
3033 } // reshook = 0 => execute normal code
3035 // Some external module want no update price after a trigger because they have another method to calculate the total (ex: with an extrafield)
3037 if ($this->element == 'propal')
3038 $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_PROPOSAL
";
3039 elseif ($this->element == 'commande' || $this->element == 'order')
3040 $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_ORDER
";
3041 elseif ($this->element == 'facture' || $this->element == 'invoice')
3042 $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_INVOICE
";
3043 elseif ($this->element == 'facture_fourn' || $this->element == 'supplier_invoice' || $this->element == 'invoice_supplier')
3044 $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_SUPPLIER_INVOICE
";
3045 elseif ($this->element == 'order_supplier' || $this->element == 'supplier_order')
3046 $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_SUPPLIER_ORDER
";
3047 elseif ($this->element == 'supplier_proposal')
3048 $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_SUPPLIER_PROPOSAL
";
3050 if (!empty($MODULE)) {
3051 if (!empty($conf->global->$MODULE)) {
3052 $modsactivated = explode(',', $conf->global->$MODULE);
3053 foreach ($modsactivated as $mod) {
3054 if ($conf->$mod->enabled)
3055 return 1; // update was disabled by specific setup
3060 include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
3062 if ($roundingadjust == '-1') $roundingadjust = 'auto'; // For backward compatibility
3064 $forcedroundingmode = $roundingadjust;
3065 if ($forcedroundingmode == 'auto' && isset($conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND)) $forcedroundingmode = $conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND;
3066 elseif ($forcedroundingmode == 'auto') $forcedroundingmode = '0';
3070 $multicurrency_tx = !empty($this->multicurrency_tx) ? $this->multicurrency_tx : 1;
3072 // Define constants to find lines to sum
3073 $fieldtva = 'total_tva';
3074 $fieldlocaltax1 = 'total_localtax1';
3075 $fieldlocaltax2 = 'total_localtax2';
3076 $fieldup = 'subprice';
3077 if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier')
3082 if ($this->element == 'expensereport')
3084 $fieldup = 'value_unit';
3087 $sql = 'SELECT rowid, qty, '.$fieldup.' as up, remise_percent, total_ht, '.$fieldtva.' as total_tva, total_ttc, '.$fieldlocaltax1.' as total_localtax1, '.$fieldlocaltax2.' as total_localtax2,';
3088 $sql .= ' tva_tx as vatrate, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type, info_bits, product_type';
3089 if ($this->table_element_line == 'facturedet') $sql .= ', situation_percent';
3090 $sql .= ', multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc';
3091 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line;
3092 $sql .= ' WHERE '.$this->fk_element.' = '.$this->id;
3095 $product_field = 'product_type';
3096 if ($this->table_element_line == 'contratdet') $product_field = ''; // contratdet table has no product_type field
3097 if ($product_field) $sql .= ' AND '.$product_field.' <> 9';
3099 $sql .= ' ORDER by rowid'; // We want to be sure to always use same order of line to not change lines differently when option MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND is used
3101 dol_syslog(get_class($this)."::
update_price", LOG_DEBUG);
3102 $resql = $this->db->query($sql);
3105 $this->total_ht = 0;
3106 $this->total_tva = 0;
3107 $this->total_localtax1 = 0;
3108 $this->total_localtax2 = 0;
3109 $this->total_ttc = 0;
3110 $total_ht_by_vats = array();
3111 $total_tva_by_vats = array();
3112 $total_ttc_by_vats = array();
3113 $this->multicurrency_total_ht = 0;
3114 $this->multicurrency_total_tva = 0;
3115 $this->multicurrency_total_ttc = 0;
3117 $num = $this->db->num_rows($resql);
3121 $obj = $this->db->fetch_object($resql);
3123 // Note: There is no check on detail line and no check on total, if $forcedroundingmode = 'none'
3124 $parameters = array('fk_element' => $obj->rowid);
3125 $reshook = $hookmanager->executeHooks('changeRoundingMode', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
3127 if (empty($reshook) && $forcedroundingmode == '0') // Check if data on line are consistent. This may solve lines that were not consistent because set with $forcedroundingmode='auto'
3129 // This part of code is to fix data. We should not call it too often.
3130 $localtax_array = array($obj->localtax1_type, $obj->localtax1_tx, $obj->localtax2_type, $obj->localtax2_tx);
3131 $tmpcal = calcul_price_total($obj->qty, $obj->up, $obj->remise_percent, $obj->vatrate, $obj->localtax1_tx, $obj->localtax2_tx, 0, 'HT', $obj->info_bits, $obj->product_type, $seller, $localtax_array, (isset($obj->situation_percent) ? $obj->situation_percent : 100), $multicurrency_tx);
3133 $diff_when_using_price_ht = price2num($tmpcal[1] - $obj->total_tva, 'MT', 1); // If price was set with tax price adn unit price HT has a low number of digits, then we may have a diff on recalculation from unit price HT.
3134 $diff_on_current_total = price2num($obj->total_ttc - $obj->total_ht - $obj->total_tva - $obj->total_localtax1 - $obj->total_localtax2, 'MT', 1);
3135 //var_dump($obj->total_ht.' '.$obj->total_tva.' '.$obj->total_localtax1.' '.$obj->total_localtax2.' =? '.$obj->total_ttc);
3136 //var_dump($diff_when_using_price_ht.' '.$diff_on_current_total);
3138 if ($diff_when_using_price_ht && $diff_on_current_total)
3140 $sqlfix = "UPDATE
".MAIN_DB_PREFIX.$this->table_element_line." SET
".$fieldtva." =
".$tmpcal[1].", total_ttc =
".$tmpcal[2]." WHERE rowid =
".$obj->rowid;
3141 dol_syslog('We found unconsistent data into detailed line (diff_when_using_price_ht = '.$diff_when_using_price_ht.' and diff_on_current_total = '.$diff_on_current_total.') for line rowid = '.$obj->rowid." (total vat of line calculated=
".$tmpcal[1].", database=
".$obj->total_tva."). We fix the total_vat and total_ttc of line by running sqlfix =
".$sqlfix, LOG_WARNING);
3142 $resqlfix = $this->db->query($sqlfix);
3143 if (!$resqlfix) dol_print_error($this->db, 'Failed to update line');
3144 $obj->total_tva = $tmpcal[1];
3145 $obj->total_ttc = $tmpcal[2];
3149 $this->total_ht += $obj->total_ht; // The field visible at end of line detail
3150 $this->total_tva += $obj->total_tva;
3151 $this->total_localtax1 += $obj->total_localtax1;
3152 $this->total_localtax2 += $obj->total_localtax2;
3153 $this->total_ttc += $obj->total_ttc;
3154 $this->multicurrency_total_ht += $obj->multicurrency_total_ht; // The field visible at end of line detail
3155 $this->multicurrency_total_tva += $obj->multicurrency_total_tva;
3156 $this->multicurrency_total_ttc += $obj->multicurrency_total_ttc;
3158 if (!isset($total_ht_by_vats[$obj->vatrate])) $total_ht_by_vats[$obj->vatrate] = 0;
3159 if (!isset($total_tva_by_vats[$obj->vatrate])) $total_tva_by_vats[$obj->vatrate] = 0;
3160 if (!isset($total_ttc_by_vats[$obj->vatrate])) $total_ttc_by_vats[$obj->vatrate] = 0;
3161 $total_ht_by_vats[$obj->vatrate] += $obj->total_ht;
3162 $total_tva_by_vats[$obj->vatrate] += $obj->total_tva;
3163 $total_ttc_by_vats[$obj->vatrate] += $obj->total_ttc;
3165 if ($forcedroundingmode == '1') // Check if we need adjustement onto line for vat. TODO This works on the company currency but not on multicurrency
3167 $tmpvat = price2num($total_ht_by_vats[$obj->vatrate] * $obj->vatrate / 100, 'MT', 1);
3168 $diff = price2num($total_tva_by_vats[$obj->vatrate] - $tmpvat, 'MT', 1);
3169 //print 'Line '.$i.' rowid='.$obj->rowid.' vat_rate='.$obj->vatrate.' total_ht='.$obj->total_ht.' total_tva='.$obj->total_tva.' total_ttc='.$obj->total_ttc.' total_ht_by_vats='.$total_ht_by_vats[$obj->vatrate].' total_tva_by_vats='.$total_tva_by_vats[$obj->vatrate].' (new calculation = '.$tmpvat.') total_ttc_by_vats='.$total_ttc_by_vats[$obj->vatrate].($diff?" => DIFF
":"")."<br>\
n";
3172 if (abs($diff) > 0.1) {
3173 $errmsg = 'A rounding difference was detected into TOTAL but is too high to be corrected. Some data in your line may be corrupted. Try to edit each line manually.';
3174 dol_syslog($errmsg, LOG_WARNING);
3175 dol_print_error('', $errmsg);
3178 $sqlfix = "UPDATE
".MAIN_DB_PREFIX.$this->table_element_line." SET
".$fieldtva." =
".($obj->total_tva - $diff).", total_ttc =
".($obj->total_ttc - $diff)." WHERE rowid =
".$obj->rowid;
3179 dol_syslog('We found a difference of '.$diff.' for line rowid = '.$obj->rowid.". We fix the total_vat and total_ttc of line by running sqlfix =
".$sqlfix);
3180 $resqlfix = $this->db->query($sqlfix);
3181 if (!$resqlfix) dol_print_error($this->db, 'Failed to update line');
3182 $this->total_tva -= $diff;
3183 $this->total_ttc -= $diff;
3184 $total_tva_by_vats[$obj->vatrate] -= $diff;
3185 $total_ttc_by_vats[$obj->vatrate] -= $diff;
3192 // Add revenue stamp to total
3193 $this->total_ttc += isset($this->revenuestamp) ? $this->revenuestamp : 0;
3194 $this->multicurrency_total_ttc += isset($this->revenuestamp) ? ($this->revenuestamp * $multicurrency_tx) : 0;
3196 // Situations totals
3197 if (!empty($this->situation_cycle_ref) && $this->situation_counter > 1 && method_exists($this, 'get_prev_sits') && $this->type != $this::TYPE_CREDIT_NOTE)
3199 $prev_sits = $this->get_prev_sits();
3201 foreach ($prev_sits as $sit) { // $sit is an object Facture loaded with a fetch.
3202 $this->total_ht -= $sit->total_ht;
3203 $this->total_tva -= $sit->total_tva;
3204 $this->total_localtax1 -= $sit->total_localtax1;
3205 $this->total_localtax2 -= $sit->total_localtax2;
3206 $this->total_ttc -= $sit->total_ttc;
3207 $this->multicurrency_total_ht -= $sit->multicurrency_total_ht;
3208 $this->multicurrency_total_tva -= $sit->multicurrency_total_tva;
3209 $this->multicurrency_total_ttc -= $sit->multicurrency_total_ttc;
3213 $this->db->free($resql);
3215 // Now update global field total_ht, total_ttc and tva
3216 $fieldht = 'total_ht';
3218 $fieldlocaltax1 = 'localtax1';
3219 $fieldlocaltax2 = 'localtax2';
3220 $fieldttc = 'total_ttc';
3221 // Specific code for backward compatibility with old field names
3222 if ($this->element == 'facture' || $this->element == 'facturerec') $fieldht = 'total';
3223 if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') $fieldtva = 'total_tva';
3224 if ($this->element == 'propal') $fieldttc = 'total';
3225 if ($this->element == 'expensereport') $fieldtva = 'total_tva';
3226 if ($this->element == 'supplier_proposal') $fieldttc = 'total';
3228 if (empty($nodatabaseupdate))
3230 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET';
3231 $sql .= " ".$fieldht."=
'".price2num($this->total_ht)."',
";
3232 $sql .= " ".$fieldtva."=
'".price2num($this->total_tva)."',
";
3233 $sql .= " ".$fieldlocaltax1."=
'".price2num($this->total_localtax1)."',
";
3234 $sql .= " ".$fieldlocaltax2."=
'".price2num($this->total_localtax2)."',
";
3235 $sql .= " ".$fieldttc."=
'".price2num($this->total_ttc)."'";
3236 $sql .= ", multicurrency_total_ht=
'".price2num($this->multicurrency_total_ht, 'MT
', 1)."'";
3237 $sql .= ", multicurrency_total_tva=
'".price2num($this->multicurrency_total_tva, 'MT
', 1)."'";
3238 $sql .= ", multicurrency_total_ttc=
'".price2num($this->multicurrency_total_ttc, 'MT
', 1)."'";
3239 $sql .= ' WHERE rowid = '.$this->id;
3242 dol_syslog(get_class($this)."::
update_price", LOG_DEBUG);
3243 $resql = $this->db->query($sql);
3247 $this->error = $this->db->lasterror();
3248 $this->errors[] = $this->db->lasterror();
3259 dol_print_error($this->db, 'Bad request in update_price');
3264 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3273 public function add_object_linked($origin = null, $origin_id = null)
3276 $origin = (!empty($origin) ? $origin : $this->origin);
3277 $origin_id = (!empty($origin_id) ? $origin_id : $this->origin_id);
3280 if ($origin == 'order') $origin = 'commande';
3281 if ($origin == 'invoice') $origin = 'facture';
3282 if ($origin == 'invoice_template') $origin = 'facturerec';
3283 if ($origin == 'supplierorder') $origin = 'order_supplier';
3286 $sql = "INSERT INTO
".MAIN_DB_PREFIX."element_element (
";
3287 $sql .= "fk_source
";
3288 $sql .= ", sourcetype
";
3289 $sql .= ", fk_target
";
3290 $sql .= ", targettype
";
3291 $sql .= ") VALUES (
";
3293 $sql .= ",
'".$this->db->escape($origin)."'";
3294 $sql .= ",
".$this->id;
3295 $sql .= ",
'".$this->db->escape($this->element)."'";
3299 if ($this->db->query($sql))
3301 $this->db->commit();
3304 $this->error = $this->db->lasterror();
3305 $this->db->rollback();
3332 public function fetchObjectLinked($sourceid = null, $sourcetype = '', $targetid = null, $targettype = '', $clause = 'OR', $alsosametype = 1, $orderby = 'sourcetype', $loadalsoobjects = 1)
3336 $this->linkedObjectsIds = array();
3337 $this->linkedObjects = array();
3339 $justsource = false;
3340 $justtarget = false;
3341 $withtargettype = false;
3342 $withsourcetype = false;
3344 if (!empty($sourceid) && !empty($sourcetype) && empty($targetid))
3346 $justsource = true; // the source (id and type) is a search criteria
3347 if (!empty($targettype)) $withtargettype = true;
3349 if (!empty($targetid) && !empty($targettype) && empty($sourceid))
3351 $justtarget = true; // the target (id and type) is a search criteria
3352 if (!empty($sourcetype)) $withsourcetype = true;
3355 $sourceid = (!empty($sourceid) ? $sourceid : $this->id);
3356 $targetid = (!empty($targetid) ? $targetid : $this->id);
3357 $sourcetype = (!empty($sourcetype) ? $sourcetype : $this->element);
3358 $targettype = (!empty($targettype) ? $targettype : $this->element);
3360 /*if (empty($sourceid) && empty($targetid))
3362 dol_syslog('Bad usage of function. No source nor target id defined (nor as parameter nor as object id)', LOG_ERR);
3366 // Links between objects are stored in table element_element
3367 $sql = 'SELECT rowid, fk_source, sourcetype, fk_target, targettype';
3368 $sql .= ' FROM '.MAIN_DB_PREFIX.'element_element';
3370 if ($justsource || $justtarget)
3374 $sql .= "fk_source =
".$sourceid." AND sourcetype =
'".$this->db->escape($sourcetype)."'";
3375 if ($withtargettype) $sql .= " AND targettype =
'".$this->db->escape($targettype)."'";
3376 } elseif ($justtarget)
3378 $sql .= "fk_target =
".$targetid." AND targettype =
'".$this->db->escape($targettype)."'";
3379 if ($withsourcetype) $sql .= " AND sourcetype =
'".$this->db->escape($sourcetype)."'";
3382 $sql .= "(fk_source =
".$sourceid." AND sourcetype =
'".$this->db->escape($sourcetype)."')
";
3383 $sql .= " ".$clause." (fk_target =
".$targetid." AND targettype =
'".$this->db->escape($targettype)."')
";
3385 $sql .= ' ORDER BY '.$orderby;
3387 dol_syslog(get_class($this)."::fetchObjectLink
", LOG_DEBUG);
3388 $resql = $this->db->query($sql);
3391 $num = $this->db->num_rows($resql);
3395 $obj = $this->db->fetch_object($resql);
3396 if ($justsource || $justtarget)
3400 $this->linkedObjectsIds[$obj->targettype][$obj->rowid] = $obj->fk_target;
3401 } elseif ($justtarget)
3403 $this->linkedObjectsIds[$obj->sourcetype][$obj->rowid] = $obj->fk_source;
3406 if ($obj->fk_source == $sourceid && $obj->sourcetype == $sourcetype)
3408 $this->linkedObjectsIds[$obj->targettype][$obj->rowid] = $obj->fk_target;
3410 if ($obj->fk_target == $targetid && $obj->targettype == $targettype)
3412 $this->linkedObjectsIds[$obj->sourcetype][$obj->rowid] = $obj->fk_source;
3418 if (!empty($this->linkedObjectsIds))
3420 $tmparray = $this->linkedObjectsIds;
3421 foreach ($tmparray as $objecttype => $objectids) // $objecttype is a module name ('facture', 'mymodule', ...) or a module name with a suffix ('project_task', 'mymodule_myobj', ...)
3423 // Parse element/subelement (ex: project_task, cabinetmed_consultation, ...)
3424 $module = $element = $subelement = $objecttype;
3426 if ($objecttype != 'supplier_proposal' && $objecttype != 'order_supplier' && $objecttype != 'invoice_supplier'
3427 && preg_match('/^([^_]+)_([^_]+)/i', $objecttype, $regs))
3429 $module = $element = $regs[1];
3430 $subelement = $regs[2];
3433 $classpath = $element.'/class';
3434 // To work with non standard classpath or module name
3435 if ($objecttype == 'facture') {
3436 $classpath = 'compta/facture/class';
3437 } elseif ($objecttype == 'facturerec') {
3438 $classpath = 'compta/facture/class'; $module = 'facture';
3439 } elseif ($objecttype == 'propal') {
3440 $classpath = 'comm/propal/class';
3441 } elseif ($objecttype == 'supplier_proposal') {
3442 $classpath = 'supplier_proposal/class';
3443 } elseif ($objecttype == 'shipping') {
3444 $classpath = 'expedition/class'; $subelement = 'expedition'; $module = 'expedition_bon';
3445 } elseif ($objecttype == 'delivery') {
3446 $classpath = 'delivery/class'; $subelement = 'delivery'; $module = 'delivery_note';
3447 } elseif ($objecttype == 'invoice_supplier' || $objecttype == 'order_supplier') {
3448 $classpath = 'fourn/class'; $module = 'fournisseur';
3449 } elseif ($objecttype == 'fichinter') {
3450 $classpath = 'fichinter/class'; $subelement = 'fichinter'; $module = 'ficheinter';
3451 } elseif ($objecttype == 'subscription') {
3452 $classpath = 'adherents/class'; $module = 'adherent';
3453 } elseif ($objecttype == 'contact') {
3454 $module = 'societe';
3458 $classfile = strtolower($subelement); $classname = ucfirst($subelement);
3460 if ($objecttype == 'order') {
3461 $classfile = 'commande'; $classname = 'Commande';
3462 } elseif ($objecttype == 'invoice_supplier') {
3463 $classfile = 'fournisseur.facture'; $classname = 'FactureFournisseur';
3464 } elseif ($objecttype == 'order_supplier') {
3465 $classfile = 'fournisseur.commande'; $classname = 'CommandeFournisseur';
3466 } elseif ($objecttype == 'supplier_proposal') {
3467 $classfile = 'supplier_proposal'; $classname = 'SupplierProposal';
3468 } elseif ($objecttype == 'facturerec') {
3469 $classfile = 'facture-rec'; $classname = 'FactureRec';
3470 } elseif ($objecttype == 'subscription') {
3471 $classfile = 'subscription'; $classname = 'Subscription';
3472 } elseif ($objecttype == 'project' || $objecttype == 'projet') {
3473 $classpath = 'projet/class'; $classfile = 'project'; $classname = 'Project';
3476 // Here $module, $classfile and $classname are set
3477 if ($conf->$module->enabled && (($element != $this->element) || $alsosametype))
3479 if ($loadalsoobjects)
3481 dol_include_once('/'.$classpath.'/'.$classfile.'.class.php');
3482 //print '/'.$classpath.'/'.$classfile.'.class.php '.class_exists($classname);
3483 if (class_exists($classname))
3485 foreach ($objectids as $i => $objectid) // $i is rowid into llx_element_element
3487 $object = new $classname($this->db);
3488 $ret = $object->fetch($objectid);
3491 $this->linkedObjects[$objecttype][$i] = $object;
3497 unset($this->linkedObjectsIds[$objecttype]);
3503 dol_print_error($this->db);
3518 public function updateObjectLinked($sourceid = null, $sourcetype = '', $targetid = null, $targettype = '')
3520 $updatesource = false;
3521 $updatetarget = false;
3523 if (!empty($sourceid) && !empty($sourcetype) && empty($targetid) && empty($targettype)) $updatesource = true;
3524 elseif (empty($sourceid) && empty($sourcetype) && !empty($targetid) && !empty($targettype)) $updatetarget = true;
3526 $sql = "UPDATE
".MAIN_DB_PREFIX."element_element SET
";
3529 $sql .= "fk_source =
".$sourceid;
3530 $sql .= ", sourcetype =
'".$this->db->escape($sourcetype)."'";
3531 $sql .= " WHERE fk_target =
".$this->id;
3532 $sql .= " AND targettype =
'".$this->db->escape($this->element)."'";
3533 } elseif ($updatetarget)
3535 $sql .= "fk_target =
".$targetid;
3536 $sql .= ", targettype =
'".$this->db->escape($targettype)."'";
3537 $sql .= " WHERE fk_source =
".$this->id;
3538 $sql .= " AND sourcetype =
'".$this->db->escape($this->element)."'";
3542 if ($this->db->query($sql))
3546 $this->error = $this->db->lasterror();
3562 public function deleteObjectLinked($sourceid = null, $sourcetype = '', $targetid = null, $targettype = '', $rowid = '')
3564 $deletesource = false;
3565 $deletetarget = false;
3567 if (!empty($sourceid) && !empty($sourcetype) && empty($targetid) && empty($targettype)) $deletesource = true;
3568 elseif (empty($sourceid) && empty($sourcetype) && !empty($targetid) && !empty($targettype)) $deletetarget = true;
3570 $sourceid = (!empty($sourceid) ? $sourceid : $this->id);
3571 $sourcetype = (!empty($sourcetype) ? $sourcetype : $this->element);
3572 $targetid = (!empty($targetid) ? $targetid : $this->id);
3573 $targettype = (!empty($targettype) ? $targettype : $this->element);
3575 $sql = "DELETE FROM
".MAIN_DB_PREFIX."element_element
";
3579 $sql .= " rowid =
".$rowid;
3583 $sql .= " fk_source =
".$sourceid." AND sourcetype =
'".$this->db->escape($sourcetype)."'";
3584 $sql .= " AND fk_target =
".$this->id." AND targettype =
'".$this->db->escape($this->element)."'";
3585 } elseif ($deletetarget)
3587 $sql .= " fk_target =
".$targetid." AND targettype =
'".$this->db->escape($targettype)."'";
3588 $sql .= " AND fk_source =
".$this->id." AND sourcetype =
'".$this->db->escape($this->element)."'";
3590 $sql .= " (fk_source =
".$this->id." AND sourcetype =
'".$this->db->escape($this->element)."')
";
3592 $sql .= " (fk_target =
".$this->id." AND targettype =
'".$this->db->escape($this->element)."')
";
3597 if ($this->db->query($sql))
3601 $this->error = $this->db->lasterror();
3602 $this->errors[] = $this->error;
3616 public function setStatut($status, $elementId = null, $elementType = '', $trigkey = '')
3618 global $user, $langs, $conf;
3620 $savElementId = $elementId; // To be used later to know if we were using the method using the id of this or not.
3622 $elementId = (!empty($elementId) ? $elementId : $this->id);
3623 $elementTable = (!empty($elementType) ? $elementType : $this->table_element);
3627 $fieldstatus = "fk_statut
";
3628 if ($elementTable == 'facture_rec') $fieldstatus = "suspended
";
3629 if ($elementTable == 'mailing') $fieldstatus = "statut
";
3630 if ($elementTable == 'cronjob') $fieldstatus = "status
";
3631 if ($elementTable == 'user') $fieldstatus = "statut
";
3632 if ($elementTable == 'expensereport') $fieldstatus = "fk_statut
";
3633 if ($elementTable == 'commande_fournisseur_dispatch') $fieldstatus = "status
";
3634 if (is_array($this->fields) && array_key_exists('status', $this->fields)) $fieldstatus = 'status';
3636 $sql = "UPDATE
".MAIN_DB_PREFIX.$elementTable;
3637 $sql .= " SET
".$fieldstatus." =
".$status;
3638 // If status = 1 = validated, update also fk_user_valid
3639 if ($status == 1 && $elementTable == 'expensereport') $sql .= ", fk_user_valid =
".$user->id;
3640 $sql .= " WHERE rowid=
".$elementId;
3642 dol_syslog(get_class($this)."::
setStatut", LOG_DEBUG);
3643 if ($this->db->query($sql))
3647 // Try autoset of trigkey
3648 if (empty($trigkey))
3650 if ($this->element == 'supplier_proposal' && $status == 2) $trigkey = 'SUPPLIER_PROPOSAL_SIGN'; // 2 = SupplierProposal::STATUS_SIGNED. Can't use constant into this generic class
3651 if ($this->element == 'supplier_proposal' && $status == 3) $trigkey = 'SUPPLIER_PROPOSAL_REFUSE'; // 3 = SupplierProposal::STATUS_REFUSED. Can't use constant into this generic class
3652 if ($this->element == 'supplier_proposal' && $status == 4) $trigkey = 'SUPPLIER_PROPOSAL_CLOSE'; // 4 = SupplierProposal::STATUS_CLOSED. Can't use constant into this generic class
3653 if ($this->element == 'fichinter' && $status == 3) $trigkey = 'FICHINTER_CLASSIFY_DONE';
3654 if ($this->element == 'fichinter' && $status == 2) $trigkey = 'FICHINTER_CLASSIFY_BILLED';
3655 if ($this->element == 'fichinter' && $status == 1) $trigkey = 'FICHINTER_CLASSIFY_UNBILLED';
3661 $result = $this->call_trigger($trigkey, $user);
3662 if ($result < 0) $error++;
3663 // End call triggers
3668 $this->db->commit();
3670 if (empty($savElementId)) // If the element we update was $this (so $elementId is null)
3672 $this->statut = $status;
3673 $this->status = $status;
3678 $this->db->rollback();
3679 dol_syslog(get_class($this)."::
setStatut ".$this->error, LOG_ERR);
3683 $this->error = $this->db->lasterror();
3684 $this->db->rollback();
3697 public function getCanvas($id = 0, $ref = '')
3701 if (empty($id) && empty($ref)) return 0;
3702 if (!empty($conf->global->MAIN_DISABLE_CANVAS)) return 0; // To increase speed. Not enabled by default.
3707 $sql = "SELECT rowid, canvas
";
3708 $sql .= " FROM
".MAIN_DB_PREFIX.$this->table_element;
3709 $sql .= " WHERE entity IN (
".getEntity($this->element).")
";
3710 if (!empty($id)) $sql .= " AND rowid =
".$id;
3711 if (!empty($ref)) $sql .= " AND ref =
'".$this->db->escape($ref)."'";
3713 $resql = $this->db->query($sql);
3716 $obj = $this->db->fetch_object($resql);
3719 $this->canvas = $obj->canvas;
3723 dol_print_error($this->db);
3735 public function getSpecialCode($lineid)
3737 $sql = 'SELECT special_code FROM '.MAIN_DB_PREFIX.$this->table_element_line;
3738 $sql .= ' WHERE rowid = '.$lineid;
3739 $resql = $this->db->query($sql);
3742 $row = $this->db->fetch_row($resql);
3754 public function isObjectUsed($id = 0)
3758 if (empty($id)) $id = $this->id;
3761 if (!isset($this->childtables) || !is_array($this->childtables) || count($this->childtables) == 0)
3763 dol_print_error('Called isObjectUsed on a class with property this->childtables not defined');
3767 $arraytoscan = $this->childtables;
3768 // For backward compatibility, we check if array is old format array('table1', 'table2', ...)
3769 $tmparray = array_keys($this->childtables);
3770 if (is_numeric($tmparray[0]))
3772 $arraytoscan = array_flip($this->childtables);
3775 // Test if child exists
3777 foreach ($arraytoscan as $table => $elementname)
3779 //print $id.'-'.$table.'-'.$elementname.'<br>';
3780 // Check if third party can be deleted
3781 $sql = "SELECT COUNT(*) as nb from
".MAIN_DB_PREFIX.$table;
3782 $sql .= " WHERE
".$this->fk_element." =
".$id;
3783 $resql = $this->db->query($sql);
3786 $obj = $this->db->fetch_object($resql);
3789 $langs->load("errors
");
3790 //print 'Found into table '.$table.', type '.$langs->transnoentitiesnoconv($elementname).', haschild='.$haschild;
3791 $haschild += $obj->nb;
3792 if (is_numeric($elementname)) // old usage
3794 $this->errors[] = $langs->trans("ErrorRecordHasAtLeastOneChildOfType
", $table);
3795 } else // new usage: $elementname=Translation key
3797 $this->errors[] = $langs->trans("ErrorRecordHasAtLeastOneChildOfType
", $langs->transnoentitiesnoconv($elementname));
3799 break; // We found at least one, we stop here
3802 $this->errors[] = $this->db->lasterror();
3808 $this->errors[] = "ErrorRecordHasChildren
";
3819 public function hasProductsOrServices($predefined = -1)
3823 foreach ($this->lines as $key => $val)
3826 if ($predefined == -1) $qualified = 1;
3827 if ($predefined == 1 && $val->fk_product > 0) $qualified = 1;
3828 if ($predefined == 0 && $val->fk_product <= 0) $qualified = 1;
3829 if ($predefined == 2 && $val->fk_product > 0 && $val->product_type == 0) $qualified = 1;
3830 if ($predefined == 3 && $val->fk_product > 0 && $val->product_type == 1) $qualified = 1;
3831 if ($qualified) $nb++;
3833 dol_syslog(get_class($this).'::hasProductsOrServices we found '.$nb.' qualified lines of products/servcies');
3842 public function getTotalDiscount()
3844 $total_discount = 0.00;
3846 $sql = "SELECT subprice as pu_ht, qty, remise_percent, total_ht
";
3847 $sql .= " FROM
".MAIN_DB_PREFIX.$this->table_element."det
";
3848 $sql .= " WHERE
".$this->fk_element." =
".$this->id;
3850 dol_syslog(get_class($this).'::getTotalDiscount', LOG_DEBUG);
3851 $resql = $this->db->query($sql);
3854 $num = $this->db->num_rows($resql);
3858 $obj = $this->db->fetch_object($resql);
3860 $pu_ht = $obj->pu_ht;
3862 $total_ht = $obj->total_ht;
3864 $total_discount_line = floatval(price2num(($pu_ht * $qty) - $total_ht, 'MT'));
3865 $total_discount += $total_discount_line;
3871 //print $total_discount; exit;
3872 return price2num($total_discount);
3882 public function getTotalWeightVolume()
3886 // defined for shipment only
3888 // defined for shipment only
3891 foreach ($this->lines as $line)
3893 if (isset($line->qty_asked))
3895 if (empty($totalOrdered)) $totalOrdered = 0; // Avoid warning because $totalOrdered is ''
3896 $totalOrdered += $line->qty_asked; // defined for shipment only
3898 if (isset($line->qty_shipped))
3900 if (empty($totalToShip)) $totalToShip = 0; // Avoid warning because $totalToShip is ''
3901 $totalToShip += $line->qty_shipped; // defined for shipment only
3902 } elseif ($line->element == 'commandefournisseurdispatch' && isset($line->qty))
3904 if (empty($totalToShip)) $totalToShip = 0;
3905 $totalToShip += $line->qty; // defined for reception only
3908 // Define qty, weight, volume, weight_units, volume_units
3909 if ($this->element == 'shipping') {
3911 $qty = $line->qty_shipped ? $line->qty_shipped : 0;
3913 $qty = $line->qty ? $line->qty : 0;
3916 $weight = $line->weight ? $line->weight : 0;
3917 ($weight == 0 && !empty($line->product->weight)) ? $weight = $line->product->weight : 0;
3918 $volume = $line->volume ? $line->volume : 0;
3919 ($volume == 0 && !empty($line->product->volume)) ? $volume = $line->product->volume : 0;
3921 $weight_units = $line->weight_units;
3922 ($weight_units == 0 && !empty($line->product->weight_units)) ? $weight_units = $line->product->weight_units : 0;
3923 $volume_units = $line->volume_units;
3924 ($volume_units == 0 && !empty($line->product->volume_units)) ? $volume_units = $line->product->volume_units : 0;
3928 if (!empty($weight_units)) $weightUnit = $weight_units;
3929 if (!empty($volume_units)) $volumeUnit = $volume_units;
3931 if (empty($totalWeight)) $totalWeight = 0; // Avoid warning because $totalWeight is ''
3932 if (empty($totalVolume)) $totalVolume = 0; // Avoid warning because $totalVolume is ''
3934 //var_dump($line->volume_units);
3935 if ($weight_units < 50) // < 50 means a standard unit (power of 10 of official unit), > 50 means an exotic unit (like inch)
3937 $trueWeightUnit = pow(10, $weightUnit);
3938 $totalWeight += $weight * $qty * $trueWeightUnit;
3940 if ($weight_units == 99) {
3941 // conversion 1 Pound = 0.45359237 KG
3942 $trueWeightUnit = 0.45359237;
3943 $totalWeight += $weight * $qty * $trueWeightUnit;
3944 } elseif ($weight_units == 98) {
3945 // conversion 1 Ounce = 0.0283495 KG
3946 $trueWeightUnit = 0.0283495;
3947 $totalWeight += $weight * $qty * $trueWeightUnit;
3949 $totalWeight += $weight * $qty; // This may be wrong if we mix different units
3952 if ($volume_units < 50) // >50 means a standard unit (power of 10 of official unit), > 50 means an exotic unit (like inch)
3954 //print $line->volume."x
".$line->volume_units."x
".($line->volume_units < 50)."x
".$volumeUnit;
3955 $trueVolumeUnit = pow(10, $volumeUnit);
3956 //print $line->volume;
3957 $totalVolume += $volume * $qty * $trueVolumeUnit;
3959 $totalVolume += $volume * $qty; // This may be wrong if we mix different units
3963 return array('weight'=>$totalWeight, 'volume'=>$totalVolume, 'ordered'=>$totalOrdered, 'toship'=>$totalToShip);
3972 public function setExtraParameters()
3976 $extraparams = (!empty($this->extraparams) ? json_encode($this->extraparams) : null);
3978 $sql = "UPDATE
".MAIN_DB_PREFIX.$this->table_element;
3979 $sql .= " SET extraparams =
".(!empty($extraparams) ? "'".$this->db->escape($extraparams)."'" : "null
");
3980 $sql .= " WHERE rowid =
".$this->id;
3983 $resql = $this->db->query($sql);
3986 $this->error = $this->db->lasterror();
3987 $this->db->rollback();
3990 $this->db->commit();
3996 // --------------------
3997 // TODO: All functions here must be redesigned and moved as they are not business functions but output functions
3998 // --------------------
4000 /* This is to show add lines */
4011 public function formAddObjectLine($dateSelector, $seller, $buyer, $defaulttpldir = '/core/tpl')
4013 global $conf, $user, $langs, $object, $hookmanager, $extrafields;
4017 if (!is_object($extrafields))
4019 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
4020 $extrafields = new ExtraFields($this->db);
4022 $extrafields->fetch_name_optionals_label($this->table_element_line);
4024 // Output template part (modules that overwrite templates must declare this into descriptor)
4025 // Use global variables + $dateSelector + $seller and $buyer
4026 // Note: This is deprecated. If you need to overwrite the tpl file, use instead the hook 'formAddObjectLine'.
4027 $dirtpls = array_merge($conf->modules_parts['tpl'], array($defaulttpldir));
4028 foreach ($dirtpls as $module => $reldir)
4030 if (!empty($module))
4032 $tpl = dol_buildpath($reldir.'/objectline_create.tpl.php');
4034 $tpl = DOL_DOCUMENT_ROOT.$reldir.'/objectline_create.tpl.php';
4037 if (empty($conf->file->strict_mode)) {
4038 $res = @include $tpl;
4040 $res = include $tpl; // for debug
4048 /* This is to show array of line of details */
4065 public function printObjectLines($action, $seller, $buyer, $selected = 0, $dateSelector = 0, $defaulttpldir = '/core/tpl')
4067 global $conf, $hookmanager, $langs, $user, $form, $extrafields, $object;
4068 // TODO We should not use global var for this
4069 global $inputalsopricewithtax, $usemargins, $disableedit, $disablemove, $disableremove, $outputalsopricetotalwithtax;
4071 // Define usemargins
4073 if (!empty($conf->margin->enabled) && !empty($this->element) && in_array($this->element, array('facture', 'facturerec', 'propal', 'commande'))) $usemargins = 1;
4075 $num = count($this->lines);
4078 if (!is_object($extrafields))
4080 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
4081 $extrafields = new ExtraFields($this->db);
4083 $extrafields->fetch_name_optionals_label($this->table_element_line);
4085 $parameters = array('num'=>$num, 'dateSelector'=>$dateSelector, 'seller'=>$seller, 'buyer'=>$buyer, 'selected'=>$selected, 'table_element_line'=>$this->table_element_line);
4086 $reshook = $hookmanager->executeHooks('printObjectLineTitle', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
4087 if (empty($reshook))
4089 // Output template part (modules that overwrite templates must declare this into descriptor)
4090 // Use global variables + $dateSelector + $seller and $buyer
4091 // Note: This is deprecated. If you need to overwrite the tpl file, use instead the hook.
4092 $dirtpls = array_merge($conf->modules_parts['tpl'], array($defaulttpldir));
4093 foreach ($dirtpls as $module => $reldir)
4095 if (!empty($module))
4097 $tpl = dol_buildpath($reldir.'/objectline_title.tpl.php');
4099 $tpl = DOL_DOCUMENT_ROOT.$reldir.'/objectline_title.tpl.php';
4101 if (empty($conf->file->strict_mode)) {
4102 $res = @include $tpl;
4104 $res = include $tpl; // for debug
4113 foreach ($this->lines as $line)
4116 $line->fetch_optionals();
4118 //if (is_object($hookmanager) && (($line->product_type == 9 && ! empty($line->special_code)) || ! empty($line->fk_parent_line)))
4119 if (is_object($hookmanager)) // Old code is commented on preceding line.
4121 if (empty($line->fk_parent_line))
4123 $parameters = array('line'=>$line, 'num'=>$num, 'i'=>$i, 'dateSelector'=>$dateSelector, 'seller'=>$seller, 'buyer'=>$buyer, 'selected'=>$selected, 'table_element_line'=>$line->table_element);
4124 $reshook = $hookmanager->executeHooks('printObjectLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
4126 $parameters = array('line'=>$line, 'num'=>$num, 'i'=>$i, 'dateSelector'=>$dateSelector, 'seller'=>$seller, 'buyer'=>$buyer, 'selected'=>$selected, 'table_element_line'=>$line->table_element, 'fk_parent_line'=>$line->fk_parent_line);
4127 $reshook = $hookmanager->executeHooks('printObjectSubLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
4130 if (empty($reshook))
4132 $this->printObjectLine($action, $line, '', $num, $i, $dateSelector, $seller, $buyer, $selected, $extrafields, $defaulttpldir);
4157 public function printObjectLine($action, $line, $var, $num, $i, $dateSelector, $seller, $buyer, $selected = 0, $extrafields = null, $defaulttpldir = '/core/tpl')
4159 global $conf, $langs, $user, $object, $hookmanager;
4161 global $object_rights, $disableedit, $disablemove, $disableremove; // TODO We should not use global var for this !
4163 $object_rights = $this->getRights();
4165 $element = $this->element;
4167 $text = ''; $description = '';
4169 // Line in view mode
4170 if ($action != 'editline' || $selected != $line->id)
4173 if ($line->fk_product > 0)
4175 $product_static = new Product($this->db);
4176 $product_static->fetch($line->fk_product);
4178 $product_static->ref = $line->ref; //can change ref in hook
4179 $product_static->label = $line->label; //can change label in hook
4181 $text = $product_static->getNomUrl(1);
4183 // Define output language and label
4184 if (!empty($conf->global->MAIN_MULTILANGS))
4186 if (property_exists($this, 'socid') && !is_object($this->thirdparty))
4188 dol_print_error('', 'Error: Method printObjectLine was called on an object and object->fetch_thirdparty was not done before');
4192 $prod = new Product($this->db);
4193 $prod->fetch($line->fk_product);
4195 $outputlangs = $langs;
4197 if (empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09');
4198 if (!empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE) && empty($newlang) && is_object($this->thirdparty)) $newlang = $this->thirdparty->default_lang; // To use language of customer
4199 if (!empty($newlang))
4201 $outputlangs = new Translate("", $conf);
4202 $outputlangs->setDefaultLang($newlang);
4205 $label = (!empty($prod->multilangs[$outputlangs->defaultlang]["label
"])) ? $prod->multilangs[$outputlangs->defaultlang]["label
"] : $line->product_label;
4207 $label = $line->product_label;
4210 $text .= ' - '.(!empty($line->label) ? $line->label : $label);
4211 $description .= (!empty($conf->global->PRODUIT_DESC_IN_FORM) ? '' : dol_htmlentitiesbr($line->description)); // Description is what to show on popup. We shown nothing if already into desc.
4214 $line->pu_ttc = price2num($line->subprice * (1 + ($line->tva_tx / 100)), 'MU');
4216 // Output template part (modules that overwrite templates must declare this into descriptor)
4217 // Use global variables + $dateSelector + $seller and $buyer
4218 // Note: This is deprecated. If you need to overwrite the tpl file, use instead the hook printObjectLine and printObjectSubLine.
4219 $dirtpls = array_merge($conf->modules_parts['tpl'], array($defaulttpldir));
4220 foreach ($dirtpls as $module => $reldir)
4222 if (!empty($module))
4224 $tpl = dol_buildpath($reldir.'/objectline_view.tpl.php');
4226 $tpl = DOL_DOCUMENT_ROOT.$reldir.'/objectline_view.tpl.php';
4229 if (empty($conf->file->strict_mode)) {
4230 $res = @include $tpl;
4232 $res = include $tpl; // for debug
4238 // Line in update mode
4239 if ($this->statut == 0 && $action == 'editline' && $selected == $line->id)
4241 $label = (!empty($line->label) ? $line->label : (($line->fk_product > 0) ? $line->product_label : ''));
4243 $line->pu_ttc = price2num($line->subprice * (1 + ($line->tva_tx / 100)), 'MU');
4245 // Output template part (modules that overwrite templates must declare this into descriptor)
4246 // Use global variables + $dateSelector + $seller and $buyer
4247 // Note: This is deprecated. If you need to overwrite the tpl file, use instead the hook printObjectLine and printObjectSubLine.
4248 $dirtpls = array_merge($conf->modules_parts['tpl'], array($defaulttpldir));
4249 foreach ($dirtpls as $module => $reldir)
4251 if (!empty($module))
4253 $tpl = dol_buildpath($reldir.'/objectline_edit.tpl.php');
4255 $tpl = DOL_DOCUMENT_ROOT.$reldir.'/objectline_edit.tpl.php';
4258 if (empty($conf->file->strict_mode)) {
4259 $res = @include $tpl;
4261 $res = include $tpl; // for debug
4269 /* This is to show array of line of details of source object */
4282 public function printOriginLinesList($restrictlist = '', $selectedLines = array())
4284 global $langs, $hookmanager, $conf, $form;
4286 print '<tr class="liste_titre
">';
4287 print '<td>'.$langs->trans('Ref').'</td>';
4288 print '<td>'.$langs->trans('Description').'</td>';
4289 print '<td class="right
">'.$langs->trans('VATRate').'</td>';
4290 print '<td class="right
">'.$langs->trans('PriceUHT').'</td>';
4291 if (!empty($conf->multicurrency->enabled)) print '<td class="right
">'.$langs->trans('PriceUHTCurrency').'</td>';
4292 print '<td class="right
">'.$langs->trans('Qty').'</td>';
4293 if (!empty($conf->global->PRODUCT_USE_UNITS))
4295 print '<td class="left
">'.$langs->trans('Unit').'</td>';
4297 print '<td class="right
">'.$langs->trans('ReductionShort').'</td>';
4298 print '<td class="center
">'.$form->showCheckAddButtons('checkforselect', 1).'</td>';
4302 if (!empty($this->lines))
4304 foreach ($this->lines as $line)
4306 if (is_object($hookmanager) && (($line->product_type == 9 && !empty($line->special_code)) || !empty($line->fk_parent_line)))
4308 if (empty($line->fk_parent_line))
4310 $parameters = array('line'=>$line, 'i'=>$i);
4312 $hookmanager->executeHooks('printOriginObjectLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
4315 $this->printOriginLine($line, '', $restrictlist, '/core/tpl', $selectedLines);
4336 public function printOriginLine($line, $var, $restrictlist = '', $defaulttpldir = '/core/tpl', $selectedLines = array())
4338 global $langs, $conf;
4341 if (!empty($line->date_start))
4343 $date_start = $line->date_start;
4345 $date_start = $line->date_debut_prevue;
4346 if ($line->date_debut_reel) $date_start = $line->date_debut_reel;
4348 if (!empty($line->date_end))
4350 $date_end = $line->date_end;
4352 $date_end = $line->date_fin_prevue;
4353 if ($line->date_fin_reel) $date_end = $line->date_fin_reel;
4356 $this->tpl['id'] = $line->id;
4358 $this->tpl['label'] = '';
4359 if (!empty($line->fk_parent_line)) $this->tpl['label'] .= img_picto('', 'rightarrow');
4361 if (($line->info_bits & 2) == 2) // TODO Not sure this is used for source object
4363 $discount = new DiscountAbsolute($this->db);
4364 $discount->fk_soc = $this->socid;
4365 $this->tpl['label'] .= $discount->getNomUrl(0, 'discount');
4366 } elseif (!empty($line->fk_product))
4368 $productstatic = new Product($this->db);
4369 $productstatic->id = $line->fk_product;
4370 $productstatic->ref = $line->ref;
4371 $productstatic->type = $line->fk_product_type;
4372 if (empty($productstatic->ref)) {
4373 $line->fetch_product();
4374 $productstatic = $line->product;
4377 $this->tpl['label'] .= $productstatic->getNomUrl(1);
4378 $this->tpl['label'] .= ' - '.(!empty($line->label) ? $line->label : $line->product_label);
4380 if ($line->product_type == 1 && ($date_start || $date_end))
4382 $this->tpl['label'] .= get_date_range($date_start, $date_end);
4385 $this->tpl['label'] .= ($line->product_type == -1 ? ' ' : ($line->product_type == 1 ? img_object($langs->trans(''), 'service') : img_object($langs->trans(''), 'product')));
4386 if (!empty($line->desc)) {
4387 $this->tpl['label'] .= $line->desc;
4389 $this->tpl['label'] .= ($line->label ? ' '.$line->label : '');
4393 if ($line->product_type == 1 && ($date_start || $date_end))
4395 $this->tpl['label'] .= get_date_range($date_start, $date_end);
4399 if (!empty($line->desc))
4401 if ($line->desc == '(CREDIT_NOTE)') // TODO Not sure this is used for source object
4403 $discount = new DiscountAbsolute($this->db);
4404 $discount->fetch($line->fk_remise_except);
4405 $this->tpl['description'] = $langs->transnoentities("DiscountFromCreditNote
", $discount->getNomUrl(0));
4406 } elseif ($line->desc == '(DEPOSIT)') // TODO Not sure this is used for source object
4408 $discount = new DiscountAbsolute($this->db);
4409 $discount->fetch($line->fk_remise_except);
4410 $this->tpl['description'] = $langs->transnoentities("DiscountFromDeposit
", $discount->getNomUrl(0));
4411 } elseif ($line->desc == '(EXCESS RECEIVED)')
4413 $discount = new DiscountAbsolute($this->db);
4414 $discount->fetch($line->fk_remise_except);
4415 $this->tpl['description'] = $langs->transnoentities("DiscountFromExcessReceived
", $discount->getNomUrl(0));
4416 } elseif ($line->desc == '(EXCESS PAID)')
4418 $discount = new DiscountAbsolute($this->db);
4419 $discount->fetch($line->fk_remise_except);
4420 $this->tpl['description'] = $langs->transnoentities("DiscountFromExcessPaid
", $discount->getNomUrl(0));
4422 $this->tpl['description'] = dol_trunc($line->desc, 60);
4425 $this->tpl['description'] = ' ';
4429 $this->tpl['vat_rate'] = vatrate($line->tva_tx, true);
4430 $this->tpl['vat_rate'] .= (($line->info_bits & 1) == 1) ? '*' : '';
4431 if (!empty($line->vat_src_code) && !preg_match('/\(/', $this->tpl['vat_rate'])) $this->tpl['vat_rate'] .= ' ('.$line->vat_src_code.')';
4433 $this->tpl['price'] = price($line->subprice);
4434 $this->tpl['multicurrency_price'] = price($line->multicurrency_subprice);
4435 $this->tpl['qty'] = (($line->info_bits & 2) != 2) ? $line->qty : ' ';
4436 if (!empty($conf->global->PRODUCT_USE_UNITS)) $this->tpl['unit'] = $langs->transnoentities($line->getLabelOfUnit('long'));
4437 $this->tpl['remise_percent'] = (($line->info_bits & 2) != 2) ? vatrate($line->remise_percent, true) : ' ';
4439 // Is the line strike or not
4440 $this->tpl['strike'] = 0;
4441 if ($restrictlist == 'services' && $line->product_type != Product::TYPE_SERVICE) $this->tpl['strike'] = 1;
4443 // Output template part (modules that overwrite templates must declare this into descriptor)
4444 // Use global variables + $dateSelector + $seller and $buyer
4445 $dirtpls = array_merge($conf->modules_parts['tpl'], array($defaulttpldir));
4446 foreach ($dirtpls as $module => $reldir)
4448 if (!empty($module))
4450 $tpl = dol_buildpath($reldir.'/originproductline.tpl.php');
4452 $tpl = DOL_DOCUMENT_ROOT.$reldir.'/originproductline.tpl.php';
4455 if (empty($conf->file->strict_mode)) {
4456 $res = @include $tpl;
4458 $res = include $tpl; // for debug
4465 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
4476 public function add_element_resource($resource_id, $resource_type, $busy = 0, $mandatory = 0)
4481 $sql = "INSERT INTO
".MAIN_DB_PREFIX."element_resources (
";
4482 $sql .= "resource_id
";
4483 $sql .= ", resource_type
";
4484 $sql .= ", element_id
";
4485 $sql .= ", element_type
";
4487 $sql .= ", mandatory
";
4488 $sql .= ") VALUES (
";
4489 $sql .= $resource_id;
4490 $sql .= ",
'".$this->db->escape($resource_type)."'";
4491 $sql .= ",
'".$this->db->escape($this->id)."'";
4492 $sql .= ",
'".$this->db->escape($this->element)."'";
4493 $sql .= ",
'".$this->db->escape($busy)."'";
4494 $sql .= ",
'".$this->db->escape($mandatory)."'";
4498 if ($this->db->query($sql))
4500 $this->db->commit();
4503 $this->error = $this->db->lasterror();
4504 $this->db->rollback();
4509 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
4518 public function delete_resource($rowid, $element, $notrigger = 0)
4525 $sql = "DELETE FROM
".MAIN_DB_PREFIX."element_resources
";
4526 $sql .= " WHERE rowid=
".$rowid;
4530 $resql = $this->db->query($sql);
4533 $this->error = $this->db->lasterror();
4534 $this->db->rollback();
4539 $result = $this->call_trigger(strtoupper($element).'_DELETE_RESOURCE', $user);
4540 if ($result < 0) { $this->db->rollback(); return -1; }
4542 $this->db->commit();
4553 public function __clone()
4555 // Force a copy of this->lines, otherwise it will point to same object.
4556 if (isset($this->lines) && is_array($this->lines))
4558 $nboflines = count($this->lines);
4559 for ($i = 0; $i < $nboflines; $i++)
4561 $this->lines[$i] = clone $this->lines[$i];
4579 protected function commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams = null)
4581 global $conf, $langs, $user, $hookmanager, $action;
4583 $srctemplatepath = '';
4585 $parameters = array('modelspath'=>$modelspath, 'modele'=>$modele, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'hidedesc'=>$hidedesc, 'hideref'=>$hideref, 'moreparams'=>$moreparams);
4586 $reshook = $hookmanager->executeHooks('commonGenerateDocument', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
4588 if (empty($reshook))
4590 dol_syslog("commonGenerateDocument modele=
".$modele." outputlangs->defaultlang=
".(is_object($outputlangs) ? $outputlangs->defaultlang : 'null'));
4592 if (empty($modele)) {
4593 $this->error = 'BadValueForParameterModele';
4597 // Increase limit for PDF build
4598 $err = error_reporting();
4600 @set_time_limit(120);
4601 error_reporting($err);
4603 // If selected model is a filename template (then $modele="modelname
" or "modelname:filename
")
4604 $tmp = explode(':', $modele, 2);
4605 if (!empty($tmp[1]))
4608 $srctemplatepath = $tmp[1];
4611 // Search template files
4615 $dirmodels = array('/');
4616 if (is_array($conf->modules_parts['models'])) $dirmodels = array_merge($dirmodels, $conf->modules_parts['models']);
4617 foreach ($dirmodels as $reldir)
4619 foreach (array('doc', 'pdf') as $prefix)
4621 if (in_array(get_class($this), array('Adherent'))) {
4622 // Member module use prefix_modele.class.php
4623 $file = $prefix."_
".$modele.".class.php
";
4625 // Other module use prefix_modele.modules.php
4626 $file = $prefix."_
".$modele.".modules.php
";
4629 // On verifie l'emplacement du modele
4630 $file = dol_buildpath($reldir.$modelspath.$file, 0);
4631 if (file_exists($file)) {
4633 $classname = $prefix.'_'.$modele;
4637 if ($filefound) break;
4640 // If generator was found
4643 global $db; // Required to solve a conception default making an include of code using $db instead of $this->db just after.
4647 $obj = new $classname($this->db);
4649 // If generator is ODT, we must have srctemplatepath defined, if not we set it.
4650 if ($obj->type == 'odt' && empty($srctemplatepath))
4652 $varfortemplatedir = $obj->scandir;
4653 if ($varfortemplatedir && !empty($conf->global->$varfortemplatedir))
4655 $dirtoscan = $conf->global->$varfortemplatedir;
4657 $listoffiles = array();
4659 // Now we add first model found in directories scanned
4660 $listofdir = explode(',', $dirtoscan);
4661 foreach ($listofdir as $key => $tmpdir)
4663 $tmpdir = trim($tmpdir);
4664 $tmpdir = preg_replace('/DOL_DATA_ROOT/', DOL_DATA_ROOT, $tmpdir);
4665 if (!$tmpdir) { unset($listofdir[$key]); continue; }
4666 if (is_dir($tmpdir))
4668 $tmpfiles = dol_dir_list($tmpdir, 'files', 0, '\.od(s|t)$', '', 'name', SORT_ASC, 0);
4669 if (count($tmpfiles)) $listoffiles = array_merge($listoffiles, $tmpfiles);
4673 if (count($listoffiles))
4675 foreach ($listoffiles as $record)
4677 $srctemplatepath = $record['fullname'];
4683 if (empty($srctemplatepath))
4685 $this->error = 'ErrorGenerationAskedForOdtTemplateWithSrcFileNotDefined';
4690 if ($obj->type == 'odt' && !empty($srctemplatepath))
4692 if (!dol_is_file($srctemplatepath))
4694 dol_syslog("Failed to locate
template file
".$srctemplatepath, LOG_WARNING);
4695 $this->error = 'ErrorGenerationAskedForOdtTemplateWithSrcFileNotFound';
4700 // We save charset_output to restore it because write_file can change it if needed for
4701 // output format that does not support UTF8.
4702 $sav_charset_output = $outputlangs->charset_output;
4704 if (in_array(get_class($this), array('Adherent')))
4706 $arrayofrecords = array(); // The write_file of templates of adherent class need this var
4707 $resultwritefile = $obj->write_file($this, $outputlangs, $srctemplatepath, 'member', 1, $moreparams);
4709 $resultwritefile = $obj->write_file($this, $outputlangs, $srctemplatepath, $hidedetails, $hidedesc, $hideref, $moreparams);
4711 // After call of write_file $obj->result['fullpath'] is set with generated file. It will be used to update the ECM database index.
4713 if ($resultwritefile > 0)
4715 $outputlangs->charset_output = $sav_charset_output;
4717 // We delete old preview
4718 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
4719 dol_delete_preview($this);
4721 // Index file in database
4722 if (!empty($obj->result['fullpath']))
4724 $destfull = $obj->result['fullpath'];
4725 $upload_dir = dirname($destfull);
4726 $destfile = basename($destfull);
4727 $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $upload_dir);
4729 if (!preg_match('/[\\/]temp[\\/]|[\\/]thumbs|\.meta$/', $rel_dir)) // If not a tmp dir
4731 $filename = basename($destfile);
4732 $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir);
4733 $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir);
4735 include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
4736 $ecmfile = new EcmFiles($this->db);
4737 $result = $ecmfile->fetch(0, '', ($rel_dir ? $rel_dir.'/' : '').$filename);
4739 // Set the public "share
" key
4740 $setsharekey = false;
4741 if ($this->element == 'propal')
4743 $useonlinesignature = $conf->global->MAIN_FEATURES_LEVEL; // Replace this with 1 when feature to make online signature is ok
4744 if ($useonlinesignature) $setsharekey = true;
4745 if (!empty($conf->global->PROPOSAL_ALLOW_EXTERNAL_DOWNLOAD)) $setsharekey = true;
4747 if ($this->element == 'commande' && !empty($conf->global->ORDER_ALLOW_EXTERNAL_DOWNLOAD)) {
4748 $setsharekey = true;
4750 if ($this->element == 'facture' && !empty($conf->global->INVOICE_ALLOW_EXTERNAL_DOWNLOAD)) {
4751 $setsharekey = true;
4753 if ($this->element == 'bank_account' && !empty($conf->global->BANK_ACCOUNT_ALLOW_EXTERNAL_DOWNLOAD)) {
4754 $setsharekey = true;
4758 if (empty($ecmfile->share)) // Because object not found or share not set yet
4760 require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
4761 $ecmfile->share = getRandomPassword(true);
4767 $ecmfile->label = md5_file(dol_osencode($destfull)); // hash of file content
4768 $ecmfile->fullpath_orig = '';
4769 $ecmfile->gen_or_uploaded = 'generated';
4770 $ecmfile->description = ''; // indexed content
4771 $ecmfile->keyword = ''; // keyword content
4772 $result = $ecmfile->update($user);
4774 setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings');
4777 $ecmfile->entity = $conf->entity;
4778 $ecmfile->filepath = $rel_dir;
4779 $ecmfile->filename = $filename;
4780 $ecmfile->label = md5_file(dol_osencode($destfull)); // hash of file content
4781 $ecmfile->fullpath_orig = '';
4782 $ecmfile->gen_or_uploaded = 'generated';
4783 $ecmfile->description = ''; // indexed content
4784 $ecmfile->keyword = ''; // keyword content
4785 $ecmfile->src_object_type = $this->table_element;
4786 $ecmfile->src_object_id = $this->id;
4788 $result = $ecmfile->create($user);
4790 setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings');
4794 /*$this->result['fullname']=$destfull;
4795 $this->result['filepath']=$ecmfile->filepath;
4796 $this->result['filename']=$ecmfile->filename;*/
4797 //var_dump($obj->update_main_doc_field);exit;
4799 // Update the last_main_doc field into main object (if documenent generator has property ->update_main_doc_field set)
4800 $update_main_doc_field = 0;
4801 if (!empty($obj->update_main_doc_field)) $update_main_doc_field = 1;
4802 if ($update_main_doc_field && !empty($this->table_element))
4804 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element." SET last_main_doc =
'".$this->db->escape($ecmfile->filepath.'/
'.$ecmfile->filename)."'";
4805 $sql .= ' WHERE rowid = '.$this->id;
4807 $resql = $this->db->query($sql);
4809 dol_print_error($this->db);
4811 $this->last_main_doc = $ecmfile->filepath.'/'.$ecmfile->filename;
4816 dol_syslog('Method ->write_file was called on object '.get_class($obj).' and return a success but the return array ->result["fullpath
"] was not set.', LOG_WARNING);
4819 // Success in building document. We build meta file.
4820 dol_meta_create($this);
4824 $outputlangs->charset_output = $sav_charset_output;
4825 dol_print_error($this->db, "Error generating document
for ".__CLASS__.". Error:
".$obj->error, $obj->errors);
4830 $this->error = $langs->trans("Error
").' Failed to load doc generator with modelpaths='.$modelspath.' - modele='.$modele;
4831 dol_print_error('', $this->error);
4833 $this->error = $langs->trans("Error
")." ".$langs->trans("ErrorFileDoesNotExists
", $filefound);
4834 dol_print_error('', $this->error);
4838 } else return $reshook;
4848 public function addThumbs($file)
4850 global $maxwidthsmall, $maxheightsmall, $maxwidthmini, $maxheightmini, $quality;
4852 require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; // This define also $maxwidthsmall, $quality, ...
4854 $file_osencoded = dol_osencode($file);
4855 if (file_exists($file_osencoded))
4857 // Create small thumbs for company (Ratio is near 16/9)
4858 // Used on logon for example
4859 vignette($file_osencoded, $maxwidthsmall, $maxheightsmall, '_small', $quality);
4861 // Create mini thumbs for company (Ratio is near 16/9)
4862 // Used on menu or for setup page for example
4863 vignette($file_osencoded, $maxwidthmini, $maxheightmini, '_mini', $quality);
4868 /* Functions common to commonobject and commonobjectline */
4870 /* For default values */
4884 public function getDefaultCreateValueFor($fieldname, $alternatevalue = null)
4886 global $conf, $_POST;
4888 // If param here has been posted, we use this value first.
4889 if (GETPOSTISSET($fieldname)) return GETPOST($fieldname, 'alphanohtml', 3);
4891 if (isset($alternatevalue)) return $alternatevalue;
4893 $newelement = $this->element;
4894 if ($newelement == 'facture') $newelement = 'invoice';
4895 if ($newelement == 'commande') $newelement = 'order';
4896 if (empty($newelement))
4898 dol_syslog("Ask a
default value
using common method getDefaultCreateValueForField on an
object with no property ->element defined. Return empty
string.
", LOG_WARNING);
4902 $keyforfieldname = strtoupper($newelement.'_DEFAULT_'.$fieldname);
4903 //var_dump($keyforfieldname);
4904 if (isset($conf->global->$keyforfieldname)) return $conf->global->$keyforfieldname;
4906 // TODO Ad here a scan into table llx_overwrite_default with a filter on $this->element and $fieldname
4913 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
4924 public function call_trigger($triggerName, $user)
4927 global $langs, $conf;
4929 if (!is_object($langs)) { // If lang was not defined, we set it. It is required by run_triggers.
4930 include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php';
4931 $langs = new Translate('', $conf);
4934 include_once DOL_DOCUMENT_ROOT.'/core/class/interfaces.class.php';
4935 $interface = new Interfaces($this->db);
4936 $result = $interface->run_triggers($triggerName, $this, $user, $langs, $conf);
4940 if (!empty($this->errors))
4942 $this->errors = array_unique(array_merge($this->errors, $interface->errors)); // We use array_unique because when a trigger call another trigger on same object, this->errors is added twice.
4944 $this->errors = $interface->errors;
4951 /* Functions for data in other language */
4961 public function fetchValuesForExtraLanguages()
4963 // To avoid SQL errors. Probably not the better solution though
4964 if (!$this->element) {
4967 if (!($this->id > 0)) {
4970 if (is_array($this->array_languages)) {
4974 $this->array_languages = array();
4976 $element = $this->element;
4977 if ($element == 'categorie') $element = 'categories'; // For compatibility
4979 // Request to get translation values for object
4980 $sql = "SELECT rowid, property, lang , value
";
4981 $sql .= " FROM
".MAIN_DB_PREFIX."object_lang
";
4982 $sql .= " WHERE type_object =
'".$this->db->escape($element)."'";
4983 $sql .= " AND fk_object =
".$this->id;
4985 //dol_syslog(get_class($this)."::
fetch_optionals get extrafields data
for ".$this->table_element, LOG_DEBUG); // Too verbose
4986 $resql = $this->db->query($sql);
4989 $numrows = $this->db->num_rows($resql);
4993 while ($i < $numrows) {
4994 $obj = $this->db->fetch_object($resql);
4995 $key = $obj->property;
4996 $value = $obj->value;
4997 $codelang = $obj->lang;
4998 $type = $this->fields[$key]['type'];
5000 // we can add this attribute to object
5001 if (preg_match('/date/', $type))
5003 $this->array_languages[$key][$codelang] = $this->db->jdate($value);
5005 $this->array_languages[$key][$codelang] = $value;
5012 $this->db->free($resql);
5014 if ($numrows) return $numrows;
5017 dol_print_error($this->db);
5028 public function setValuesForExtraLanguages($onlykey = '')
5030 global $_POST, $langs;
5033 foreach ($_POST as $postfieldkey => $postfieldvalue) {
5034 $tmparray = explode('-', $postfieldkey);
5035 if ($tmparray[0] != 'field') continue;
5037 $element = $tmparray[1];
5038 $key = $tmparray[2];
5039 $codelang = $tmparray[3];
5040 //var_dump("postfieldkey=
".$postfieldkey." element=
".$element." key=
".$key." codelang=
".$codelang);
5042 if (!empty($onlykey) && $key != $onlykey) continue;
5043 if ($element != $this->element) continue;
5045 $key_type = $this->fields[$key]['type'];
5048 if (isset($this->fields[$key]['enabled']))
5050 $enabled = dol_eval($this->fields[$key]['enabled'], 1);
5053 if (isset($this->fields[$key]['perms']))
5055 $perms = dol_eval($this->fields[$key]['perms'], 1);
5057 if (empty($enabled)) continue;
5058 //if (empty($perms)) continue;
5060 if (in_array($key_type, array('date')))
5063 // TODO GMT date in memory must be GMT so we should add gm=true in parameters
5064 $value_key = dol_mktime(0, 0, 0, $_POST[$postfieldkey."month
"], $_POST[$postfieldkey."day
"], $_POST[$postfieldkey."year
"]);
5065 } elseif (in_array($key_type, array('datetime')))
5068 // TODO GMT date in memory must be GMT so we should add gm=true in parameters
5069 $value_key = dol_mktime($_POST[$postfieldkey."hour
"], $_POST[$postfieldkey."min
"], 0, $_POST[$postfieldkey."month
"], $_POST[$postfieldkey."day
"], $_POST[$postfieldkey."year
"]);
5070 } elseif (in_array($key_type, array('checkbox', 'chkbxlst')))
5072 $value_arr = GETPOST($postfieldkey, 'array'); // check if an array
5073 if (!empty($value_arr)) {
5074 $value_key = implode(',', $value_arr);
5078 } elseif (in_array($key_type, array('price', 'double')))
5080 $value_arr = GETPOST($postfieldkey, 'alpha');
5081 $value_key = price2num($value_arr);
5083 $value_key = GETPOST($postfieldkey);
5084 if (in_array($key_type, array('link')) && $value_key == '-1') $value_key = '';
5087 $this->array_languages[$key][$codelang] = $value_key;
5089 /*if ($nofillrequired) {
5090 $langs->load('errors');
5091 setEventMessages($langs->trans('ErrorFieldsRequired').' : '.implode(', ', $error_field_required), null, 'errors');
5100 /* Functions for extrafields */
5108 public function fetchNoCompute($id)
5112 $savDisableCompute = $conf->disable_compute;
5113 $conf->disable_compute = 1;
5115 $ret = $this->fetch($id);
5117 $conf->disable_compute = $savDisableCompute;
5122 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
5132 public function fetch_optionals($rowid = null, $optionsArray = null)
5135 global $conf, $extrafields;
5137 if (empty($rowid)) $rowid = $this->id;
5138 if (empty($rowid) && isset($this->rowid)) $rowid = $this->rowid; // deprecated
5140 // To avoid SQL errors. Probably not the better solution though
5141 if (!$this->table_element) {
5145 $this->array_options = array();
5147 if (!is_array($optionsArray))
5149 // If $extrafields is not a known object, we initialize it. Best practice is to have $extrafields defined into card.php or list.php page.
5150 if (!isset($extrafields) || !is_object($extrafields))
5152 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
5153 $extrafields = new ExtraFields($this->db);
5156 // Load array of extrafields for elementype = $this->table_element
5157 if (empty($extrafields->attributes[$this->table_element]['loaded']))
5159 $extrafields->fetch_name_optionals_label($this->table_element);
5161 $optionsArray = (!empty($extrafields->attributes[$this->table_element]['label']) ? $extrafields->attributes[$this->table_element]['label'] : null);
5163 global $extrafields;
5164 dol_syslog("Warning:
fetch_optionals was called with param optionsArray defined when you should pass null now
", LOG_WARNING);
5167 $table_element = $this->table_element;
5168 if ($table_element == 'categorie') $table_element = 'categories'; // For compatibility
5170 // Request to get complementary values
5171 if (is_array($optionsArray) && count($optionsArray) > 0)
5173 $sql = "SELECT rowid
";
5174 foreach ($optionsArray as $name => $label)
5176 if (empty($extrafields->attributes[$this->table_element]['type'][$name]) || $extrafields->attributes[$this->table_element]['type'][$name] != 'separate')
5181 $sql .= " FROM
".MAIN_DB_PREFIX.$table_element."_extrafields
";
5182 $sql .= " WHERE fk_object =
".((int) $rowid);
5184 //dol_syslog(get_class($this)."::
fetch_optionals get extrafields data
for ".$this->table_element, LOG_DEBUG); // Too verbose
5185 $resql = $this->db->query($sql);
5188 $numrows = $this->db->num_rows($resql);
5191 $tab = $this->db->fetch_array($resql);
5193 foreach ($tab as $key => $value)
5195 // Test fetch_array ! is_int($key) because fetch_array result is a mix table with Key as alpha and Key as int (depend db engine)
5196 if ($key != 'rowid' && $key != 'tms' && $key != 'fk_member' && !is_int($key))
5198 // we can add this attribute to object
5199 if (!empty($extrafields) && in_array($extrafields->attributes[$this->table_element]['type'][$key], array('date', 'datetime')))
5201 //var_dump($extrafields->attributes[$this->table_element]['type'][$key]);
5202 $this->array_options["options_
".$key] = $this->db->jdate($value);
5204 $this->array_options["options_
".$key] = $value;
5207 //var_dump('key '.$key.' '.$value.' type='.$extrafields->attributes[$this->table_element]['type'][$key].' '.$this->array_options["options_
".$key]);
5211 // If field is a computed field, value must become result of compute
5212 foreach ($tab as $key => $value) {
5213 if (!empty($extrafields) && !empty($extrafields->attributes[$this->table_element]['computed'][$key]))
5215 //var_dump($conf->disable_compute);
5216 if (empty($conf->disable_compute)) {
5217 $this->array_options["options_
".$key] = dol_eval($extrafields->attributes[$this->table_element]['computed'][$key], 1, 0);
5223 $this->db->free($resql);
5225 if ($numrows) return $numrows;
5228 dol_print_error($this->db);
5241 public function deleteExtraFields()
5245 if (!empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) return 0;
5249 $table_element = $this->table_element;
5250 if ($table_element == 'categorie') $table_element = 'categories'; // For compatibility
5252 $sql_del = "DELETE FROM
".MAIN_DB_PREFIX.$table_element."_extrafields WHERE fk_object =
".$this->id;
5254 $resql = $this->db->query($sql_del);
5257 $this->error = $this->db->lasterror();
5258 $this->db->rollback();
5261 $this->db->commit();
5276 public function insertExtraFields($trigger = '', $userused = null)
5278 global $conf, $langs, $user;
5280 if (!empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) return 0;
5282 if (empty($userused)) $userused = $user;
5286 if (!empty($this->array_options))
5289 $langs->load('admin');
5290 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
5291 $extrafields = new ExtraFields($this->db);
5292 $target_extrafields = $extrafields->fetch_name_optionals_label($this->table_element);
5294 // Eliminate copied source object extra fields that do not exist in target object
5295 $new_array_options = array();
5296 foreach ($this->array_options as $key => $value) {
5297 if (in_array(substr($key, 8), array_keys($target_extrafields))) // We remove the 'options_' from $key for test
5298 $new_array_options[$key] = $value;
5299 elseif (in_array($key, array_keys($target_extrafields))) // We test on $key that does not contains the 'options_' prefix
5300 $new_array_options['options_'.$key] = $value;
5303 foreach ($new_array_options as $key => $value)
5305 $attributeKey = substr($key, 8); // Remove 'options_' prefix
5306 $attributeType = $extrafields->attributes[$this->table_element]['type'][$attributeKey];
5307 $attributeLabel = $extrafields->attributes[$this->table_element]['label'][$attributeKey];
5308 $attributeParam = $extrafields->attributes[$this->table_element]['param'][$attributeKey];
5309 $attributeRequired = $extrafields->attributes[$this->table_element]['required'][$attributeKey];
5310 $attrfieldcomputed = $extrafields->attributes[$this->table_element]['computed'][$attributeKey];
5312 // Similar code than into insertExtraFields
5313 if ($attributeRequired)
5315 $mandatorypb = false;
5316 if ($attributeType == 'link' && $this->array_options[$key] == '-1') $mandatorypb = true;
5317 if ($this->array_options[$key] === '') $mandatorypb = true;
5318 if ($attributeType == 'sellist' && $this->array_options[$key] == '0') $mandatorypb = true;
5321 dol_syslog("Mandatory extra field
".$key." is empty
");
5322 $this->errors[] = $langs->trans('ErrorFieldRequired', $attributeLabel);
5327 //dol_syslog("attributeLabel=
".$attributeLabel, LOG_DEBUG);
5328 //dol_syslog("attributeType=
".$attributeType, LOG_DEBUG);
5330 if (!empty($attrfieldcomputed))
5332 if (!empty($conf->global->MAIN_STORE_COMPUTED_EXTRAFIELDS))
5334 $value = dol_eval($attrfieldcomputed, 1, 0);
5335 dol_syslog($langs->trans("Extrafieldcomputed
")." sur
".$attributeLabel."(
".$value.")
", LOG_DEBUG);
5336 $new_array_options[$key] = $value;
5338 $new_array_options[$key] = null;
5342 switch ($attributeType)
5345 if (!is_numeric($value) && $value != '')
5347 $this->errors[] = $langs->trans("ExtraFieldHasWrongValue
", $attributeLabel);
5349 } elseif ($value == '')
5351 $new_array_options[$key] = null;
5356 $value = price2num($value);
5357 if (!is_numeric($value) && $value != '')
5359 dol_syslog($langs->trans("ExtraFieldHasWrongValue
")." for ".$attributeLabel."(
".$value."is not
'".$attributeType."')
", LOG_DEBUG);
5360 $this->errors[] = $langs->trans("ExtraFieldHasWrongValue
", $attributeLabel);
5362 } elseif ($value == '')
5364 $new_array_options[$key] = null;
5366 //dol_syslog("double value
"." sur
".$attributeLabel."(
".$value." is
'".$attributeType."')
", LOG_DEBUG);
5367 $new_array_options[$key] = $value;
5369 /*case 'select': // Not required, we chosed value='0' for undefined values
5372 $this->array_options[$key] = null;
5377 if ($this->array_options[$key] != '' && is_array($extrafields->attributes[$this->table_element]['param'][$attributeKey]['options']))
5379 // If there is an encryption choice, we use it to crypt data before insert
5380 $tmparrays = array_keys($extrafields->attributes[$this->table_element]['param'][$attributeKey]['options']);
5381 $algo = reset($tmparrays);
5384 //global $action; // $action may be 'create', 'update', 'update_extras'...
5385 //var_dump($action);
5386 //var_dump($this->oldcopy);exit;
5387 if (is_object($this->oldcopy)) // If this->oldcopy is not defined, we can't know if we change attribute or not, so we must keep value
5389 //var_dump($this->oldcopy->array_options[$key]); var_dump($this->array_options[$key]);
5390 if ($this->array_options[$key] == $this->oldcopy->array_options[$key]) // If old value crypted in database is same than submited new value, it means we don't change it, so we don't update.
5392 $new_array_options[$key] = $this->array_options[$key]; // Value is kept
5395 $newvalue = dol_hash($this->array_options[$key], $algo);
5396 $new_array_options[$key] = $newvalue;
5399 $new_array_options[$key] = $this->array_options[$key]; // Value is kept
5402 } else // Common usage
5404 $new_array_options[$key] = $this->array_options[$key];
5409 // If data is a string instead of a timestamp, we convert it
5410 if (!is_int($this->array_options[$key])) {
5411 $this->array_options[$key] = strtotime($this->array_options[$key]);
5413 $new_array_options[$key] = $this->db->idate($this->array_options[$key]);
5416 $param_list = array_keys($attributeParam['options']);
5419 $InfoFieldList = explode(":
", $param_list[0]);
5420 dol_include_once($InfoFieldList[1]);
5421 if ($InfoFieldList[0] && class_exists($InfoFieldList[0]))
5423 if ($value == '-1') // -1 is key for no defined in combo list of objects
5425 $new_array_options[$key] = '';
5427 $object = new $InfoFieldList[0]($this->db);
5428 if (is_numeric($value)) $res = $object->fetch($value); // Common case
5429 else $res = $object->fetch('', $value); // For compatibility
5431 if ($res > 0) $new_array_options[$key] = $object->id;
5433 $this->error = "Id/Ref
'".$value."' for object '".$object->element."' not found
";
5434 $this->db->rollback();
5439 dol_syslog('Error bad setup of extrafield', LOG_WARNING);
5447 $table_element = $this->table_element;
5448 if ($table_element == 'categorie') $table_element = 'categories'; // For compatibility
5450 dol_syslog(get_class($this)."::
insertExtraFields delete then insert
", LOG_DEBUG);
5452 $sql_del = "DELETE FROM
".MAIN_DB_PREFIX.$table_element."_extrafields WHERE fk_object =
".$this->id;
5453 $this->db->query($sql_del);
5455 $sql = "INSERT INTO
".MAIN_DB_PREFIX.$table_element."_extrafields (fk_object
";
5456 foreach ($new_array_options as $key => $value)
5458 $attributeKey = substr($key, 8); // Remove 'options_' prefix
5459 // Add field of attribut
5460 if ($extrafields->attributes[$this->table_element]['type'][$attributeKey] != 'separate') // Only for other type than separator
5461 $sql .= ",
".$attributeKey;
5463 // We must insert a default value for fields for other entities that are mandatory to avoid not null error
5464 if (!empty($extrafields->attributes[$this->table_element]['mandatoryfieldsofotherentities']) && is_array($extrafields->attributes[$this->table_element]['mandatoryfieldsofotherentities'])) {
5465 foreach ($extrafields->attributes[$this->table_element]['mandatoryfieldsofotherentities'] as $tmpkey => $tmpval) {
5466 if (!isset($extrafields->attributes[$this->table_element]['type'][$tmpkey])) { // If field not already added previously
5467 $sql .= ",
".$tmpkey;
5471 $sql .= ") VALUES (
".$this->id;
5473 foreach ($new_array_options as $key => $value) {
5474 $attributeKey = substr($key, 8); // Remove 'options_' prefix
5475 // Add field of attribute
5476 if ($extrafields->attributes[$this->table_element]['type'][$attributeKey] != 'separate') { // Only for other type than separator)
5477 if ($new_array_options[$key] != '' || $new_array_options[$key] == '0') {
5478 $sql .= ",
'".$this->db->escape($new_array_options[$key])."'";
5484 // We must insert a default value for fields for other entities that are mandatory to avoid not null error
5485 if (!empty($extrafields->attributes[$this->table_element]['mandatoryfieldsofotherentities']) && is_array($extrafields->attributes[$this->table_element]['mandatoryfieldsofotherentities'])) {
5486 foreach ($extrafields->attributes[$this->table_element]['mandatoryfieldsofotherentities'] as $tmpkey => $tmpval) {
5487 if (!isset($extrafields->attributes[$this->table_element]['type'][$tmpkey])) { // If field not already added previously
5488 if (in_array($tmpval, array('int', 'double', 'price'))) $sql .= ", 0
";
5489 else $sql .= ",
''";
5496 $resql = $this->db->query($sql);
5499 $this->error = $this->db->lasterror();
5503 if (!$error && $trigger)
5506 $this->context = array('extrafieldaddupdate'=>1);
5507 $result = $this->call_trigger($trigger, $userused);
5508 if ($result < 0) $error++;
5514 $this->db->rollback();
5517 $this->db->commit();
5533 public function insertExtraLanguages($trigger = '', $userused = null)
5535 global $conf, $langs, $user;
5537 if (empty($userused)) $userused = $user;
5541 if (!empty($conf->global->MAIN_EXTRALANGUAGES_DISABLED)) return 0; // For avoid conflicts if trigger used
5543 if (is_array($this->array_languages))
5545 $new_array_languages = $this->array_languages;
5547 foreach ($new_array_languages as $key => $value)
5549 $attributeKey = $key;
5550 $attributeType = $this->fields[$attributeKey]['type'];
5551 $attributeLabel = $this->fields[$attributeKey]['label'];
5553 //dol_syslog("attributeLabel=
".$attributeLabel, LOG_DEBUG);
5554 //dol_syslog("attributeType=
".$attributeType, LOG_DEBUG);
5556 switch ($attributeType)
5559 if (!is_numeric($value) && $value != '')
5561 $this->errors[] = $langs->trans("ExtraLanguageHasWrongValue
", $attributeLabel);
5563 } elseif ($value == '')
5565 $new_array_languages[$key] = null;
5569 $value = price2num($value);
5570 if (!is_numeric($value) && $value != '')
5572 dol_syslog($langs->trans("ExtraLanguageHasWrongValue
")." sur
".$attributeLabel."(
".$value."is not
'".$attributeType."')
", LOG_DEBUG);
5573 $this->errors[] = $langs->trans("ExtraLanguageHasWrongValue
", $attributeLabel);
5575 } elseif ($value == '')
5577 $new_array_languages[$key] = null;
5579 //dol_syslog("double value
"." sur
".$attributeLabel."(
".$value." is
'".$attributeType."')
", LOG_DEBUG);
5580 $new_array_languages[$key] = $value;
5582 /*case 'select': // Not required, we chosed value='0' for undefined values
5585 $this->array_options[$key] = null;
5593 $table_element = $this->table_element;
5594 if ($table_element == 'categorie') $table_element = 'categories'; // For compatibility
5598 foreach ($new_array_languages as $key => $langcodearray) { // $key = 'name', 'town', ...
5599 foreach ($langcodearray as $langcode => $value) {
5600 $sql_del = "DELETE FROM
".MAIN_DB_PREFIX."object_lang
";
5601 $sql_del .= " WHERE fk_object =
".$this->id." AND property =
'".$this->db->escape($key)."' AND type_object =
'".$this->db->escape($table_element)."'";
5602 $sql_del .= " AND lang =
'".$this->db->escape($langcode)."'";
5603 $this->db->query($sql_del);
5605 if ($value !== '') {
5606 $sql = "INSERT INTO
".MAIN_DB_PREFIX."object_lang (fk_object, property, type_object, lang, value
";
5607 $sql .= ") VALUES (
".$this->id.",
'".$this->db->escape($key)."',
'".$this->db->escape($table_element)."',
'".$this->db->escape($langcode)."',
'".$this->db->escape($value)."'";
5610 $resql = $this->db->query($sql);
5613 $this->error = $this->db->lasterror();
5621 if (!$error && $trigger)
5624 $this->context = array('extralanguagesaddupdate'=>1);
5625 $result = $this->call_trigger($trigger, $userused);
5626 if ($result < 0) $error++;
5632 $this->db->rollback();
5635 $this->db->commit();
5651 public function updateExtraField($key, $trigger = null, $userused = null)
5653 global $conf, $langs, $user;
5655 if (!empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) return 0;
5657 if (empty($userused)) $userused = $user;
5661 if (!empty($this->array_options) && isset($this->array_options["options_
".$key]))
5664 $langs->load('admin');
5665 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
5666 $extrafields = new ExtraFields($this->db);
5667 $extrafields->fetch_name_optionals_label($this->table_element);
5669 $value = $this->array_options["options_
".$key];
5671 $attributeType = $extrafields->attributes[$this->table_element]['type'][$key];
5672 $attributeLabel = $extrafields->attributes[$this->table_element]['label'][$key];
5673 $attributeParam = $extrafields->attributes[$this->table_element]['param'][$key];
5674 $attributeRequired = $extrafields->attributes[$this->table_element]['required'][$key];
5675 $attrfieldcomputed = $extrafields->attributes[$this->table_element]['computed'][$key];
5677 // Similar code than into insertExtraFields
5678 if ($attributeRequired)
5680 $mandatorypb = false;
5681 if ($attributeType == 'link' && $this->array_options["options_
".$key] == '-1') $mandatorypb = true;
5682 if ($this->array_options["options_
".$key] === '') $mandatorypb = true;
5685 dol_syslog("Mandatory extra field options_
".$key." is empty
");
5686 $this->errors[] = $langs->trans('ErrorFieldRequired', $attributeLabel);
5691 //dol_syslog("attributeLabel=
".$attributeLabel, LOG_DEBUG);
5692 //dol_syslog("attributeType=
".$attributeType, LOG_DEBUG);
5694 if (!empty($attrfieldcomputed))
5696 if (!empty($conf->global->MAIN_STORE_COMPUTED_EXTRAFIELDS))
5698 $value = dol_eval($attrfieldcomputed, 1, 0);
5699 dol_syslog($langs->trans("Extrafieldcomputed
")." sur
".$attributeLabel."(
".$value.")
", LOG_DEBUG);
5700 $this->array_options["options_
".$key] = $value;
5702 $this->array_options["options_
".$key] = null;
5706 switch ($attributeType)
5709 if (!is_numeric($value) && $value != '')
5711 $this->errors[] = $langs->trans("ExtraFieldHasWrongValue
", $attributeLabel);
5713 } elseif ($value === '')
5715 $this->array_options["options_
".$key] = null;
5719 $value = price2num($value);
5720 if (!is_numeric($value) && $value != '')
5722 dol_syslog($langs->trans("ExtraFieldHasWrongValue
")." sur
".$attributeLabel."(
".$value."is not
'".$attributeType."')
", LOG_DEBUG);
5723 $this->errors[] = $langs->trans("ExtraFieldHasWrongValue
", $attributeLabel);
5725 } elseif ($value === '')
5727 $this->array_options["options_
".$key] = null;
5729 //dol_syslog("double value
"." sur
".$attributeLabel."(
".$value." is
'".$attributeType."')
", LOG_DEBUG);
5730 $this->array_options["options_
".$key] = $value;
5732 /*case 'select': // Not required, we chosed value='0' for undefined values
5735 $this->array_options[$key] = null;
5739 $this->array_options["options_
".$key] = price2num($this->array_options["options_
".$key]);
5742 $this->array_options["options_
".$key] = $this->db->idate($this->array_options["options_
".$key]);
5745 $this->array_options["options_
".$key] = $this->db->idate($this->array_options["options_
".$key]);
5749 $param_list = array_keys($attributeParam['options']);
5752 $InfoFieldList = explode(":
", $param_list[0]);
5753 dol_include_once($InfoFieldList[1]);
5754 if ($InfoFieldList[0] && class_exists($InfoFieldList[0]))
5756 if ($value == '-1') // -1 is key for no defined in combo list of objects
5758 $new_array_options[$key] = '';
5760 $object = new $InfoFieldList[0]($this->db);
5761 if (is_numeric($value)) $res = $object->fetch($value); // Common case
5762 else $res = $object->fetch('', $value); // For compatibility
5764 if ($res > 0) $new_array_options[$key] = $object->id;
5766 $this->error = "Id/Ref
'".$value."' for object '".$object->element."' not found
";
5767 $this->db->rollback();
5772 dol_syslog('Error bad setup of extrafield', LOG_WARNING);
5780 $linealreadyfound = 0;
5782 // Check if there is already a line for this object (in most cases, it is, but sometimes it is not, for example when extra field has been created after), so we must keep this overload)
5783 $sql = "SELECT COUNT(rowid) as nb FROM
".MAIN_DB_PREFIX.$this->table_element."_extrafields WHERE fk_object =
".$this->id;
5784 $resql = $this->db->query($sql);
5786 $tmpobj = $this->db->fetch_object($resql);
5788 $linealreadyfound = $tmpobj->nb;
5792 if ($linealreadyfound) {
5793 $sql = "UPDATE
".MAIN_DB_PREFIX.$this->table_element."_extrafields SET
".$key." =
'".$this->db->escape($this->array_options["options_".$key])."'";
5794 $sql .= " WHERE fk_object =
".$this->id;
5796 $result = $this->insertExtraFields('', $user);
5797 if ($result < 0) $error++;
5800 $resql = $this->db->query($sql);
5804 $this->error = $this->db->lasterror();
5806 if (!$error && $trigger)
5809 $this->context = array('extrafieldupdate'=>1);
5810 $result = $this->call_trigger($trigger, $userused);
5811 if ($result < 0) $error++;
5817 dol_syslog(__METHOD__.$this->error, LOG_ERR);
5818 $this->db->rollback();
5821 $this->db->commit();
5837 public function updateExtraLanguages($key, $trigger = null, $userused = null)
5839 global $conf, $langs, $user;
5841 if (empty($userused)) $userused = $user;
5845 if (!empty($conf->global->MAIN_EXTRALANGUAGES_DISABLED)) return 0; // For avoid conflicts if trigger used
5865 public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0)
5867 global $conf, $langs, $form;
5869 if (!is_object($form))
5871 require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
5872 $form = new Form($this->db);
5875 if (!empty($this->fields)) {
5876 $val = $this->fields[$key];
5883 $param['options'] = array();
5885 $size = $this->fields[$key]['size'];
5886 // Because we work on extrafields
5887 if (preg_match('/^(integer|link):(.*):(.*):(.*):(.*)/i', $val['type'], $reg)) {
5888 $param['options'] = array($reg[2].':'.$reg[3].':'.$reg[4].':'.$reg[5] => 'N');
5890 } elseif (preg_match('/^(integer|link):(.*):(.*):(.*)/i', $val['type'], $reg)) {
5891 $param['options'] = array($reg[2].':'.$reg[3].':'.$reg[4] => 'N');
5893 } elseif (preg_match('/^(integer|link):(.*):(.*)/i', $val['type'], $reg)) {
5894 $param['options'] = array($reg[2].':'.$reg[3] => 'N');
5896 } elseif (preg_match('/^(sellist):(.*):(.*):(.*):(.*)/i', $val['type'], $reg)) {
5897 $param['options'] = array($reg[2].':'.$reg[3].':'.$reg[4].':'.$reg[5] => 'N');
5899 } elseif (preg_match('/^(sellist):(.*):(.*):(.*)/i', $val['type'], $reg)) {
5900 $param['options'] = array($reg[2].':'.$reg[3].':'.$reg[4] => 'N');
5902 } elseif (preg_match('/^(sellist):(.*):(.*)/i', $val['type'], $reg)) {
5903 $param['options'] = array($reg[2].':'.$reg[3] => 'N');
5905 } elseif (preg_match('/varchar\((\d+)\)/', $val['type'], $reg)) {
5906 $param['options'] = array();
5909 } elseif (preg_match('/varchar/', $val['type'])) {
5910 $param['options'] = array();
5912 } elseif (is_array($this->fields[$key]['arrayofkeyval'])) {
5913 $param['options'] = $this->fields[$key]['arrayofkeyval'];
5916 $param['options'] = array();
5917 $type = $this->fields[$key]['type'];
5921 $label = $this->fields[$key]['label'];
5922 //$elementtype=$this->fields[$key]['elementtype']; // Seems not used
5923 $default = $this->fields[$key]['default'];
5924 $computed = $this->fields[$key]['computed'];
5925 $unique = $this->fields[$key]['unique'];
5926 $required = $this->fields[$key]['required'];
5927 $autofocusoncreate = $this->fields[$key]['autofocusoncreate'];
5929 $langfile = $this->fields[$key]['langfile'];
5930 $list = $this->fields[$key]['list'];
5931 $hidden = (in_array(abs($this->fields[$key]['visible']), array(0, 2)) ? 1 : 0);
5933 $objectid = $this->id;
5936 if (!preg_match('/^search_/', $keyprefix)) return '<span class="opacitymedium
">'.$langs->trans("AutomaticallyCalculated
").'</span>';
5940 // Set value of $morecss. For this, we use in priority showsize from parameters, then $val['css'] then autodefine
5941 if (empty($morecss) && !empty($val['css'])) {
5942 $morecss = $val['css'];
5943 } elseif (empty($morecss)) {
5944 if ($type == 'date') {
5945 $morecss = 'minwidth100imp';
5946 } elseif ($type == 'datetime' || $type == 'link') { // link means an foreign key to another primary id
5947 $morecss = 'minwidth200imp';
5948 } elseif (in_array($type, array('int', 'integer', 'price')) || preg_match('/^double(\([0-9],[0-9]\)){0,1}/', $type)) {
5949 $morecss = 'maxwidth75';
5950 } elseif ($type == 'url') {
5951 $morecss = 'minwidth400';
5952 } elseif ($type == 'boolean') {
5955 if (round($size) < 12) {
5956 $morecss = 'minwidth100';
5957 } elseif (round($size) <= 48) {
5958 $morecss = 'minwidth200';
5960 $morecss = 'minwidth400';
5965 if (in_array($type, array('date'))) {
5966 $tmp = explode(',', $size);
5970 // Do not show current date when field not required (see selectDate() method)
5971 if (!$required && $value == '') $value = '-1';
5973 // TODO Must also support $moreparam
5974 $out = $form->selectDate($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 0, 1);
5975 } elseif (in_array($type, array('datetime'))) {
5976 $tmp = explode(',', $size);
5980 // Do not show current date when field not required (see selectDate() method)
5981 if (!$required && $value == '') $value = '-1';
5983 // TODO Must also support $moreparam
5984 $out = $form->selectDate($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 0, 1, '', '', '', 1, '', '', 'tzuserrel');
5985 } elseif (in_array($type, array('duration'))) {
5986 $out = $form->select_duration($keyprefix.$key.$keysuffix, $value, 0, 'text', 0, 1);
5987 } elseif (in_array($type, array('int', 'integer'))) {
5988 $tmp = explode(',', $size);
5990 $out = '<input type="text
" class="flat
'.$morecss.'" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" maxlength="'.$newsize.'" value="'.dol_escape_htmltag($value).'"'.($moreparam ? $moreparam : '').($autofocusoncreate ? ' autofocus' : '').'>';
5991 } elseif (in_array($type, array('real'))) {
5992 $out = '<input type="text
" class="flat
'.$morecss.'" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.dol_escape_htmltag($value).'"'.($moreparam ? $moreparam : '').($autofocusoncreate ? ' autofocus' : '').'>';
5993 } elseif (preg_match('/varchar/', $type)) {
5994 $out = '<input type="text
" class="flat
'.$morecss.'" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" maxlength="'.$size.'" value="'.dol_escape_htmltag($value).'"'.($moreparam ? $moreparam : '').($autofocusoncreate ? ' autofocus' : '').'>';
5995 } elseif (in_array($type, array('mail', 'phone', 'url'))) {
5996 $out = '<input type="text
" class="flat
'.$morecss.'" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.dol_escape_htmltag($value).'" '.($moreparam ? $moreparam : '').($autofocusoncreate ? ' autofocus' : '').'>';
5997 } elseif (preg_match('/^text/', $type)) {
5998 if (!preg_match('/search_/', $keyprefix)) // If keyprefix is search_ or search_options_, we must just use a simple text field
6000 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
6001 $doleditor = new DolEditor($keyprefix.$key.$keysuffix, $value, '', 200, 'dolibarr_notes', 'In', false, false, false, ROWS_5, '90%');
6002 $out = $doleditor->Create(1);
6004 $out = '<input type="text
" class="flat
'.$morecss.' maxwidthonsmartphone
" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.dol_escape_htmltag($value).'" '.($moreparam ? $moreparam : '').'>';
6006 } elseif (preg_match('/^html/', $type)) {
6007 if (!preg_match('/search_/', $keyprefix)) { // If keyprefix is search_ or search_options_, we must just use a simple text field
6008 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
6009 $doleditor = new DolEditor($keyprefix.$key.$keysuffix, $value, '', 200, 'dolibarr_notes', 'In', false, false, !empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE, ROWS_5, '90%');
6010 $out = $doleditor->Create(1);
6012 $out = '<input type="text
" class="flat
'.$morecss.' maxwidthonsmartphone
" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.dol_escape_htmltag($value).'" '.($moreparam ? $moreparam : '').'>';
6014 } elseif ($type == 'boolean') {
6016 if (!empty($value)) {
6017 $checked = ' checked value="1
" ';
6019 $checked = ' value="1
" ';
6021 $out = '<input type="checkbox
" class="flat
'.$morecss.' maxwidthonsmartphone
" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.$checked.' '.($moreparam ? $moreparam : '').'>';
6022 } elseif ($type == 'price') {
6023 if (!empty($value)) { // $value in memory is a php numeric, we format it into user number format.
6024 $value = price($value);
6026 $out = '<input type="text
" class="flat
'.$morecss.' maxwidthonsmartphone
" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam ? $moreparam : '').'> '.$langs->getCurrencySymbol($conf->currency);
6027 } elseif (preg_match('/^double(\([0-9],[0-9]\)){0,1}/', $type)) {
6028 if (!empty($value)) { // $value in memory is a php numeric, we format it into user number format.
6029 $value = price($value);
6031 $out = '<input type="text
" class="flat
'.$morecss.' maxwidthonsmartphone
" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam ? $moreparam : '').'> ';
6032 } elseif ($type == 'select') {
6034 if (!empty($conf->use_javascript_ajax) && !empty($conf->global->MAIN_EXTRAFIELDS_USE_SELECT2))
6036 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
6037 $out .= ajax_combobox($keyprefix.$key.$keysuffix, array(), 0);
6040 $out .= '<select class="flat
'.$morecss.' maxwidthonsmartphone
" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam ? $moreparam : '').'>';
6041 if ((!isset($this->fields[$key]['default'])) || ($this->fields[$key]['notnull'] != 1))$out .= '<option value="0
"> </option>';
6042 foreach ($param['options'] as $key => $val)
6044 if ((string) $key == '') continue;
6045 list($val, $parent) = explode('|', $val);
6046 $out .= '<option value="'.$key.'"';
6047 $out .= (((string) $value == (string) $key) ? ' selected' : '');
6048 $out .= (!empty($parent) ? ' parent="'.$parent.'"' : '');
6049 $out .= '>'.$val.'</option>';
6051 $out .= '</select>';
6052 } elseif ($type == 'sellist') {
6054 if (!empty($conf->use_javascript_ajax) && !empty($conf->global->MAIN_EXTRAFIELDS_USE_SELECT2)) {
6055 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
6056 $out .= ajax_combobox($keyprefix.$key.$keysuffix, array(), 0);
6059 $out .= '<select class="flat
'.$morecss.' maxwidthonsmartphone
" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam ? $moreparam : '').'>';
6060 if (is_array($param['options'])) {
6061 $param_list = array_keys($param['options']);
6062 $InfoFieldList = explode(":
", $param_list[0]);
6066 // 1 : label field name
6067 // 2 : key fields name (if differ of rowid)
6068 // 3 : key field parent (for dependent lists)
6069 // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value
6070 $keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2].' as rowid');
6072 if (count($InfoFieldList) > 4 && !empty($InfoFieldList[4])) {
6073 if (strpos($InfoFieldList[4], 'extra.') !== false) {
6074 $keyList = 'main.'.$InfoFieldList[2].' as rowid';
6076 $keyList = $InfoFieldList[2].' as rowid';
6079 if (count($InfoFieldList) > 3 && !empty($InfoFieldList[3])) {
6080 list($parentName, $parentField) = explode('|', $InfoFieldList[3]);
6081 $keyList .= ', '.$parentField;
6084 $fields_label = explode('|', $InfoFieldList[1]);
6085 if (is_array($fields_label)) {
6087 $keyList .= implode(', ', $fields_label);
6091 $sql = 'SELECT '.$keyList;
6092 $sql .= ' FROM '.MAIN_DB_PREFIX.$InfoFieldList[0];
6093 if (!empty($InfoFieldList[4]))
6095 // can use SELECT request
6096 if (strpos($InfoFieldList[4], '$SEL$') !== false) {
6097 $InfoFieldList[4] = str_replace('$SEL$', 'SELECT', $InfoFieldList[4]);
6100 // current object id can be use into filter
6101 if (strpos($InfoFieldList[4], '$ID$') !== false && !empty($objectid)) {
6102 $InfoFieldList[4] = str_replace('$ID$', $objectid, $InfoFieldList[4]);
6104 $InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]);
6106 //We have to join on extrafield table
6107 if (strpos($InfoFieldList[4], 'extra') !== false)
6109 $sql .= ' as main, '.MAIN_DB_PREFIX.$InfoFieldList[0].'_extrafields as extra';
6110 $sqlwhere .= ' WHERE extra.fk_object=main.'.$InfoFieldList[2].' AND '.$InfoFieldList[4];
6112 $sqlwhere .= ' WHERE '.$InfoFieldList[4];
6115 $sqlwhere .= ' WHERE 1=1';
6117 // Some tables may have field, some other not. For the moment we disable it.
6118 if (in_array($InfoFieldList[0], array('tablewithentity')))
6120 $sqlwhere .= ' AND entity = '.$conf->entity;
6125 $sql .= ' ORDER BY '.implode(', ', $fields_label);
6127 dol_syslog(get_class($this).'::showInputField type=sellist', LOG_DEBUG);
6128 $resql = $this->db->query($sql);
6131 $out .= '<option value="0
"> </option>';
6132 $num = $this->db->num_rows($resql);
6137 $obj = $this->db->fetch_object($resql);
6139 // Several field into label (eq table:code|libelle:rowid)
6141 $fields_label = explode('|', $InfoFieldList[1]);
6142 if (count($fields_label) > 1)
6145 foreach ($fields_label as $field_toshow)
6147 $labeltoshow .= $obj->$field_toshow.' ';
6150 $labeltoshow = $obj->{$InfoFieldList[1]};
6152 $labeltoshow = dol_trunc($labeltoshow, 45);
6154 if ($value == $obj->rowid)
6156 foreach ($fields_label as $field_toshow)
6158 $translabel = $langs->trans($obj->$field_toshow);
6159 if ($translabel != $obj->$field_toshow) {
6160 $labeltoshow = dol_trunc($translabel, 18).' ';
6162 $labeltoshow = dol_trunc($obj->$field_toshow, 18).' ';
6165 $out .= '<option value="'.$obj->rowid.'" selected>'.$labeltoshow.'</option>';
6169 $translabel = $langs->trans($obj->{$InfoFieldList[1]});
6170 if ($translabel != $obj->{$InfoFieldList[1]}) {
6171 $labeltoshow = dol_trunc($translabel, 18);
6173 $labeltoshow = dol_trunc($obj->{$InfoFieldList[1]}, 18);
6176 if (empty($labeltoshow)) $labeltoshow = '(not defined)';
6177 if ($value == $obj->rowid)
6179 $out .= '<option value="'.$obj->rowid.'" selected>'.$labeltoshow.'</option>';
6182 if (!empty($InfoFieldList[3]) && $parentField)
6184 $parent = $parentName.':'.$obj->{$parentField};
6188 $out .= '<option value="'.$obj->rowid.'"';
6189 $out .= ($value == $obj->rowid ? ' selected' : '');
6190 $out .= (!empty($parent) ? ' parent="'.$parent.'"' : '');
6191 $out .= '>'.$labeltoshow.'</option>';
6196 $this->db->free($resql);
6198 print 'Error in request '.$sql.' '.$this->db->lasterror().'. Check setup of extra parameters.<br>';
6201 $out .= '</select>';
6202 } elseif ($type == 'checkbox') {
6203 $value_arr = explode(',', $value);
6204 $out = $form->multiselectarray($keyprefix.$key.$keysuffix, (empty($param['options']) ?null:$param['options']), $value_arr, '', 0, '', 0, '100%');
6205 } elseif ($type == 'radio') {
6207 foreach ($param['options'] as $keyopt => $val)
6209 $out .= '<input class="flat
'.$morecss.'" type="radio
" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam ? $moreparam : '');
6210 $out .= ' value="'.$keyopt.'"';
6211 $out .= ' id="'.$keyprefix.$key.$keysuffix.'_
'.$keyopt.'"';
6212 $out .= ($value == $keyopt ? 'checked' : '');
6213 $out .= '/><label for="'.$keyprefix.$key.$keysuffix.'_
'.$keyopt.'">'.$val.'</label><br>';
6215 } elseif ($type == 'chkbxlst') {
6216 if (is_array($value)) {
6217 $value_arr = $value;
6219 $value_arr = explode(',', $value);
6222 if (is_array($param['options'])) {
6223 $param_list = array_keys($param['options']);
6224 $InfoFieldList = explode(":
", $param_list[0]);
6228 // 1 : label field name
6229 // 2 : key fields name (if differ of rowid)
6230 // 3 : key field parent (for dependent lists)
6231 // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value
6232 $keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2].' as rowid');
6234 if (count($InfoFieldList) > 3 && !empty($InfoFieldList[3])) {
6235 list ($parentName, $parentField) = explode('|', $InfoFieldList[3]);
6236 $keyList .= ', '.$parentField;
6238 if (count($InfoFieldList) > 4 && !empty($InfoFieldList[4])) {
6239 if (strpos($InfoFieldList[4], 'extra.') !== false) {
6240 $keyList = 'main.'.$InfoFieldList[2].' as rowid';
6242 $keyList = $InfoFieldList[2].' as rowid';
6246 $fields_label = explode('|', $InfoFieldList[1]);
6247 if (is_array($fields_label)) {
6249 $keyList .= implode(', ', $fields_label);
6253 $sql = 'SELECT '.$keyList;
6254 $sql .= ' FROM '.MAIN_DB_PREFIX.$InfoFieldList[0];
6255 if (!empty($InfoFieldList[4])) {
6256 // can use SELECT request
6257 if (strpos($InfoFieldList[4], '$SEL$') !== false) {
6258 $InfoFieldList[4] = str_replace('$SEL$', 'SELECT', $InfoFieldList[4]);
6261 // current object id can be use into filter
6262 if (strpos($InfoFieldList[4], '$ID$') !== false && !empty($objectid)) {
6263 $InfoFieldList[4] = str_replace('$ID$', $objectid, $InfoFieldList[4]);
6265 $InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]);
6268 // We have to join on extrafield table
6269 if (strpos($InfoFieldList[4], 'extra') !== false) {
6270 $sql .= ' as main, '.MAIN_DB_PREFIX.$InfoFieldList[0].'_extrafields as extra';
6271 $sqlwhere .= ' WHERE extra.fk_object=main.'.$InfoFieldList[2].' AND '.$InfoFieldList[4];
6273 $sqlwhere .= ' WHERE '.$InfoFieldList[4];
6276 $sqlwhere .= ' WHERE 1=1';
6278 // Some tables may have field, some other not. For the moment we disable it.
6279 if (in_array($InfoFieldList[0], array('tablewithentity')))
6281 $sqlwhere .= ' AND entity = '.$conf->entity;
6283 // $sql.=preg_replace('/^ AND /','',$sqlwhere);
6287 dol_syslog(get_class($this).'::showInputField type=chkbxlst', LOG_DEBUG);
6288 $resql = $this->db->query($sql);
6290 $num = $this->db->num_rows($resql);
6297 $obj = $this->db->fetch_object($resql);
6300 // Several field into label (eq table:code|libelle:rowid)
6301 $fields_label = explode('|', $InfoFieldList[1]);
6302 if (count($fields_label) > 1) {
6304 foreach ($fields_label as $field_toshow) {
6305 $labeltoshow .= $obj->$field_toshow.' ';
6308 $labeltoshow = $obj->{$InfoFieldList[1]};
6310 $labeltoshow = dol_trunc($labeltoshow, 45);
6312 if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
6313 foreach ($fields_label as $field_toshow) {
6314 $translabel = $langs->trans($obj->$field_toshow);
6315 if ($translabel != $obj->$field_toshow) {
6316 $labeltoshow = dol_trunc($translabel, 18).' ';
6318 $labeltoshow = dol_trunc($obj->$field_toshow, 18).' ';
6322 $data[$obj->rowid] = $labeltoshow;
6325 $translabel = $langs->trans($obj->{$InfoFieldList[1]});
6326 if ($translabel != $obj->{$InfoFieldList[1]}) {
6327 $labeltoshow = dol_trunc($translabel, 18);
6329 $labeltoshow = dol_trunc($obj->{$InfoFieldList[1]}, 18);
6332 if (empty($labeltoshow)) {
6333 $labeltoshow = '(not defined)';
6336 if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
6337 $data[$obj->rowid] = $labeltoshow;
6340 if (!empty($InfoFieldList[3]) && $parentField) {
6341 $parent = $parentName.':'.$obj->{$parentField};
6345 $data[$obj->rowid] = $labeltoshow;
6350 $this->db->free($resql);
6352 $out = $form->multiselectarray($keyprefix.$key.$keysuffix, $data, $value_arr, '', 0, '', 0, '100%');
6354 print 'Error in request '.$sql.' '.$this->db->lasterror().'. Check setup of extra parameters.<br>';
6357 } elseif ($type == 'link') {
6358 $param_list = array_keys($param['options']); // $param_list='ObjectName:classPath[:AddCreateButtonOrNot[:Filter]]'
6359 $param_list_array = explode(':', $param_list[0]);
6360 $showempty = (($required && $default != '') ? 0 : 1);
6362 if (!preg_match('/search_/', $keyprefix)) {
6363 if (!empty($param_list_array[2])) { // If the entry into $fields is set to add a create button
6364 if (!empty($this->fields[$key]['picto'])) {
6365 $morecss .= ' widthcentpercentminusxx';
6367 $morecss .= ' widthcentpercentminusx';
6370 if (!empty($this->fields[$key]['picto'])) {
6371 $morecss .= ' widthcentpercentminusx';
6376 $out = $form->selectForForms($param_list[0], $keyprefix.$key.$keysuffix, $value, $showempty, '', '', $morecss, $moreparam, 0, empty($val['disabled']) ? 0 : 1);
6378 if (!empty($param_list_array[2])) { // If the entry into $fields is set to add a create button
6379 if (!GETPOSTISSET('backtopage') && empty($val['disabled']) && empty($nonewbutton)) // To avoid to open several times the 'Create Object' button and to avoid to have button if field is protected by a "disabled
".
6381 list($class, $classfile) = explode(':', $param_list[0]);
6382 if (file_exists(dol_buildpath(dirname(dirname($classfile)).'/card.php'))) $url_path = dol_buildpath(dirname(dirname($classfile)).'/card.php', 1);
6383 else $url_path = dol_buildpath(dirname(dirname($classfile)).'/'.strtolower($class).'_card.php', 1);
6384 $paramforthenewlink = '';
6385 $paramforthenewlink .= (GETPOSTISSET('action') ? '&action='.GETPOST('action', 'aZ09') : '');
6386 $paramforthenewlink .= (GETPOSTISSET('id') ? '&id='.GETPOST('id', 'int') : '');
6387 $paramforthenewlink .= '&fk_'.strtolower($class).'=--IDFORBACKTOPAGE--';
6388 // TODO Add Javascript code to add input fields already filled into $paramforthenewlink so we won't loose them when going back to main page
6389 $out .= '<a class="butActionNew
" title="'.$langs->trans("New").'" href="'.$url_path.'?action=create&backtopage=
'.urlencode($_SERVER['PHP_SELF
'].($paramforthenewlink ? '?
'.$paramforthenewlink : '')).'"><span class="fa fa-plus-circle valignmiddle
"></span></a>';
6392 } elseif ($type == 'password') {
6393 // If prefix is 'search_', field is used as a filter, we use a common text field.
6394 $out = '<input type="'.($keyprefix == 'search_
' ? 'text
' : 'password
').'" class="flat
'.$morecss.'" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam ? $moreparam : '').'>';
6395 } elseif ($type == 'array') {
6397 $newval['type'] = 'varchar(256)';
6400 if (!empty($value)) {
6401 foreach ($value as $option) {
6402 $out .= '<span><a class="'.dol_escape_htmltag($keyprefix.$key.$keysuffix).'_del
" href="javascript:;
"><span class="fa fa-minus-circle valignmiddle
"></span></a> ';
6403 $out .= $this->showInputField($newval, $keyprefix.$key.$keysuffix.'[]', $option, $moreparam, '', '', $morecss).'<br></span>';
6406 $out .= '<a id="'.dol_escape_htmltag($keyprefix.$key.$keysuffix).'_add
" href="javascript:;
"><span class="fa fa-plus-circle valignmiddle
"></span></a>';
6408 $newInput = '<span><a class="'.dol_escape_htmltag($keyprefix.$key.$keysuffix).'_del
" href="javascript:;
"><span class="fa fa-minus-circle valignmiddle
"></span></a> ';
6409 $newInput .= $this->showInputField($newval, $keyprefix.$key.$keysuffix.'[]', '', $moreparam, '', '', $morecss).'<br></span>';
6411 if (!empty($conf->use_javascript_ajax)) {
6414 $(document).ready(function() {
6415 $("a#
'.dol_escape_js($keyprefix.$key.$keysuffix).'_add
").click(function() {
6416 $("'.dol_escape_js($newInput).'").insertBefore(this);
6419 $(document).on("click
", "a.
'.dol_escape_js($keyprefix.$key.$keysuffix).'_del
", function() {
6420 $(this).parent().remove();
6426 if (!empty($hidden)) {
6427 $out = '<input type="hidden
" value="'.$value.'" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'"/>';
6430 if ($isDependList==1) {
6431 $out .= $this->getJSListDependancies('_common');
6434 if ($type == 'date') $out.=' (YYYY-MM-DD)';
6435 elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)';
6453 public function showOutputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '')
6455 global $conf, $langs, $form;
6457 if (!is_object($form))
6459 require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
6460 $form = new Form($this->db);
6463 $objectid = $this->id;
6464 $label = $val['label'];
6465 $type = $val['type'];
6466 $size = $val['css'];
6469 // Convert var to be able to share same code than showOutputField of extrafields
6470 if (preg_match('/varchar\((\d+)\)/', $type, $reg))
6472 $type = 'varchar'; // convert varchar(xx) int varchar
6474 } elseif (preg_match('/varchar/', $type)) $type = 'varchar'; // convert varchar(xx) int varchar
6475 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) $type = 'select';
6476 if (preg_match('/^integer:(.*):(.*)/i', $val['type'], $reg)) $type = 'link';
6478 $default = $val['default'];
6479 $computed = $val['computed'];
6480 $unique = $val['unique'];
6481 $required = $val['required'];
6483 $param['options'] = array();
6485 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) $param['options'] = $val['arrayofkeyval'];
6486 if (preg_match('/^integer:(.*):(.*)/i', $val['type'], $reg)) {
6488 $param['options'] = array($reg[1].':'.$reg[2]=>$reg[1].':'.$reg[2]);
6489 } elseif (preg_match('/^sellist:(.*):(.*):(.*):(.*)/i', $val['type'], $reg)) {
6490 $param['options'] = array($reg[1].':'.$reg[2].':'.$reg[3].':'.$reg[4] => 'N');
6492 } elseif (preg_match('/^sellist:(.*):(.*):(.*)/i', $val['type'], $reg)) {
6493 $param['options'] = array($reg[1].':'.$reg[2].':'.$reg[3] => 'N');
6495 } elseif (preg_match('/^sellist:(.*):(.*)/i', $val['type'], $reg)) {
6496 $param['options'] = array($reg[1].':'.$reg[2] => 'N');
6500 $langfile = $val['langfile'];
6501 $list = $val['list'];
6502 $help = $val['help'];
6503 $hidden = (($val['visible'] == 0) ? 1 : 0); // If zero, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller)
6505 if ($hidden) return '';
6507 // If field is a computed field, value must become result of compute
6510 // Make the eval of compute string
6511 //var_dump($computed);
6512 $value = dol_eval($computed, 1, 0);
6515 if (empty($morecss))
6517 if ($type == 'date') {
6518 $morecss = 'minwidth100imp';
6519 } elseif ($type == 'datetime' || $type == 'timestamp') {
6520 $morecss = 'minwidth200imp';
6521 } elseif (in_array($type, array('int', 'double', 'price'))) {
6522 $morecss = 'maxwidth75';
6523 } elseif ($type == 'url') {
6524 $morecss = 'minwidth400';
6525 } elseif ($type == 'boolean') {
6528 if (round($size) < 12) {
6529 $morecss = 'minwidth100';
6530 } elseif (round($size) <= 48) {
6531 $morecss = 'minwidth200';
6533 $morecss = 'minwidth400';
6538 // Format output value differently according to properties of field
6539 if ($key == 'ref' && method_exists($this, 'getNomUrl')) $value = $this->getNomUrl(1, '', 0, '', 1);
6540 elseif ($key == 'status' && method_exists($this, 'getLibStatut')) $value = $this->getLibStatut(3);
6541 elseif ($type == 'date') {
6542 if (!empty($value)) {
6543 $value = dol_print_date($value, 'day'); // We suppose dates without time are always gmt (storage of course + output)
6547 } elseif ($type == 'datetime' || $type == 'timestamp') {
6548 if (!empty($value)) {
6549 $value = dol_print_date($value, 'dayhour', 'tzuserrel');
6553 } elseif ($type == 'duration') {
6554 include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
6555 if (!is_null($value) && $value !== '') {
6556 $value = convertSecondToTime($value, 'allhourmin');
6558 } elseif ($type == 'double' || $type == 'real') {
6559 if (!is_null($value) && $value !== '') {
6560 $value = price($value);
6562 } elseif ($type == 'boolean') {
6564 if (!empty($value)) {
6565 $checked = ' checked ';
6567 $value = '<input type="checkbox
" '.$checked.' '.($moreparam ? $moreparam : '').' readonly disabled>';
6568 } elseif ($type == 'mail') {
6569 $value = dol_print_email($value, 0, 0, 0, 64, 1, 1);
6570 } elseif ($type == 'url') {
6571 $value = dol_print_url($value, '_blank', 32, 1);
6572 } elseif ($type == 'phone') {
6573 $value = dol_print_phone($value, '', 0, 0, '', ' ', 1);
6574 } elseif ($type == 'price')
6576 if (!is_null($value) && $value !== '') {
6577 $value = price($value, 0, $langs, 0, 0, -1, $conf->currency);
6579 } elseif ($type == 'select') {
6580 $value = $param['options'][$value];
6581 } elseif ($type == 'sellist') {
6582 $param_list = array_keys($param['options']);
6583 $InfoFieldList = explode(":
", $param_list[0]);
6585 $selectkey = "rowid
";
6588 if (count($InfoFieldList) > 4 && !empty($InfoFieldList[4])) {
6589 $selectkey = $InfoFieldList[2];
6590 $keyList = $InfoFieldList[2].' as rowid';
6593 $fields_label = explode('|', $InfoFieldList[1]);
6594 if (is_array($fields_label)) {
6596 $keyList .= implode(', ', $fields_label);
6599 $sql = 'SELECT '.$keyList;
6600 $sql .= ' FROM '.MAIN_DB_PREFIX.$InfoFieldList[0];
6601 if (strpos($InfoFieldList[4], 'extra') !== false)
6605 if ($selectkey == 'rowid' && empty($value)) {
6606 $sql .= " WHERE
".$selectkey."=0
";
6607 } elseif ($selectkey == 'rowid') {
6608 $sql .= " WHERE
".$selectkey."=
".$this->db->escape($value);
6610 $sql .= " WHERE
".$selectkey."=
'".$this->db->escape($value)."'";
6613 //$sql.= ' AND entity = '.$conf->entity;
6615 dol_syslog(get_class($this).':showOutputField:$type=sellist', LOG_DEBUG);
6616 $resql = $this->db->query($sql);
6619 $value = ''; // value was used, so now we reste it to use it to build final output
6621 $obj = $this->db->fetch_object($resql);
6623 // Several field into label (eq table:code|libelle:rowid)
6624 $fields_label = explode('|', $InfoFieldList[1]);
6626 if (is_array($fields_label) && count($fields_label) > 1)
6628 foreach ($fields_label as $field_toshow)
6631 if (!empty($obj->$field_toshow)) {
6632 $translabel = $langs->trans($obj->$field_toshow);
6634 if ($translabel != $field_toshow) {
6635 $value .= dol_trunc($translabel, 18).' ';
6637 $value .= $obj->$field_toshow.' ';
6642 if (!empty($obj->{$InfoFieldList[1]})) {
6643 $translabel = $langs->trans($obj->{$InfoFieldList[1]});
6645 if ($translabel != $obj->{$InfoFieldList[1]}) {
6646 $value = dol_trunc($translabel, 18);
6648 $value = $obj->{$InfoFieldList[1]};
6651 } else dol_syslog(get_class($this).'::showOutputField error '.$this->db->lasterror(), LOG_WARNING);
6652 } elseif ($type == 'radio') {
6653 $value = $param['options'][$value];
6654 } elseif ($type == 'checkbox') {
6655 $value_arr = explode(',', $value);
6657 if (is_array($value_arr) && count($value_arr) > 0)
6660 foreach ($value_arr as $keyval=>$valueval) {
6661 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories
" style="background: #bbb
">'.$param['options'][$valueval].'</li>';
6663 $value = '<div class="select2-container-multi-dolibarr
" style="width: 90%;
"><ul class="select2-choices-dolibarr
">'.implode(' ', $toprint).'</ul></div>';
6665 } elseif ($type == 'chkbxlst') {
6666 $value_arr = explode(',', $value);
6668 $param_list = array_keys($param['options']);
6669 $InfoFieldList = explode(":
", $param_list[0]);
6671 $selectkey = "rowid
";
6674 if (count($InfoFieldList) >= 3) {
6675 $selectkey = $InfoFieldList[2];
6676 $keyList = $InfoFieldList[2].' as rowid';
6679 $fields_label = explode('|', $InfoFieldList[1]);
6680 if (is_array($fields_label)) {
6682 $keyList .= implode(', ', $fields_label);
6685 $sql = 'SELECT '.$keyList;
6686 $sql .= ' FROM '.MAIN_DB_PREFIX.$InfoFieldList[0];
6687 if (strpos($InfoFieldList[4], 'extra') !== false) {
6690 // $sql.= " WHERE
".$selectkey."=
'".$this->db->escape($value)."'";
6691 // $sql.= ' AND entity = '.$conf->entity;
6693 dol_syslog(get_class($this).':showOutputField:$type=chkbxlst', LOG_DEBUG);
6694 $resql = $this->db->query($sql);
6696 $value = ''; // value was used, so now we reste it to use it to build final output
6698 while ($obj = $this->db->fetch_object($resql)) {
6699 // Several field into label (eq table:code|libelle:rowid)
6700 $fields_label = explode('|', $InfoFieldList[1]);
6701 if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
6702 if (is_array($fields_label) && count($fields_label) > 1) {
6703 foreach ($fields_label as $field_toshow) {
6705 if (!empty($obj->$field_toshow)) {
6706 $translabel = $langs->trans($obj->$field_toshow);
6708 if ($translabel != $field_toshow) {
6709 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories
" style="background: #bbb
">'.dol_trunc($translabel, 18).'</li>';
6711 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories
" style="background: #bbb
">'.$obj->$field_toshow.'</li>';
6716 if (!empty($obj->{$InfoFieldList[1]})) {
6717 $translabel = $langs->trans($obj->{$InfoFieldList[1]});
6719 if ($translabel != $obj->{$InfoFieldList[1]}) {
6720 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories
" style="background: #bbb
">'.dol_trunc($translabel, 18).'</li>';
6722 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories
" style="background: #bbb
">'.$obj->{$InfoFieldList[1]}.'</li>';
6727 $value = '<div class="select2-container-multi-dolibarr
" style="width: 90%;
"><ul class="select2-choices-dolibarr
">'.implode(' ', $toprint).'</ul></div>';
6729 dol_syslog(get_class($this).'::showOutputField error '.$this->db->lasterror(), LOG_WARNING);
6731 } elseif ($type == 'link') {
6734 // only if something to display (perf)
6737 $param_list = array_keys($param['options']); // $param_list='ObjectName:classPath'
6739 $InfoFieldList = explode(":
", $param_list[0]);
6740 $classname = $InfoFieldList[0];
6741 $classpath = $InfoFieldList[1];
6742 $getnomurlparam = (empty($InfoFieldList[2]) ? 3 : $InfoFieldList[2]);
6743 if (!empty($classpath))
6745 dol_include_once($InfoFieldList[1]);
6746 if ($classname && class_exists($classname))
6748 $object = new $classname($this->db);
6749 $object->fetch($value);
6750 $value = $object->getNomUrl($getnomurlparam);
6753 dol_syslog('Error bad setup of extrafield', LOG_WARNING);
6754 return 'Error bad setup of extrafield';
6757 } elseif (preg_match('/^(text|html)/', $type)) {
6758 $value = dol_htmlentitiesbr($value);
6759 } elseif ($type == 'password') {
6760 $value = preg_replace('/./i', '*', $value);
6761 } elseif ($type == 'array') {
6762 $value = implode('<br>', $value);
6765 //print $type.'-'.$size.'-'.$value;
6784 public function showOptionals($extrafields, $mode = 'view', $params = null, $keysuffix = '', $keyprefix = '', $onetrtd = 0)
6786 global $db, $conf, $langs, $action, $form, $hookmanager;
6788 if (!is_object($form)) $form = new Form($db);
6792 $parameters = array();
6793 $reshook = $hookmanager->executeHooks('showOptionals', $parameters, $this, $action); // Note that $action and $object may have been modified by hook
6794 if (empty($reshook))
6796 if (is_array($extrafields->attributes[$this->table_element]['label']) && count($extrafields->attributes[$this->table_element]['label']) > 0)
6799 $out .= '<!-- showOptionals --> ';
6802 $extrafields_collapse_num = '';
6804 foreach ($extrafields->attributes[$this->table_element]['label'] as $key=>$label)
6806 // Show only the key field in params
6807 if (is_array($params) && array_key_exists('onlykey', $params) && $key != $params['onlykey']) continue;
6809 // Test on 'enabled' ('enabled' is different than 'list' = 'visibility')
6811 if ($enabled && isset($extrafields->attributes[$this->table_element]['enabled'][$key]))
6813 $enabled = dol_eval($extrafields->attributes[$this->table_element]['enabled'][$key], 1);
6815 if (empty($enabled)) continue;
6818 if ($visibility && isset($extrafields->attributes[$this->table_element]['list'][$key]))
6820 $visibility = dol_eval($extrafields->attributes[$this->table_element]['list'][$key], 1);
6824 if ($perms && isset($extrafields->attributes[$this->table_element]['perms'][$key]))
6826 $perms = dol_eval($extrafields->attributes[$this->table_element]['perms'][$key], 1);
6829 if (($mode == 'create') && abs($visibility) != 1 && abs($visibility) != 3) continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list
6830 elseif (($mode == 'edit') && abs($visibility) != 1 && abs($visibility) != 3 && abs($visibility) != 4) continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list and <> 4 = not visible at the creation
6831 elseif ($mode == 'view' && empty($visibility)) continue;
6832 if (empty($perms)) continue;
6833 // Load language if required
6834 if (!empty($extrafields->attributes[$this->table_element]['langfile'][$key])) {
6835 $langs->load($extrafields->attributes[$this->table_element]['langfile'][$key]);
6839 if (is_array($params) && count($params) > 0) {
6840 if (array_key_exists('cols', $params)) {
6841 $colspan = $params['cols'];
6842 } elseif (array_key_exists('colspan', $params)) { // For backward compatibility. Use cols instead now.
6844 if (preg_match('/colspan="(\d+)
"/', $params['colspan'], $reg)) {
6847 $colspan = $params['colspan'];
6854 $value = $this->array_options["options_
".$key.$keysuffix]; // Value may be clean or formated later
6858 // We get the value of property found with GETPOST so it takes into account:
6859 // default values overwrite, restore back to list link, ... (but not 'default value in database' of field)
6860 $check = 'alphanohtml';
6861 if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('html', 'text'))) {
6862 $check = 'restricthtml';
6864 $getposttemp = GETPOST($keyprefix.'options_'.$key.$keysuffix, $check, 3); // GETPOST can get value from GET, POST or setup of default values overwrite.
6865 // GETPOST("options_
" . $key) can be 'abc' or array(0=>'abc')
6866 if (is_array($getposttemp) || $getposttemp != '' || GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix))
6868 if (is_array($getposttemp)) {
6869 // $getposttemp is an array but following code expects a comma separated string
6870 $value = implode(",
", $getposttemp);
6872 $value = $getposttemp;
6875 $value = $this->array_options["options_
".$key]; // No GET, no POST, no default value, so we take value of object.
6877 //var_dump($keyprefix.' - '.$key.' - '.$keysuffix.' - '.$keyprefix.'options_'.$key.$keysuffix.' - '.$this->array_options["options_
".$key.$keysuffix].' - '.$getposttemp.' - '.$value);
6881 // Output value of the current field
6882 if ($extrafields->attributes[$this->table_element]['type'][$key] == 'separate')
6884 $extrafields_collapse_num = '';
6885 $extrafield_param = $extrafields->attributes[$this->table_element]['param'][$key];
6886 if (!empty($extrafield_param) && is_array($extrafield_param)) {
6887 $extrafield_param_list = array_keys($extrafield_param['options']);
6889 if (count($extrafield_param_list) > 0) {
6890 $extrafield_collapse_display_value = intval($extrafield_param_list[0]);
6892 if ($extrafield_collapse_display_value == 1 || $extrafield_collapse_display_value == 2) {
6893 $extrafields_collapse_num = $extrafields->attributes[$this->table_element]['pos'][$key];
6898 $out .= $extrafields->showSeparator($key, $this, ($colspan + 1));
6900 $class = (!empty($extrafields->attributes[$this->table_element]['hidden'][$key]) ? 'hideobject ' : '');
6902 if (is_array($params) && count($params) > 0) {
6903 if (array_key_exists('class', $params)) {
6904 $class .= $params['class'].' ';
6906 if (array_key_exists('style', $params)) {
6907 $csstyle = $params['style'];
6911 // add html5 elements
6912 $domData = ' data-element="extrafield
"';
6913 $domData .= ' data-targetelement="'.$this->element.'"';
6914 $domData .= ' data-targetid="'.$this->id.'"';
6916 $html_id = (empty($this->id) ? '' : 'extrarow-'.$this->element.'_'.$key.'_'.$this->id);
6918 if (!empty($conf->global->MAIN_EXTRAFIELDS_USE_TWO_COLUMS) && ($e % 2) == 0) { $colspan = '0'; }
6920 if ($action == 'selectlines') { $colspan++; }
6922 // Convert date into timestamp format (value in memory must be a timestamp)
6923 if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('date')))
6925 $datenotinstring = $this->array_options['options_'.$key];
6926 if (!is_numeric($this->array_options['options_'.$key])) // For backward compatibility
6928 $datenotinstring = $this->db->jdate($datenotinstring);
6930 $value = (GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix)) ? dol_mktime(12, 0, 0, GETPOST($keyprefix.'options_'.$key.$keysuffix."month
", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."day
", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."year
", 'int', 3)) : $datenotinstring;
6932 if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('datetime')))
6934 $datenotinstring = $this->array_options['options_'.$key];
6935 if (!is_numeric($this->array_options['options_'.$key])) // For backward compatibility
6937 $datenotinstring = $this->db->jdate($datenotinstring);
6939 $value = (GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix)) ? dol_mktime(GETPOST($keyprefix.'options_'.$key.$keysuffix."hour
", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."min
", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."sec
", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."month
", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."day
", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."year
", 'int', 3), 'tzuserrel') : $datenotinstring;
6941 // Convert float submited string into real php numeric (value in memory must be a php numeric)
6942 if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('price', 'double')))
6944 $value = (GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix) || $value) ? price2num($value) : $this->array_options['options_'.$key];
6947 // HTML, text, select, integer and varchar: take into account default value in database if in create mode
6948 if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('html', 'text', 'varchar', 'select', 'int')))
6950 if ($action == 'create') $value = (GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix) || $value) ? $value : $extrafields->attributes[$this->table_element]['default'][$key];
6953 $labeltoshow = $langs->trans($label);
6954 $helptoshow = $langs->trans($extrafields->attributes[$this->table_element]['help'][$key]);
6956 $out .= '<tr '.($html_id ? 'id="'.$html_id.'" ' : '').$csstyle.' class="'.$class.$this->element.'_extras_
'.$key.' trextrafields_collapse
'.$extrafields_collapse_num.'" '.$domData.' >';
6957 if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER) && $action == 'view') {
6958 $out .= '<td></td>';
6960 $out .= '<td class="wordbreak
';
6961 //$out .= "titlefield";
6962 //if (GETPOST('action
', 'restricthtml
') == 'create
') $out.='create
';
6963 // BUG #11554 : For public page, use red dot for required fields, instead of bold label
6964 $tpl_context = isset($params["tpl_context"]) ? $params["tpl_context"] : "none";
6965 if ($tpl_context == "public") { // Public page : red dot instead of fieldrequired characters
6967 if (!empty($extrafields->attributes[$this->table_element]['help'][$key])) $out .= $form->textwithpicto($labeltoshow, $helptoshow);
6968 else $out .= $labeltoshow;
6969 if ($mode != 'view' && !empty($extrafields->attributes[$this->table_element]['required'][$key])) $out .= ' <font color="red
">*</font>';
6971 if ($mode != 'view' && !empty($extrafields->attributes[$this->table_element]['required'][$key])) $out .= ' fieldrequired';
6973 if (!empty($extrafields->attributes[$this->table_element]['help
'][$key])) $out .= $form->textwithpicto($labeltoshow, $helptoshow);
6974 else $out .= $labeltoshow;
6978 $html_id = !empty($this->id) ? $this->element.'_extras_
'.$key.'_
'.$this->id : '';
6980 $out .= '<td
'.($html_id ? 'id=
"'.$html_id.'" ' : '').'class=
"'.$this->element.'_extras_'.$key.'" '.($colspan ? ' colspan=
"'.$colspan.'"' : '').'>
';
6984 $out .= $extrafields->showOutputField($key, $value);
6987 $out .= $extrafields->showInputField($key, $value, '', $keysuffix, '', 0, $this->id, $this->table_element);
6990 $out .= $extrafields->showInputField($key, $value, '', $keysuffix, '', 0, $this->id, $this->table_element);
6996 /*for($ii = 0; $ii < ($colspan - 1); $ii++)
6998 $out .='<td
class=
"'.$this->element.'_extras_'.$key.'"></td>
';
7001 if (!empty($conf->global->MAIN_EXTRAFIELDS_USE_TWO_COLUMS) && (($e % 2) == 1)) $out .= '</tr>
';
7002 else $out .= '</tr>
';
7007 // Add code to manage list depending on others
7008 if (!empty($conf->use_javascript_ajax)) {
7009 $out .= $this->getJSListDependancies();
7016 $out .= $hookmanager->resPrint;
7025 public function getJSListDependancies($type = '_extra
')
7029 jQuery(document).ready(
function() {
7030 function showOptions
'.$type.'(child_list, parent_list, orig_select)
7032 var val = $(
"select[name=\""+parent_list+
"\"]").val();
7033 var parentVal = parent_list +
":" + val;
7035 var options = orig_select.find(
"option[parent=\""+parentVal+
"\"]").clone();
7036 $(
"select[name=\""+child_list+
"\"] option[parent]").
remove();
7037 $(
"select[name=\""+child_list+
"\"]").append(options);
7039 var options = orig_select.find(
"option[parent]").clone();
7040 $(
"select[name=\""+child_list+
"\"] option[parent]").
remove();
7041 $(
"select[name=\""+child_list+
"\"]").append(options);
7044 function setListDependencies
'.$type.'() {
7045 jQuery(
"select option[parent]").parent().each(
function() {
7046 var orig_select = {};
7047 var child_list = $(
this).attr(
"name");
7048 orig_select[child_list] = $(
this).clone();
7049 var parent = $(
this).find(
"option[parent]:first").attr(
"parent");
7050 var infos = parent.split(
":");
7051 var parent_list = infos[0];
7052 $(
"select[name=\""+parent_list+
"\"]").change(
function() {
7053 showOptions
'.$type.'(child_list, parent_list, orig_select[child_list]);
7058 setListDependencies
'.$type.'();
7068 public function getRights()
7072 $element = $this->element;
7073 if ($element == 'facturerec
') $element = 'facture
';
7075 return $user->rights->{$element};
7090 public static function commonReplaceThirdparty(DoliDB $db, $origin_id, $dest_id, array $tables, $ignoreerrors = 0)
7092 foreach ($tables as $table)
7094 $sql = 'UPDATE
'.MAIN_DB_PREFIX.$table.' SET fk_soc =
'.$dest_id.' WHERE fk_soc =
'.$origin_id;
7096 if (!$db->query($sql))
7098 if ($ignoreerrors) return true; // TODO Not enough. If there is A-B on kept thirdarty and B-C on old one, we must get A-B-C after merge. Not A-B.
7099 //$this->errors = $db->lasterror();
7119 public function defineBuyPrice($unitPrice = 0.0, $discountPercent = 0.0, $fk_product = 0)
7125 if (($unitPrice > 0) && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) // In most cases, test here is false
7127 $buyPrice = $unitPrice * (1 - $discountPercent / 100);
7129 // Get cost price for margin calculation
7130 if (!empty($fk_product))
7132 if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == 'costprice
')
7134 require_once DOL_DOCUMENT_ROOT.'/product/
class/product.class.php
';
7135 $product = new Product($this->db);
7136 $result = $product->fetch($fk_product);
7139 $this->errors[] = 'ErrorProductIdDoesNotExists
';
7142 if ($product->cost_price > 0)
7144 $buyPrice = $product->cost_price;
7145 } elseif ($product->pmp > 0)
7147 $buyPrice = $product->pmp;
7149 } elseif (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == 'pmp
')
7151 require_once DOL_DOCUMENT_ROOT.'/product/
class/product.class.php
';
7152 $product = new Product($this->db);
7153 $result = $product->fetch($fk_product);
7156 $this->errors[] = 'ErrorProductIdDoesNotExists
';
7159 if ($product->pmp > 0)
7161 $buyPrice = $product->pmp;
7165 if (empty($buyPrice) && isset($conf->global->MARGIN_TYPE) && in_array($conf->global->MARGIN_TYPE, array('1
', 'pmp
', 'costprice
')))
7167 require_once DOL_DOCUMENT_ROOT.'/fourn/
class/fournisseur.product.class.php
';
7168 $productFournisseur = new ProductFournisseur($this->db);
7169 if (($result = $productFournisseur->find_min_price_product_fournisseur($fk_product)) > 0)
7171 $buyPrice = $productFournisseur->fourn_unitprice;
7172 } elseif ($result < 0)
7174 $this->errors[] = $productFournisseur->error;
7183 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
7201 public function show_photos($modulepart, $sdir, $size = 0, $nbmax = 0, $nbbyrow = 5, $showfilename = 0, $showaction = 0, $maxHeight = 120, $maxWidth = 160, $nolink = 0, $notitle = 0, $usesharelink = 0)
7204 global $conf, $user, $langs;
7206 include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php
';
7207 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php
';
7209 $sortfield = 'position_name
';
7215 $dir .= get_exdir(0, 0, 0, 0, $this, $modulepart);
7216 $pdir .= get_exdir(0, 0, 0, 0, $this, $modulepart);
7218 // For backward compatibility
7219 if ($modulepart == 'product
') {
7220 if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) {
7221 $dir = $sdir.'/
'.get_exdir($this->id, 2, 0, 0, $this, $modulepart).$this->id."/photos/";
7222 $pdir = '/
'.get_exdir($this->id, 2, 0, 0, $this, $modulepart).$this->id."/photos/";
7226 // Defined relative dir to DOL_DATA_ROOT
7229 $relativedir = preg_replace('/^
'.preg_quote(DOL_DATA_ROOT, '/
').'/
', '', $dir);
7230 $relativedir = preg_replace('/^[\\/]/
', '', $relativedir);
7231 $relativedir = preg_replace('/[\\/]$/
', '', $relativedir);
7234 $dirthumb = $dir.'thumbs/
';
7235 $pdirthumb = $pdir.'thumbs/
';
7237 $return = '<!-- Photo -->
'."\n";
7240 $filearray = dol_dir_list($dir, "files", 0, '', '(\.meta|_preview.*\.png)$
', $sortfield, (strtolower($sortorder) == 'desc
' ?SORT_DESC:SORT_ASC), 1);
7242 /*if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) // For backward compatiblity, we scan also old dirs
7244 $filearrayold=dol_dir_list($dirold,"files",0,'','(\.meta|_preview.*\.png)$
',$sortfield,(strtolower($sortorder)=='desc
'?SORT_DESC:SORT_ASC),1);
7245 $filearray=array_merge($filearray, $filearrayold);
7248 completeFileArrayWithDatabaseInfo($filearray, $relativedir);
7250 if (count($filearray)) {
7251 if ($sortfield && $sortorder) {
7252 $filearray = dol_sort_array($filearray, $sortfield, $sortorder);
7255 foreach ($filearray as $key => $val) {
7257 $file = $val['name'];
7259 //if (! utf8_check($file)) $file=utf8_encode($file); // To be sure file is stored in UTF8 in memory
7261 //if (dol_is_file($dir.$file) && image_format_supported($file) >= 0)
7262 if (image_format_supported($file) >= 0) {
7265 $viewfilename = $file;
7267 if ($size == 1 || $size == 'small
') { // Format vignette
7268 // Find name of thumb file
7269 $photo_vignette = basename(getImageFileNameForSize($dir.$file, '_small
'));
7270 if (!dol_is_file($dirthumb.$photo_vignette)) $photo_vignette = '';
7272 // Get filesize of original file
7273 $imgarray = dol_getImageSize($dir.$photo);
7277 if ($nbphoto == 1) $return .= '<table
class=
"valigntop center centpercent" style=
"border: 0; padding: 2px; border-spacing: 2px; border-collapse: separate;">
';
7279 if ($nbphoto % $nbbyrow == 1) $return .= '<tr
class=
"center valignmiddle" style=
"border: 1px">
';
7280 $return .= '<td style=
"width: '.ceil(100 / $nbbyrow).'%" class=
"photo">
';
7281 } elseif ($nbbyrow < 0) $return .= '<div
class=
"inline-block">
';
7285 $relativefile = preg_replace('/^\
7289 if ($urladvanced) $return .=
'<a href="'.$urladvanced.
'">';
7290 else $return .=
'<a href="'.DOL_URL_ROOT.
'/viewimage.php?modulepart='.$modulepart.
'&entity='.$this->entity.
'&file='.urlencode($pdir.$photo).
'" class="aphoto" target="_blank">';
7295 $alt = $langs->transnoentitiesnoconv(
'File').
': '.$relativefile;
7296 $alt .=
' - '.$langs->transnoentitiesnoconv(
'Size').
': '.$imgarray[
'width'].
'x'.$imgarray[
'height'];
7297 if ($notitle) $alt =
'';
7299 if ($usesharelink) {
7300 if ($val[
'share']) {
7301 if (empty($maxHeight) || $photo_vignette && $imgarray[
'height'] > $maxHeight) {
7302 $return .=
'<!-- Show original file (thumb not yet available with shared links) -->';
7303 $return .=
'<img class="photo photowithmargin" height="'.$maxHeight.
'" src="'.DOL_URL_ROOT.
'/viewimage.php?hashp='.urlencode($val[
'share']).
'" title="'.
dol_escape_htmltag($alt).
'">';
7305 $return .=
'<!-- Show original file -->';
7306 $return .=
'<img class="photo photowithmargin" height="'.$maxHeight.
'" src="'.DOL_URL_ROOT.
'/viewimage.php?hashp='.urlencode($val[
'share']).
'" title="'.
dol_escape_htmltag($alt).
'">';
7309 $return .=
'<!-- Show nophoto file (because file is not shared) -->';
7310 $return .=
'<img class="photo photowithmargin" height="'.$maxHeight.
'" src="'.DOL_URL_ROOT.
'/public/theme/common/nophoto.png" title="'.
dol_escape_htmltag($alt).
'">';
7313 if (empty($maxHeight) || $photo_vignette && $imgarray[
'height'] > $maxHeight) {
7314 $return .=
'<!-- Show thumb -->';
7315 $return .=
'<img class="photo photowithmargin maxwidth150onsmartphone" height="'.$maxHeight.
'" src="'.DOL_URL_ROOT.
'/viewimage.php?modulepart='.$modulepart.
'&entity='.$this->entity.
'&file='.urlencode($pdirthumb.$photo_vignette).
'" title="'.
dol_escape_htmltag($alt).
'">';
7317 $return .=
'<!-- Show original file -->';
7318 $return .=
'<img class="photo photowithmargin" height="'.$maxHeight.
'" src="'.DOL_URL_ROOT.
'/viewimage.php?modulepart='.$modulepart.
'&entity='.$this->entity.
'&file='.urlencode($pdir.$photo).
'" title="'.
dol_escape_htmltag($alt).
'">';
7322 if (empty($nolink)) $return .=
'</a>';
7325 if ($showfilename) $return .=
'<br>'.$viewfilename;
7330 if ($photo_vignette && (
image_format_supported($photo) > 0) && ($this->imgWidth > $maxWidth || $this->imgHeight > $maxHeight))
7332 $return .=
'<a href="'.$_SERVER[
"PHP_SELF"].
'?id='.$this->
id.
'&action=addthumb&file='.urlencode($pdir.$viewfilename).
'">'.
img_picto($langs->trans(
'GenerateThumb'),
'refresh').
' </a>';
7335 if ($modulepart ==
'product' && ($user->rights->produit->creer || $user->rights->service->creer))
7338 $return .=
'<a href="'.DOL_URL_ROOT.
'/core/photos_resize.php?modulepart='.urlencode(
'produit|service').
'&id='.$this->
id.
'&file='.urlencode($pdir.$viewfilename).
'" title="'.
dol_escape_htmltag($langs->trans(
"Resize")).
'">'.
img_picto($langs->trans(
"Resize"),
'resize',
'').
'</a> ';
7341 $return .=
'<a href="'.$_SERVER[
"PHP_SELF"].
'?id='.$this->
id.
'&action=delete&token='.
newToken().
'&file='.urlencode($pdir.$viewfilename).
'">';
7350 if (($nbphoto % $nbbyrow) == 0) $return .=
'</tr>';
7351 } elseif ($nbbyrow < 0) $return .= '</div>';
7355 $return .=
'<img class="photo photowithmargin" src="'.DOL_URL_ROOT.
'/viewimage.php?modulepart='.$modulepart.
'&entity='.$this->entity.
'&file='.urlencode($pdir.$photo).
'">';
7357 if ($showfilename) $return .=
'<br>'.$viewfilename;
7361 if ($modulepart ==
'product' && ($user->rights->produit->creer || $user->rights->service->creer))
7364 $return .=
'<a href="'.DOL_URL_ROOT.
'/core/photos_resize.php?modulepart='.urlencode(
'produit|service').
'&id='.$this->
id.
'&file='.urlencode($pdir.$viewfilename).
'" title="'.
dol_escape_htmltag($langs->trans(
"Resize")).
'">'.
img_picto($langs->trans(
"Resize"),
'resize',
'').
'</a> ';
7367 $return .=
'<a href="'.$_SERVER[
"PHP_SELF"].
'?id='.$this->
id.
'&action=delete&token='.
newToken().
'&file='.urlencode($pdir.$viewfilename).
'">';
7374 if ($nbmax && $nbphoto >= $nbmax)
break;
7378 if ($size == 1 || $size ==
'small')
7383 while ($nbphoto % $nbbyrow)
7385 $return .=
'<td style="width: '.ceil(100 / $nbbyrow).
'%"> </td>';
7389 if ($nbphoto) $return .=
'</table>';
7394 $this->nbphoto = $nbphoto;
7408 if (is_array($info)) {
7409 if (isset($info[
'type']) && $info[
'type'] ==
'array')
return true;
7423 if (isset($info[
'type']) && ($info[
'type'] ==
'date' || $info[
'type'] ==
'datetime' || $info[
'type'] ==
'timestamp'))
return true;
7435 if (is_array($info)) {
7436 if (isset($info[
'type']) && ($info[
'type'] ==
'duration'))
return true;
7438 }
else return false;
7449 if (is_array($info)) {
7450 if (isset($info[
'type']) && ($info[
'type'] ==
'int' || preg_match(
'/^integer/i', $info[
'type'])))
return true;
7452 }
else return false;
7463 if (is_array($info)) {
7464 if (isset($info[
'type']) && (preg_match(
'/^(double|real|price)/i', $info[
'type'])))
return true;
7478 if (is_array($info)) {
7479 if (isset($info[
'type']) && $info[
'type'] ==
'text')
return true;
7493 if (is_array($info)) {
7494 if (isset($info[
'notnull']) && $info[
'notnull'] !=
'1')
return true;
7508 if (is_array($info)) {
7509 if (isset($info[
'notnull']) && $info[
'notnull'] ==
'-1')
return true;
7523 if (is_array($info)) {
7524 if (isset($info[
'index']) && $info[
'index'] ==
true)
return true;
7542 $queryarray = array();
7543 foreach ($this->fields as $field => $info)
7546 if ($this->isDate($info))
7548 if (empty($this->{$field})) {
7549 $queryarray[$field] = null;
7551 $queryarray[$field] = $this->
db->idate($this->{$field});
7553 } elseif ($this->isArray($info))
7555 if (!empty($this->{$field})) {
7556 if (!is_array($this->{$field})) {
7557 $this->{$field} = array($this->{$field});
7559 $queryarray[$field] = serialize($this->{$field});
7561 $queryarray[$field] = null;
7563 } elseif ($this->isDuration($info))
7566 if ((isset($this->{$field}) && $this->{$field} !=
'') || !empty($info[
'notnull'])) {
7567 if (!isset($this->{$field})) {
7568 $queryarray[$field] = 0;
7570 $queryarray[$field] = (int) $this->{$field};
7573 else $queryarray[$field] = null;
7574 } elseif ($this->isInt($info) || $this->isFloat($info))
7576 if ($field ==
'entity' && is_null($this->{$field})) $queryarray[$field] = $conf->entity;
7579 if ((isset($this->{$field}) && $this->{$field} !=
'') || !empty($info[
'notnull'])) {
7580 if (!isset($this->{$field})) {
7581 $queryarray[$field] = 0;
7582 } elseif ($this->isInt($info)) {
7583 $queryarray[$field] = (int) $this->{$field};
7584 } elseif ($this->isFloat($info)) {
7585 $queryarray[$field] = (double) $this->{$field};
7587 }
else $queryarray[$field] = null;
7590 $queryarray[$field] = $this->{$field};
7593 if ($info[
'type'] ==
'timestamp' && empty($queryarray[$field])) unset($queryarray[$field]);
7594 if (!empty($info[
'notnull']) && $info[
'notnull'] == -1 && empty($queryarray[$field])) $queryarray[$field] = null;
7610 foreach ($this->fields as $field => $info)
7612 if ($this->isDate($info)) {
7613 if (is_null($obj->{$field}) || $obj->{$field} ===
'' || $obj->{$field} ===
'0000-00-00 00:00:00' || $obj->{$field} ===
'1000-01-01 00:00:00') $this->{$field} =
'';
7614 else $this->{$field} = $db->jdate($obj->{$field});
7615 } elseif ($this->isArray($info))
7617 if (!empty($obj->{$field})) {
7618 $this->{$field} = @unserialize($obj->{$field});
7620 if ($this->{$field } ===
false) @unserialize(utf8_decode($obj->{$field}));
7622 $this->{$field} = array();
7624 } elseif ($this->isInt($info)) {
7625 if ($field ==
'rowid') $this->
id = (int) $obj->{$field};
7627 if ($this->isForcedToNullIfZero($info)) {
7628 if (empty($obj->{$field})) $this->{$field} = null;
7629 else $this->{$field} = (double) $obj->{$field};
7631 if (!is_null($obj->{$field}) || (isset($info[
'notnull']) && $info[
'notnull'] == 1)) {
7632 $this->{$field} = (int) $obj->{$field};
7634 $this->{$field} = null;
7638 } elseif ($this->isFloat($info)) {
7639 if ($this->isForcedToNullIfZero($info)) {
7640 if (empty($obj->{$field})) $this->{$field} = null;
7641 else $this->{$field} = (double) $obj->{$field};
7643 if (!is_null($obj->{$field}) || (isset($info[
'notnull']) && $info[
'notnull'] == 1)) {
7644 $this->{$field} = (double) $obj->{$field};
7646 $this->{$field} = null;
7650 $this->{$field} = $obj->{$field};
7655 if (!isset($this->fields[
'ref']) && isset($this->
id)) $this->ref = $this->
id;
7665 $keys = array_keys($this->fields);
7666 return implode(
',', $keys);
7676 protected function quote($value, $fieldsentry)
7678 if (is_null($value))
return 'NULL';
7679 elseif (preg_match(
'/^(int|double|real|price)/i', $fieldsentry[
'type']))
return $this->
db->escape(
"$value");
7680 elseif ($fieldsentry[
'type'] ==
'boolean') {
7681 if ($value)
return 'true';
7682 else return 'false';
7684 else return "'".$this->db->escape($value).
"'";
7698 dol_syslog(get_class($this).
"::createCommon create", LOG_DEBUG);
7704 $fieldvalues = $this->setSaveQuery();
7706 if (array_key_exists(
'date_creation', $fieldvalues) && empty($fieldvalues[
'date_creation'])) $fieldvalues[
'date_creation'] = $this->
db->idate($now);
7707 if (array_key_exists(
'fk_user_creat', $fieldvalues) && !($fieldvalues[
'fk_user_creat'] > 0)) $fieldvalues[
'fk_user_creat'] = $user->id;
7708 unset($fieldvalues[
'rowid']);
7709 if (array_key_exists(
'ref', $fieldvalues)) $fieldvalues[
'ref'] =
dol_string_nospecial($fieldvalues[
'ref']);
7713 foreach ($fieldvalues as $k => $v) {
7715 $value = $this->fields[$k];
7716 $values[$k] = $this->quote($v, $value);
7720 foreach ($keys as $key)
7723 if (preg_match(
'/^integer:/i', $this->fields[$key][
'type']) && $values[$key] ==
'-1') $values[$key] =
'';
7724 if (!empty($this->fields[$key][
'foreignkey']) && $values[$key] ==
'-1') $values[$key] =
'';
7726 if (isset($this->fields[$key][
'notnull']) && $this->fields[$key][
'notnull'] == 1 && (!isset($values[$key]) || $values[$key] ===
'NULL') && is_null($this->fields[$key][
'default']))
7729 $this->errors[] = $langs->trans(
"ErrorFieldRequired", $this->fields[$key][
'label']);
7733 if (isset($this->fields[$key][
'notnull']) && $this->fields[$key][
'notnull'] == 1 && (!isset($values[$key]) || $values[$key] ===
'NULL') && !is_null($this->fields[$key][
'default']))
7735 $values[$key] = $this->fields[$key][
'default'];
7739 if (preg_match(
'/^integer:/i', $this->fields[$key][
'type']) && empty($values[$key])) {
7740 if (isset($this->fields[$key][
'default'])) $values[$key] = $this->fields[$key][
'default'];
7741 else $values[$key] =
'null';
7743 if (!empty($this->fields[$key][
'foreignkey']) && empty($values[$key])) $values[$key] =
'null';
7746 if ($error)
return -1;
7752 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element;
7753 $sql .=
' ('.implode(
", ", $keys).
')';
7754 $sql .=
' VALUES ('.implode(
", ", $values).
')';
7756 $res = $this->
db->query($sql);
7757 if ($res ===
false) {
7759 $this->errors[] = $this->
db->lasterror();
7765 $this->
id = $this->
db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
7771 if (key_exists(
'ref', $this->fields) && $this->fields[
'ref'][
'notnull'] > 0 && !is_null($this->fields[
'ref'][
'default']) && $this->fields[
'ref'][
'default'] ==
'(PROV)')
7773 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET ref = '(PROV".$this->
id.
")' WHERE (ref = '(PROV)' OR ref = '') AND rowid = ".$this->id;
7774 $resqlupdate = $this->
db->query($sql);
7776 if ($resqlupdate ===
false)
7779 $this->errors[] = $this->
db->lasterror();
7781 $this->ref =
'(PROV'.$this->id.
')';
7789 $result = $this->insertExtraFields();
7790 if ($result < 0) $error++;
7794 if (!empty($this->table_element_line) && !empty($this->fk_element))
7796 $num = (is_array($this->lines) ? count($this->lines) : 0);
7797 for ($i = 0; $i < $num; $i++)
7799 $line = $this->lines[$i];
7801 $keyforparent = $this->fk_element;
7802 $line->$keyforparent = $this->id;
7806 if (!is_object($line)) $line = (
object) $line;
7808 $result = $line->create($user, 1);
7811 $this->error = $this->
db->lasterror();
7812 $this->
db->rollback();
7819 if (!$error && !$notrigger)
7822 $result = $this->call_trigger(strtoupper(get_class($this)).
'_CREATE', $user);
7823 if ($result < 0) { $error++; }
7829 $this->
db->rollback();
7832 $this->
db->commit();
7848 if (empty($id) && empty($ref) && empty($morewhere))
return -1;
7850 $fieldlist = $this->getFieldList();
7851 if (empty($fieldlist))
return 0;
7853 $sql =
'SELECT '.$fieldlist;
7854 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element;
7856 if (!empty($id)) $sql .=
' WHERE rowid = '.$id;
7857 elseif (!empty($ref)) $sql .=
" WHERE ref = ".$this->quote($ref, $this->fields[
'ref']);
7858 else $sql .=
' WHERE 1 = 1';
7859 if (empty($id) && isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql .=
' AND entity IN ('.getEntity($this->table_element).
')';
7860 if ($morewhere) $sql .= $morewhere;
7863 $res = $this->
db->query($sql);
7866 $obj = $this->
db->fetch_object($res);
7869 $this->setVarsFromFetchObj($obj);
7873 $this->fetch_optionals();
7880 $this->error = $this->
db->lasterror();
7881 $this->errors[] = $this->error;
7894 $objectlineclassname = get_class($this).
'Line';
7895 if (!class_exists($objectlineclassname))
7897 $this->error =
'Error, class '.$objectlineclassname.
' not found during call of fetchLinesCommon';
7901 $objectline =
new $objectlineclassname($this->
db);
7903 $sql =
'SELECT '.$objectline->getFieldList();
7904 $sql .=
' FROM '.MAIN_DB_PREFIX.$objectline->table_element;
7905 $sql .=
' WHERE fk_'.$this->element.
' = '.$this->id;
7906 if ($morewhere) $sql .= $morewhere;
7907 if (isset($objectline->fields[
'position'])) {
7908 $sql .= $this->
db->order(
'position',
'ASC');
7914 $num_rows = $this->
db->num_rows(
$resql);
7916 while ($i < $num_rows)
7918 $obj = $this->
db->fetch_object(
$resql);
7921 $newline =
new $objectlineclassname($this->
db);
7922 $newline->setVarsFromFetchObj($obj);
7924 $this->lines[] = $newline;
7931 $this->error = $this->
db->lasterror();
7932 $this->errors[] = $this->error;
7946 global $conf, $langs;
7947 dol_syslog(get_class($this).
"::updateCommon update", LOG_DEBUG);
7953 $fieldvalues = $this->setSaveQuery();
7955 if (array_key_exists(
'date_modification', $fieldvalues) && empty($fieldvalues[
'date_modification'])) $fieldvalues[
'date_modification'] = $this->
db->idate($now);
7956 if (array_key_exists(
'fk_user_modif', $fieldvalues) && !($fieldvalues[
'fk_user_modif'] > 0)) $fieldvalues[
'fk_user_modif'] = $user->id;
7957 unset($fieldvalues[
'rowid']);
7958 if (array_key_exists(
'ref', $fieldvalues)) $fieldvalues[
'ref'] =
dol_string_nospecial($fieldvalues[
'ref']);
7964 foreach ($fieldvalues as $k => $v) {
7966 $value = $this->fields[$k];
7967 $values[$k] = $this->quote($v, $value);
7968 $tmp[] = $k.
'='.$this->quote($v, $this->fields[$k]);
7972 foreach ($keys as $key)
7974 if (preg_match(
'/^integer:/i', $this->fields[$key][
'type']) && $values[$key] ==
'-1') $values[$key] =
'';
7975 if (!empty($this->fields[$key][
'foreignkey']) && $values[$key] ==
'-1') $values[$key] =
'';
7986 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element.
' SET '.implode(
', ', $tmp).
' WHERE rowid='.$this->id;
7991 $res = $this->
db->query($sql);
7995 $this->errors[] = $this->
db->lasterror();
8002 $result = $this->insertExtraFields();
8010 if (!$error && !$notrigger)
8013 $result = $this->call_trigger(strtoupper(get_class($this)).
'_MODIFY', $user);
8014 if ($result < 0) { $error++; }
8020 $this->
db->rollback();
8023 $this->
db->commit();
8038 dol_syslog(get_class($this).
"::deleteCommon delete", LOG_DEBUG);
8044 if ($forcechilddeletion)
8046 foreach ($this->childtables as $table)
8048 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.$table.
' WHERE '.$this->fk_element.
' = '.$this->id;
8052 $this->error = $this->
db->lasterror();
8053 $this->errors[] = $this->error;
8054 $this->
db->rollback();
8058 } elseif (!empty($this->fk_element) && !empty($this->childtables))
8060 $objectisused = $this->isObjectUsed($this->
id);
8061 if (!empty($objectisused))
8063 dol_syslog(get_class($this).
"::deleteCommon Can't delete record as it has some child", LOG_WARNING);
8064 $this->error =
'ErrorRecordHasChildren';
8065 $this->errors[] = $this->error;
8066 $this->
db->rollback();
8072 if (is_array($this->childtablesoncascade) && !empty($this->childtablesoncascade)) {
8073 foreach ($this->childtablesoncascade as $table)
8075 $deleteFromObject = explode(
':', $table);
8076 if (count($deleteFromObject) >= 2) {
8077 $className = str_replace(
'@',
'', $deleteFromObject[0]);
8078 $filePath = $deleteFromObject[1];
8079 $columnName = $deleteFromObject[2];
8081 $childObject =
new $className($this->
db);
8082 if (method_exists($childObject,
'deleteByParentField')) {
8083 $result = $childObject->deleteByParentField($this->
id, $columnName);
8086 $this->errors[] = $childObject->error;
8091 $this->errors[] =
"You defined a cascade delete on an object $childObject but there is no method deleteByParentField for it";
8096 $this->errors[] =
'Cannot include child class file '.$filePath;
8101 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.$table.
' WHERE '.$this->fk_element.
' = '.$this->id;
8106 $this->error = $this->
db->lasterror();
8107 $this->errors[] = $this->error;
8117 $result = $this->call_trigger(strtoupper(get_class($this)).
'_DELETE', $user);
8118 if ($result < 0) { $error++; }
8125 $res = $this->deleteEcmFiles(1);
8131 if (!$error && !empty($this->isextrafieldmanaged))
8133 $result = $this->deleteExtraFields();
8134 if ($result < 0) { $error++; }
8139 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.
' WHERE rowid='.$this->id;
8141 $res = $this->
db->query($sql);
8142 if ($res ===
false) {
8144 $this->errors[] = $this->
db->lasterror();
8150 $this->
db->rollback();
8153 $this->
db->commit();
8173 if (!empty($parentId) && !empty($parentField)) {
8176 $sql =
"SELECT rowid FROM ".MAIN_DB_PREFIX.$this->table_element;
8177 $sql .=
' WHERE '.$parentField.
' = '.(int) $parentId;
8181 $this->errors[] = $this->
db->lasterror();
8184 while ($obj = $this->
db->fetch_object(
$resql)) {
8185 $result = $this->fetch($obj->rowid);
8188 $this->errors[] = $this->error;
8190 if (get_class($this) ==
'Contact') {
8191 $result = $this->
delete();
8193 $result = $this->
delete($user);
8197 $this->errors[] = $this->error;
8205 if (empty($error)) {
8206 $this->
db->commit();
8209 $this->error = implode(
', ', $this->errors);
8210 $this->
db->rollback();
8232 $tmpforobjectclass = get_class($this);
8233 $tmpforobjectlineclass = ucfirst($tmpforobjectclass).
'Line';
8236 $result = $this->call_trigger(
'LINE'.strtoupper($tmpforobjectclass).
'_DELETE', $user);
8237 if ($result < 0)
return -1;
8242 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element_line;
8243 $sql .=
" WHERE rowid=".$idline;
8245 dol_syslog(get_class($this).
"::deleteLineCommon", LOG_DEBUG);
8249 $this->error =
"Error ".$this->db->lasterror();
8253 if (empty($error)) {
8255 $tmpobjectline =
new $tmpforobjectlineclass($this->
db);
8256 if (!isset($tmpobjectline->isextrafieldmanaged) || !empty($tmpobjectline->isextrafieldmanaged)) {
8257 $tmpobjectline->id = $idline;
8258 $result = $tmpobjectline->deleteExtraFields();
8262 $this->error =
"Error ".get_class($this).
"::deleteLineCommon deleteExtraFields error -4 ".$tmpobjectline->error;
8267 if (empty($error)) {
8268 $this->
db->commit();
8271 dol_syslog(get_class($this).
"::deleteLineCommon ERROR:".$this->error, LOG_ERR);
8272 $this->
db->rollback();
8293 $statusfield =
'status';
8294 if ($this->element ==
'don' || $this->element ==
'donation') $statusfield =
'fk_statut';
8296 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
8297 $sql .=
" SET ".$statusfield.
" = ".((int) $status);
8298 $sql .=
" WHERE rowid = ".$this->id;
8300 if ($this->
db->query($sql))
8304 $this->oldcopy = clone $this;
8307 if (!$error && !$notrigger) {
8309 $result = $this->call_trigger($triggercode, $user);
8310 if ($result < 0) $error++;
8314 $this->status = $status;
8315 $this->
db->commit();
8318 $this->
db->rollback();
8322 $this->error = $this->
db->error();
8323 $this->
db->rollback();
8340 $this->specimen = 1;
8342 'label' =>
'This is label',
8343 'ref' =>
'ABCD1234',
8344 'description' =>
'This is a description',
8346 'note_public' =>
'Public note',
8347 'note_private' =>
'Private note',
8348 'date_creation' => (
dol_now() - 3600 * 48),
8349 'date_modification' => (
dol_now() - 3600 * 24),
8350 'fk_user_creat' => $user->id,
8351 'fk_user_modif' => $user->id,
8354 foreach ($fields as $key => $value) {
8355 if (array_key_exists($key, $this->fields)) $this->{$key} = $value;
8369 require_once DOL_DOCUMENT_ROOT.
'/core/class/comment.class.php';
8372 $result = $comment->fetchAllFor($this->element, $this->
id);
8374 $this->errors = array_merge($this->errors, $comment->errors);
8377 $this->comments = $comment->comments;
8379 return count($this->comments);
8389 return count($this->comments);
8400 if (!is_array($parameters))
return;
8401 foreach ($parameters as $parameter) {
8402 if (isset($this->$parameter)) {
8403 $this->$parameter = trim($this->$parameter);
8422 require_once DOL_DOCUMENT_ROOT.
'/categories/class/categorie.class.php';
8426 $existing = $c->containing($this->
id, $type_categ,
'id');
8444 require_once DOL_DOCUMENT_ROOT.
'/categories/class/categorie.class.php';
8447 if (!is_array($categories)) {
8448 $categories = array($categories);
8453 $existing = $c->containing($this->
id, $type_categ,
'id');
8456 if (is_array($existing)) {
8457 $to_del = array_diff($existing, $categories);
8458 $to_add = array_diff($categories, $existing);
8461 $to_add = $categories;
8467 foreach ($to_del as $del) {
8468 if ($c->fetch($del) > 0) {
8469 $c->del_type($this, $type_categ);
8472 foreach ($to_add as $add) {
8473 if ($c->fetch($add) > 0)
8475 $result = $c->add_type($this, $type_categ);
8479 $this->error = $c->error;
8480 $this->errors = $c->errors;
8486 return $error ? -1 : 1;
8501 if (empty($type)) $type = $this->table_element;
8503 require_once DOL_DOCUMENT_ROOT.
'/categories/class/categorie.class.php';
8506 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"categorie_".(empty($categorystatic->MAP_CAT_TABLE[$type]) ? $type : $categorystatic->MAP_CAT_TABLE[$type]).
" (fk_categorie, fk_product)";
8507 $sql .=
" SELECT fk_categorie, $toId FROM ".MAIN_DB_PREFIX.
"categorie_".(empty($categorystatic->MAP_CAT_TABLE[$type]) ? $type : $categorystatic->MAP_CAT_TABLE[$type]);
8508 $sql .=
" WHERE fk_product = ".((int) $fromId);
8510 if (!$this->
db->query($sql))
8512 $this->error = $this->
db->lasterror();
8513 $this->
db->rollback();
8517 $this->
db->commit();
8535 switch ($this->element) {
8537 $element =
'propale';
8540 $element =
'produit';
8542 case 'order_supplier':
8543 $element =
'fournisseur/commande';
8545 case 'invoice_supplier':
8546 $element =
'fournisseur/facture/'.get_exdir($this->
id, 2, 0, 1, $this,
'invoice_supplier');
8549 $element =
'expedition/sending';
8552 $element = $this->element;
8556 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"ecm_files_extrafields WHERE fk_object IN (";
8557 $sql .=
" SELECT rowid FROM ".MAIN_DB_PREFIX.
"ecm_files WHERE filename LIKE '".$this->
db->escape($this->ref).
"%'";
8558 $sql .=
" AND filepath = '".$this->db->escape($element).
"/".$this->
db->escape($this->ref).
"' AND entity = ".$conf->entity;
8561 if (!$this->
db->query($sql)) {
8562 $this->error = $this->
db->lasterror();
8563 $this->
db->rollback();
8568 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"ecm_files";
8569 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->ref).
"%'";
8570 $sql .=
" AND filepath = '".$this->db->escape($element).
"/".$this->
db->escape($this->ref).
"' AND entity = ".$conf->entity;
8572 if (!$this->
db->query($sql)) {
8573 $this->error = $this->
db->lasterror();
8574 $this->
db->rollback();
8581 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.
"ecm_files_extrafields";
8582 $sql .=
" WHERE fk_object IN (SELECT rowid FROM ".MAIN_DB_PREFIX.
"ecm_files WHERE src_object_type = '".$this->
db->escape($this->table_element.(empty($this->module) ?
'' :
'@'.$this->module)).
"' AND src_object_id = ".$this->
id.
")";
8585 $this->error = $this->
db->lasterror();
8586 $this->
db->rollback();
8590 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.
"ecm_files";
8591 $sql .=
" WHERE src_object_type = '".$this->db->escape($this->table_element.(empty($this->module) ?
'' :
'@'.$this->module)).
"' AND src_object_id = ".$this->id;
8594 $this->error = $this->
db->lasterror();
8595 $this->
db->rollback();
8600 $this->
db->commit();
if(!function_exists('dol_getprefix')) dol_include_once($relpath, $classname= '')
Make an include_once using default root and alternate root if it fails.
getCategoriesCommon($type_categ)
Sets object to given categories.
deleteCommon(User $user, $notrigger=false, $forcechilddeletion=0)
Delete object in database.
setExtraParameters()
Set extra parameters.
getFullAddress($withcountry=0, $sep="\n", $withregion=0, $extralangcode= '')
Return full address of contact.
getKanbanView($option= '')
Return clicable link of object (with eventually picto)
getIdContact($source, $code, $status=0)
Return id of contacts for a source and a contact code.
static isExistingObject($element, $id, $ref= '', $ref_ext= '')
Check an object id/ref exists If you don't need/want to instantiate object and just need to know if o...
if(!empty($arrayfields['u.datec']['checked'])) print_liste_field_titre("DateCreationShort"u if(!empty($arrayfields['u.tms']['checked'])) print_liste_field_titre("DateModificationShort"u if(!empty($arrayfields['u.statut']['checked'])) print_liste_field_titre("Status"u statut
isFloat($info)
Function test if type is float.
if(!empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'] country if(!empty($arrayfields['typent.code']['checked'])) print_liste_field_titre($arrayfields['typent.code']['label'] typent code
isInt($info)
Function test if type is integer.
printObjectLines($action, $seller, $buyer, $selected=0, $dateSelector=0, $defaulttpldir= '/core/tpl')
Return HTML table for object lines TODO Move this into an output class file (htmlline.class.php) If lines are into a template, title must also be into a template But for the moment we don't know if it's possible as we keep a method available on overloaded objects.
dol_format_address($object, $withcountry=0, $sep="\n", $outputlangs= '', $mode=0, $extralangcode= '')
Return a formated address (part address/zip/town/state) according to country rules.
setUpperOrLowerCase()
Set to upper or ucwords/lower if needed.
fetchLinesCommon($morewhere= '')
Load object in memory from the database.
isText($info)
Function test if type is text.
updateRangOfLine($rowid, $rang)
Update position of line (rang)
</td >< tdcolspan="3">< spanclass="opacitymedium"></span ></td ></tr >< trclass="liste_total"> CREANCES DETTES< tdcolspan="3"class="right"></td >< tdcolspan="3"class="right"></td ></tr > CREANCES DETTES RECETTES DEPENSES trips CREANCES DETTES Y m expensereport p date_valid Y m expensereport pe datep $db idate($date_start)."' AND $column < p rowid
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
cloneCategories($fromId, $toId, $type= '')
Copy related categories to another object.
dol_now($mode= 'auto')
Return date for now.
line_order($renum=false, $rowidorder= 'ASC', $fk_parent_line=true)
Save a new position (field rang) for details lines.
setCategoriesCommon($categories, $type_categ)
Sets object to given categories.
delete_linked_contact($source= '', $code= '')
Delete all links between an object $this and all its contacts.
Class to manage Dolibarr users.
dol_strtoupper($string, $encoding="UTF-8")
Convert a string to upper.
setProject($projectid)
Link element with a project.
add_contact($fk_socpeople, $type_contact, $source= 'external', $notrigger=0)
Add a link between element $this->element and a contact.
swapContactStatus($rowid)
Update status of a contact linked to object.
isDate($info)
Function test if type is date.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
delete_resource($rowid, $element, $notrigger=0)
Delete a link to resource line.
quote($value, $fieldsentry)
Add quote to field value if necessary.
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.
getFullName($langs, $option=0, $nameorder=-1, $maxlen=0)
Return full name (civility+' '+name+' '+lastname)
isArray($info)
Function test if type is array.
$conf db name
Only used if Module[ID]Name translation string is not found.
canBeNull($info)
Function test if field can be null.
$conf db
API class for accounts.
image_format_supported($file, $acceptsvg=0)
Return if a filename is file name of a supported image format.
insertExtraFields($trigger= '', $userused=null)
Add/Update all extra fields values for the current object.
setVarsFromFetchObj(&$obj)
Function to load data from a SQL pointer into properties of current object $this. ...
getRangOfLine($rowid)
Get position of line (rang)
dol_string_nospecial($str, $newstr= '_', $badcharstoreplace= '')
Clean a string from all punctuation characters to use it as a ref or login.
fetchComments()
Load comments linked with current task.
Class to manage categories.
update_note($note, $suffix= '')
Update note of element.
line_max($fk_parent_line=0)
Get max value used for position of line (rang)
setBankAccount($fk_account, $notrigger=false, $userused=null)
Change the bank account.
load_previous_next_ref($filter, $fieldid, $nodbprefix=0)
Load properties id_previous and id_next by comparing $fieldid with $this->ref.
if(!empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'] s nom
deleteEcmFiles($mode=0)
Delete related files of object in database.
updateObjectLinked($sourceid=null, $sourcetype= '', $targetid=null, $targettype= '')
Update object linked of a current object.
showOptionals($extrafields, $mode= 'view', $params=null, $keysuffix= '', $keyprefix= '', $onetrtd=0)
Function to show lines of extrafields with output datas.
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt= '', $morecss= '', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
getFormatedSupplierRef($objref)
Return supplier ref for screen output.
getBannerAddress($htmlkey, $object)
Return full address for banner.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
getChildrenOfLine($id, $includealltree=0)
Get children of line.
getFormatedCustomerRef($objref)
Return customer ref for screen output.
setWarehouse($warehouse_id)
Change the warehouse.
add_element_resource($resource_id, $resource_type, $busy=0, $mandatory=0)
Add resources to the current object : add entry into llx_element_resources Need $this->element & $thi...
deleteExtraFields()
Delete all extra fields values for the current object.
updateCommon(User $user, $notrigger=false)
Update object into database.
getState($id, $withcode= '', $dbtouse=0, $withregion=0, $outputlangs= '', $entconv=1)
Return state translated from an id.
setShippingMethod($shipping_method_id, $notrigger=false, $userused=null)
Change the shipping method.
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
deleteObjectLinked($sourceid=null, $sourcetype= '', $targetid=null, $targettype= '', $rowid= '')
Delete all links between an object $this.
liste_contact($status=-1, $source= 'external', $list=0, $code= '')
Get array of all contacts for an object.
setDocModel($user, $modelpdf)
Set last model used by doc generator.
dol_ucwords($string, $encoding="UTF-8")
Convert first character of all the words of a string to upper.
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
setStatut($status, $elementId=null, $elementType= '', $trigkey= '')
Set status of an object.
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.
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
isForcedToNullIfZero($info)
Function test if field is forced to null if zero or empty.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
setStatusCommon($user, $status, $notrigger=0, $triggercode= '')
Set to a status.
getFieldList()
Function to concat keys of fields.
print $_SERVER["PHP_SELF"] n
Edit parameters.
dol_trunc($string, $size=40, $trunc= 'right', $stringencoding= 'UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '...' if string larger than length.
update_ref_ext($ref_ext)
Update external ref of element.
getNbComments()
Return nb comments already posted.
isIndex($info)
Function test if is indexed.
deleteByParentField($parentId=0, $parentField= '')
Delete all child object from a parent ID.
add_object_linked($origin=null, $origin_id=null)
Add objects linked in llx_element_element.
errorsToString()
Method to output saved errors.
update_price($exclspec=0, $roundingadjust= 'none', $nodatabaseupdate=0, $seller=null)
Update total_ht, total_ttc, total_vat, total_localtax1, total_localtax2 for an object (sum of lines)...
img_delete($titlealt= 'default', $other= 'class="pictodelete"', $morecss= '')
Show delete logo.
setSaveQuery()
Function to prepare a part of the query for insert.
isDuration($info)
Function test if type is duration.
if(!defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN'
Draft customers invoices.
getAdvancedPreviewUrl($modulepart, $relativepath, $alldata=0, $param= '')
Return URL we can use for advanced preview links.
delete_contact($rowid, $notrigger=0)
Delete a link to contact line.
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
getCountry($searchkey, $withcode= '', $dbtouse=0, $outputlangs= '', $entconv=1, $searchlabel= '')
Return country label, code or id from an id, code or label.
Parent class of all other business classes (invoices, contracts, proposals, orders, ...)
if(!empty($search_group)) natural_search(array("g.nom"g note
dol_strtolower($string, $encoding="UTF-8")
Convert a string to lower.
fetchCommon($id, $ref=null, $morewhere= '')
Load object in memory from the database.
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
trimParameters($parameters)
Trim object parameters.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $keepmoretags= '', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...
insertExtraLanguages($trigger= '', $userused=null)
Add/Update all extra fields values for the current object.