50require
'../main.inc.php';
60require_once DOL_DOCUMENT_ROOT.
'/core/class/canvas.class.php';
61require_once DOL_DOCUMENT_ROOT.
'/core/class/genericobject.class.php';
62require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formcompany.class.php';
63require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formfile.class.php';
64require_once DOL_DOCUMENT_ROOT.
'/core/lib/company.lib.php';
65require_once DOL_DOCUMENT_ROOT.
'/core/lib/product.lib.php';
66require_once DOL_DOCUMENT_ROOT.
'/core/modules/product/modules_product.class.php';
67require_once DOL_DOCUMENT_ROOT.
'/categories/class/categorie.class.php';
68require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
69require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
71 require_once DOL_DOCUMENT_ROOT.
'/comm/propal/class/propal.class.php';
74 require_once DOL_DOCUMENT_ROOT.
'/compta/facture/class/facture.class.php';
77 require_once DOL_DOCUMENT_ROOT.
'/commande/class/commande.class.php';
80 require_once DOL_DOCUMENT_ROOT.
'/core/lib/accounting.lib.php';
81 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formaccounting.class.php';
82 require_once DOL_DOCUMENT_ROOT.
'/accountancy/class/accountingaccount.class.php';
85 require_once DOL_DOCUMENT_ROOT.
'/bom/class/bom.class.php';
89 require_once DOL_DOCUMENT_ROOT.
'/workstation/class/workstation.class.php';
93$langs->loadLangs(array(
'products',
'other'));
95 $langs->load(
"stocks");
98 $langs->load(
"bills");
101 $langs->load(
"productbatch");
104$backtopageforcancel =
GETPOST(
'backtopageforcancel');
110$refalreadyexists = 0;
121$action = (
GETPOST(
'action',
'alpha') ?
GETPOST(
'action',
'alpha') :
'view');
122$cancel =
GETPOST(
'cancel',
'alpha');
123$backtopage =
GETPOST(
'backtopage',
'alpha');
124$dol_openinpopup =
GETPOST(
'dol_openinpopup',
'aZ09');
125$confirm =
GETPOST(
'confirm',
'alpha');
127$duration_value =
GETPOST(
'duration_value') ===
'' ? null :
GETPOSTINT(
'duration_value');
128$duration_unit =
GETPOST(
'duration_unit',
'alpha');
130$accountancy_code_sell =
GETPOST(
'accountancy_code_sell',
'alpha');
131$accountancy_code_sell_intra =
GETPOST(
'accountancy_code_sell_intra',
'alpha');
132$accountancy_code_sell_export =
GETPOST(
'accountancy_code_sell_export',
'alpha');
133$accountancy_code_buy =
GETPOST(
'accountancy_code_buy',
'alpha');
134$accountancy_code_buy_intra =
GETPOST(
'accountancy_code_buy_intra',
'alpha');
135$accountancy_code_buy_export =
GETPOST(
'accountancy_code_buy_export',
'alpha');
137$checkmandatory =
GETPOST(
'accountancy_code_buy_export',
'alpha');
141 $label_security_check =
'nohtml';
143 $label_security_check = !
getDolGlobalString(
'MAIN_SECURITY_ALLOW_UNSECURED_LABELS_WITH_HTML') ?
'alphanohtml' :
'restricthtml';
146if (!empty($user->socid)) {
147 $socid = $user->socid;
152if (substr(
$module, 0, 16) ==
'mod_codeproduct_' && substr(
$module, -3) ==
'php') {
157 $modCodeProduct =
new $module();
166$extrafields->fetch_name_optionals_label(
$object->table_element);
168if ($id > 0 || !empty($ref)) {
169 $result =
$object->fetch($id, (
string) $ref);
175 $upload_dir =
$conf->product->multidir_output[$entity].
'/'.
get_exdir(0, 0, 0, 0, $object,
'product').dol_sanitizeFileName(
$object->ref);
177 $upload_dir =
$conf->service->multidir_output[$entity].
'/'.
get_exdir(0, 0, 0, 0, $object,
'product').dol_sanitizeFileName(
$object->ref);
182 $upload_dirold =
$conf->product->multidir_output[$entity].
'/'.substr(substr(
"000".
$object->id, -2), 1, 1).
'/'.substr(substr(
"000".
$object->id, -2), 0, 1).
'/'.
$object->id.
"/photos";
184 $upload_dirold =
$conf->service->multidir_output[$entity].
'/'.substr(substr(
"000".
$object->id, -2), 1, 1).
'/'.substr(substr(
"000".
$object->id, -2), 0, 1).
'/'.
$object->id.
"/photos";
189$modulepart =
'product';
194if (!empty($canvas)) {
195 require_once DOL_DOCUMENT_ROOT.
'/core/class/canvas.class.php';
196 $objcanvas =
new Canvas($db, $action);
197 $objcanvas->getCanvas(
'product',
'card', $canvas);
201$fieldvalue = (!empty($id) ?
$id : (!empty($ref) ? $ref :
''));
202$fieldtype = (!empty($id) ?
'rowid' :
'ref');
205$hookmanager->initHooks(array(
'productcard',
'globalcard'));
208 if (
$object->type == $object::TYPE_PRODUCT) {
211 if (
$object->type == $object::TYPE_SERVICE) {
215 restrictedArea($user,
'produit|service', 0,
'product&product',
'',
'', $fieldtype);
222$permissiontoeditextra = $usercancreate;
223if (
GETPOST(
'attribute',
'aZ09') && isset($extrafields->attributes[
$object->table_element][
'perms'][
GETPOST(
'attribute',
'aZ09')])) {
225 $permissiontoeditextra =
dol_eval((
string) $extrafields->attributes[
$object->table_element][
'perms'][
GETPOST(
'attribute',
'aZ09')]);
238if (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && !$user->hasRight(
'barcode',
'creer_advance')) {
242$parameters = array(
'id' => $id,
'ref' => $ref,
'objcanvas' => $objcanvas);
243$reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
245 setEventMessages($hookmanager->error, $hookmanager->errors,
'errors');
248if (empty($reshook)) {
249 $backurlforlist = DOL_URL_ROOT.
'/product/list.php?type='.$type;
251 if (empty($backtopage) || ($cancel && empty($id))) {
252 if (empty($backtopage) || ($cancel && strpos($backtopage,
'__ID__'))) {
253 if (empty($id) && (($action !=
'add' && $action !=
'create') || $cancel)) {
254 $backtopage = $backurlforlist;
256 $backtopage = DOL_URL_ROOT.
'/product/card.php?id='.((!empty($id) &&
$id > 0) ? $id :
'__ID__');
262 if (!empty($backtopageforcancel)) {
263 header(
"Location: ".$backtopageforcancel);
265 } elseif (!empty($backtopage)) {
266 header(
"Location: ".$backtopage);
272 if ($action ==
'confirm_merge' && $confirm ==
'yes' && $user->hasRight(
'societe',
'creer')) {
274 $productOriginId =
GETPOSTINT(
'product_origin');
275 $productOrigin =
new Product($db);
277 if ($productOriginId <= 0) {
278 $langs->load(
'errors');
279 setEventMessages($langs->trans(
'ErrorProductIdIsMandatory', $langs->transnoentitiesnoconv(
'MergeOriginProduct')),
null,
'errors');
281 if (!$error && $productOrigin->fetch($productOriginId) < 1) {
282 setEventMessages($langs->trans(
'ErrorRecordNotFound'),
null,
'errors');
291 $listofproperties = array(
301 'accountancy_code_buy',
302 'accountancy_code_buy_intra',
303 'accountancy_code_buy_export',
304 'accountancy_code_sell',
305 'accountancy_code_sell_intra',
306 'accountancy_code_sell_export'
308 foreach ($listofproperties as $property) {
309 if (empty(
$object->$property)) {
310 $object->$property = $productOrigin->$property;
314 $listofproperties = array(
315 'note_public',
'note_private'
317 foreach ($listofproperties as $property) {
322 if (is_array($productOrigin->array_options)) {
323 foreach ($productOrigin->array_options as $key => $val) {
324 if (empty(
$object->array_options[$key])) {
325 $object->array_options[$key] = $val;
332 $custcats_ori = $static_cat->containing($productOrigin->id,
'product',
'id');
333 $custcats = $static_cat->containing(
$object->id,
'product',
'id');
334 $custcats = array_merge($custcats, $custcats_ori);
335 $object->setCategories($custcats);
338 if ($productOrigin->barcode ==
$object->barcode) {
339 dol_syslog(
"We clean customer and supplier code so we will be able to make the update of target");
340 $productOrigin->barcode =
'';
356 'ActionComm' =>
'/comm/action/class/actioncomm.class.php',
357 'Bom' =>
'/bom/class/bom.class.php',
360 'Commande' =>
'/commande/class/commande.class.php',
361 'CommandeFournisseur' =>
'/fourn/class/fournisseur.commande.class.php',
362 'Contrat' =>
'/contrat/class/contrat.class.php',
363 'Delivery' =>
'/delivery/class/delivery.class.php',
364 'Facture' =>
'/compta/facture/class/facture.class.php',
365 'FactureFournisseur' =>
'/fourn/class/fournisseur.facture.class.php',
366 'FactureRec' =>
'/compta/facture/class/facture-rec.class.php',
367 'FichinterRec' =>
'/fichinter/class/fichinterrec.class.php',
368 'ProductFournisseur' =>
'/fourn/class/fournisseur.product.class.php',
369 'Propal' =>
'/comm/propal/class/propal.class.php',
370 'Reception' =>
'/reception/class/reception.class.php',
371 'SupplierProposal' =>
'/supplier_proposal/class/supplier_proposal.class.php',
375 foreach ($objects as $object_name => $object_file) {
376 require_once DOL_DOCUMENT_ROOT.$object_file;
378 if (!$error && !$object_name::replaceProduct($db, $productOrigin->id,
$object->id)) {
380 setEventMessages($db->lasterror(),
null,
'errors');
388 $parameters = array(
'soc_origin' => $productOrigin->id,
'soc_dest' =>
$object->id);
389 $reshook = $hookmanager->executeHooks(
397 setEventMessages($hookmanager->error, $hookmanager->errors,
'errors');
406 'mergefromid' => $productOrigin->id,
410 $result =
$object->call_trigger(
'PRODUCT_MODIFY', $user);
423 if (!empty(
$conf->product->multidir_output[$productOrigin->entity ??
$conf->entity])) {
424 $srcdir =
$conf->product->multidir_output[$productOrigin->entity ??
$conf->entity].
"/".$productOrigin->ref;
429 foreach ($dirlist as $filetomove) {
430 $destfile = $destdir.
'/'.$filetomove[
'relativename'];
431 dol_move($filetomove[
'fullname'], $destfile,
'0', 0, 0, 1);
438 if ($productOrigin->delete($user) < 1) {
444 setEventMessages($langs->trans(
'ProductsMergeSuccess'),
null,
'mesgs');
447 $langs->load(
"errors");
448 setEventMessages($langs->trans(
'ErrorsProductsMerge'),
null,
'errors');
456 if ($action ==
'setfk_product_type' && $usercancreate) {
457 $result =
$object->setValueFrom(
'fk_product_type',
GETPOST(
'fk_product_type'),
'',
null,
'text',
'', $user,
'PRODUCT_MODIFY');
458 header(
"Location: ".$_SERVER[
'PHP_SELF'].
"?id=".
$object->id);
463 $upload_dir =
$conf->product->dir_output;
464 $permissiontoadd = $usercancreate;
465 include DOL_DOCUMENT_ROOT.
'/core/actions_builddoc.inc.php';
467 include DOL_DOCUMENT_ROOT.
'/core/actions_printing.inc.php';
470 if ($action ==
'setfk_barcode_type' && $usercancreate) {
471 $result =
$object->setValueFrom(
'fk_barcode_type',
GETPOST(
'fk_barcode_type'),
'',
null,
'text',
'', $user,
'PRODUCT_MODIFY');
472 header(
"Location: ".$_SERVER[
'PHP_SELF'].
"?id=".
$object->id);
477 if ($action ==
'setbarcode' && $usercancreate) {
481 $result =
$object->setValueFrom(
'barcode',
GETPOST(
'barcode'),
'',
null,
'text',
'', $user,
'PRODUCT_MODIFY');
482 header(
"Location: ".$_SERVER[
'PHP_SELF'].
"?id=".
$object->id);
485 $langs->load(
"errors");
487 $errors[] =
'ErrorBadBarCodeSyntax';
488 } elseif ($result == -2) {
489 $errors[] =
'ErrorBarCodeRequired';
490 } elseif ($result == -3) {
491 $errors[] =
'ErrorBarCodeAlreadyUsed';
493 $errors[] =
'FailedToValidateBarCode';
497 setEventMessages(
'', $errors,
'errors');
502 if ($action ==
'update_extras' && $permissiontoeditextra) {
506 $attribute_name =
GETPOST(
'attribute',
'aZ09');
509 $ret = $extrafields->setOptionalsFromPost(
null, $object, $attribute_name);
515 $result =
$object->updateExtraField($attribute_name,
'PRODUCT_MODIFY');
523 $action =
'edit_extras';
528 if ($action ==
'add' && $usercancreate) {
531 if (!
GETPOST(
'label', $label_security_check)) {
532 setEventMessages($langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'Label')),
null,
'errors');
538 setEventMessages($langs->trans(
'ErrorFieldRequired', $langs->transnoentities($refLabelKey)),
null,
'errors');
543 if (!empty($duration_value) && empty($duration_unit)) {
544 setEventMessages($langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'Unit')),
null,
'errors');
548 $stockable_product = (int) ($type == 0 || ($type == 1 &&
getDolGlobalInt(
'STOCK_SUPPORTS_SERVICES')));
550 setEventMessages($langs->trans(
'ErrorBatchesNeedStockManagement'),
null,
'errors');
562 $object->mandatory_period = empty(
GETPOST(
"mandatoryperiod",
'alpha')) ? 0 : 1;
563 if (
$object->price_base_type ==
'TTC') {
568 if (
$object->price_base_type ==
'TTC') {
574 $tva_tx_txt =
GETPOST(
'tva_tx',
'alpha');
578 $tva_tx = preg_replace(
'/[^0-9\.].*$/',
'', $tva_tx_txt);
579 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
582 $localtax1_type =
'0';
583 $localtax2_type =
'0';
586 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
588 $vatratecode = $reg[1];
590 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
591 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
592 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
593 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
594 $sql .=
" AND t.code = '".$db->escape($vatratecode).
"'";
595 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
596 $resql = $db->query($sql);
598 $obj = $db->fetch_object($resql);
599 $npr = $obj->recuperableonly;
600 $localtax1 = $obj->localtax1;
601 $localtax2 = $obj->localtax2;
602 $localtax1_type = $obj->localtax1_type;
603 $localtax2_type = $obj->localtax2_type;
607 $object->default_vat_code = $vatratecode;
610 $object->localtax1_tx = $localtax1;
611 $object->localtax2_tx = $localtax2;
612 $object->localtax1_type = $localtax1_type;
613 $object->localtax2_type = $localtax2_type;
626 $stdobject->element =
'product';
627 $stdobject->barcode_type =
GETPOSTINT(
'fk_barcode_type');
628 $result = $stdobject->fetchBarCode();
631 $mesg =
'Failed to get bar code type information ';
632 setEventMessages($mesg.$stdobject->error, $stdobject->errors,
'errors');
634 $object->barcode_type_code = $stdobject->barcode_type_code;
635 $object->barcode_type_coder = $stdobject->barcode_type_coder;
636 $object->barcode_type_label = $stdobject->barcode_type_label;
647 $object->duration_value = $duration_value;
648 $object->duration_unit = $duration_unit;
667 if ($finished >= 0) {
680 $object->stockable_product = $stockable_product;
682 $accountancy_code_sell =
GETPOST(
'accountancy_code_sell',
'alpha');
683 $accountancy_code_sell_intra =
GETPOST(
'accountancy_code_sell_intra',
'alpha');
684 $accountancy_code_sell_export =
GETPOST(
'accountancy_code_sell_export',
'alpha');
685 $accountancy_code_buy =
GETPOST(
'accountancy_code_buy',
'alpha');
686 $accountancy_code_buy_intra =
GETPOST(
'accountancy_code_buy_intra',
'alpha');
687 $accountancy_code_buy_export =
GETPOST(
'accountancy_code_buy_export',
'alpha');
689 if (empty($accountancy_code_sell) || $accountancy_code_sell ==
'-1') {
690 $object->accountancy_code_sell =
'';
692 $object->accountancy_code_sell = $accountancy_code_sell;
694 if (empty($accountancy_code_sell_intra) || $accountancy_code_sell_intra ==
'-1') {
695 $object->accountancy_code_sell_intra =
'';
697 $object->accountancy_code_sell_intra = $accountancy_code_sell_intra;
699 if (empty($accountancy_code_sell_export) || $accountancy_code_sell_export ==
'-1') {
700 $object->accountancy_code_sell_export =
'';
702 $object->accountancy_code_sell_export = $accountancy_code_sell_export;
704 if (empty($accountancy_code_buy) || $accountancy_code_buy ==
'-1') {
705 $object->accountancy_code_buy =
'';
707 $object->accountancy_code_buy = $accountancy_code_buy;
709 if (empty($accountancy_code_buy_intra) || $accountancy_code_buy_intra ==
'-1') {
710 $object->accountancy_code_buy_intra =
'';
712 $object->accountancy_code_buy_intra = $accountancy_code_buy_intra;
714 if (empty($accountancy_code_buy_export) || $accountancy_code_buy_export ==
'-1') {
715 $object->accountancy_code_buy_export =
'';
717 $object->accountancy_code_buy_export = $accountancy_code_buy_export;
723 for ($i = 2; $i <= $produit_multiprices_limit; $i++) {
726 $object->multiprices_base_type[
"$i"] =
GETPOST(
"multiprices_base_type_".$i);
728 $object->multiprices[
"$i"] = 0;
734 $ret = $extrafields->setOptionalsFromPost(
null, $object);
741 '@phan-var ModeleProductCode $modCodeProduct';
743 $ref = $modCodeProduct->getNextValue($object, $type);
752 $categories =
GETPOST(
'categories',
'array:int');
753 $object->setCategories($categories);
755 if (!empty($backtopage)) {
756 $backtopage = preg_replace(
'/__ID__/', (
string)
$object->id, $backtopage);
757 $backtopage = preg_replace(
'/--IDFORBACKTOPAGE--/', (
string)
$object->id, $backtopage);
758 if (preg_match(
'/\?/', $backtopage)) {
759 $backtopage .=
'&productid='.$object->id;
762 if (!empty($dol_openinpopup)) {
764 print
'<script nonce="'.getNonce().
'">';
765 print
"window.parent.location.href = '".dol_escape_js($backtopage).
"';";
769 header(
"Location: ".$backtopage);
772 header(
"Location: ".$_SERVER[
'PHP_SELF'].
"?id=".$id);
779 if (
$object->error ==
'ErrorProductAlreadyExists') {
781 $reshook = $hookmanager->executeHooks(
'onProductAlreadyExists', $parameters, $object, $action);
783 setEventMessages($hookmanager->error, $hookmanager->errors,
'errors');
788 setEventMessages($langs->trans(
$object->error),
null,
'errors');
791 setEventMessages($langs->trans(
$object->error),
null,
'errors');
800 if ($action ==
'update' && $usercancreate) {
801 if (
GETPOST(
'cancel',
'alpha')) {
838 $object->duration_value = $duration_value;
839 $object->duration_unit = $duration_unit;
857 if ($finished >= 0) {
863 $fk_default_bom =
GETPOSTINT(
'fk_default_bom');
864 if ($fk_default_bom >= 0) {
865 $object->fk_default_bom = $fk_default_bom;
873 $object->stockable_product = 1;
874 setEventMessages($langs->trans(
'ForceBatchesNeedStockManagement'),
null,
'warnings');
888 $stdobject->element =
'product';
889 $stdobject->barcode_type =
GETPOSTINT(
'fk_barcode_type');
890 $result = $stdobject->fetchBarCode();
893 $mesg =
'Failed to get bar code type information ';
894 setEventMessages($mesg.$stdobject->error, $stdobject->errors,
'errors');
896 $object->barcode_type_code = $stdobject->barcode_type_code;
897 $object->barcode_type_coder = $stdobject->barcode_type_coder;
898 $object->barcode_type_label = $stdobject->barcode_type_label;
900 $accountancy_code_sell =
GETPOST(
'accountancy_code_sell',
'alpha');
901 $accountancy_code_sell_intra =
GETPOST(
'accountancy_code_sell_intra',
'alpha');
902 $accountancy_code_sell_export =
GETPOST(
'accountancy_code_sell_export',
'alpha');
903 $accountancy_code_buy =
GETPOST(
'accountancy_code_buy',
'alpha');
904 $accountancy_code_buy_intra =
GETPOST(
'accountancy_code_buy_intra',
'alpha');
905 $accountancy_code_buy_export =
GETPOST(
'accountancy_code_buy_export',
'alpha');
906 $checkmandatory =
GETPOST(
'mandatoryperiod',
'alpha');
907 if (empty($accountancy_code_sell) || $accountancy_code_sell ==
'-1') {
908 $object->accountancy_code_sell =
'';
910 $object->accountancy_code_sell = $accountancy_code_sell;
912 if (empty($accountancy_code_sell_intra) || $accountancy_code_sell_intra ==
'-1') {
913 $object->accountancy_code_sell_intra =
'';
915 $object->accountancy_code_sell_intra = $accountancy_code_sell_intra;
917 if (empty($accountancy_code_sell_export) || $accountancy_code_sell_export ==
'-1') {
918 $object->accountancy_code_sell_export =
'';
920 $object->accountancy_code_sell_export = $accountancy_code_sell_export;
922 if (empty($accountancy_code_buy) || $accountancy_code_buy ==
'-1') {
923 $object->accountancy_code_buy =
'';
925 $object->accountancy_code_buy = $accountancy_code_buy;
927 if (empty($accountancy_code_buy_intra) || $accountancy_code_buy_intra ==
'-1') {
928 $object->accountancy_code_buy_intra =
'';
930 $object->accountancy_code_buy_intra = $accountancy_code_buy_intra;
932 if (empty($accountancy_code_buy_export) || $accountancy_code_buy_export ==
'-1') {
933 $object->accountancy_code_buy_export =
'';
935 $object->accountancy_code_buy_export = $accountancy_code_buy_export;
938 $object->mandatory_period = (!empty($checkmandatory)) ? 1 : 0 ;
943 $ret = $extrafields->setOptionalsFromPost(
null, $object,
'@GETPOSTISSET');
948 if (!$error &&
$object->check()) {
951 $categories =
GETPOST(
'categories',
'array:int');
952 $object->setCategories($categories);
959 setEventMessages($langs->trans(
$object->error),
null,
'errors');
967 setEventMessages($langs->trans(
"ErrorProductBadRefOrLabel"),
null,
'errors');
976 if ($action ==
'confirm_clone' && $confirm !=
'yes') {
979 if ($action ==
'confirm_clone' && $confirm ==
'yes' && $usercancreate) {
981 setEventMessages($langs->trans(
"NoCloneOptionsSpecified"),
null,
'errors');
990 unset($clone->date_creation);
991 $clone->ref =
GETPOST(
'clone_ref',
'alphanohtml');
993 $clone->status_buy = 0;
994 $clone->barcode = -1;
996 if ($clone->check()) {
999 $clone->context[
'createfromclone'] =
'createfromclone';
1000 $id = $clone->create($user);
1002 if (
GETPOST(
'clone_composition')) {
1003 $result = $clone->clone_associations(
$object->id, $id);
1005 setEventMessages($langs->trans(
'ErrorProductClone'),
null,
'errors');
1006 setEventMessages($clone->error, $clone->errors,
'errors');
1011 if (!$error &&
GETPOST(
'clone_categories')) {
1012 $result = $clone->cloneCategories(
$object->id, $id);
1014 setEventMessages($langs->trans(
'ErrorProductClone'),
null,
'errors');
1015 setEventMessages($clone->error, $clone->errors,
'errors');
1020 if (!$error &&
GETPOST(
'clone_prices')) {
1021 $result = $clone->clone_price(
$object->id, $id);
1023 setEventMessages($langs->trans(
'ErrorProductClone'),
null,
'errors');
1024 setEventMessages($clone->error, $clone->errors,
'errors');
1029 if (!$error &&
isModEnabled(
'bom') && $user->hasRight(
'bom',
'write')) {
1032 $bomstatic =
new BOM($db);
1033 $bomclone = $bomstatic->createFromClone($user,
$object->fk_default_bom);
1034 if ((
int) $bomclone < 0) {
1035 setEventMessages($langs->trans(
'ErrorProductClone').
' : '.$langs->trans(
'ErrorProductCloneBom'),
null,
'warnings');
1037 $defbomidac =
$object->fk_default_bom;
1038 $clone->fk_default_bom = $bomclone->id;
1039 $clone->update($id, $user);
1040 $bomclone->fk_product =
$id;
1041 $bomclone->label = $langs->trans(
'BOMofRef', $clone->ref);
1042 $bomclone->update($user);
1043 $bomclone->validate($user);
1046 if (
GETPOST(
'clone_otherboms')) {
1047 $bomstatic =
new BOM($db);
1048 $bomlist = $bomstatic->fetchAll(
"",
"", 0, 0,
'fk_product:=:'.(
int)
$object->id);
1049 if (is_array($bomlist)) {
1050 foreach ($bomlist as $bom2clone) {
1051 if ($bom2clone->id != $defbomidac) {
1052 $bomclone = $bomstatic->createFromClone($user, $bom2clone->id);
1053 if ((
int) $bomclone < 0) {
1054 setEventMessages($langs->trans(
'ErrorProductClone').
' : '.$langs->trans(
'ErrorProductCloneBom'),
null,
'warnings');
1056 $bomclone->fk_product =
$id;
1057 $bomclone->label = $langs->trans(
'BOMofRef', $clone->ref);
1058 $bomclone->update($user);
1059 $bomclone->validate($user);
1068 if ($clone->error ==
'ErrorProductAlreadyExists') {
1069 $refalreadyexists++;
1072 $mesg = $langs->trans(
"ErrorProductAlreadyExists", $clone->ref);
1073 $mesg .=
' <a href="' . $_SERVER[
"PHP_SELF"] .
'?ref=' . $clone->ref .
'">' . $langs->trans(
"ShowCardHere") .
'</a>.';
1074 setEventMessages($mesg,
null,
'errors');
1076 setEventMessages(empty($clone->error) ?
'' : $langs->trans($clone->error), $clone->errors,
'errors');
1081 unset($clone->context[
'createfromclone']);
1088 header(
"Location: " . $_SERVER[
"PHP_SELF"] .
"?id=" . $id);
1092 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"NewRefForClone")),
null,
'errors');
1102 if ($action ==
'confirm_delete' && $confirm !=
'yes') {
1105 if ($action ==
'confirm_delete' && $confirm ==
'yes' && $usercandelete) {
1107 $result =
$object->delete($user);
1110 header(
'Location: '.DOL_URL_ROOT.
'/product/list.php?type='.
$object->type.
'&delprod='.urlencode(
$object->ref));
1113 setEventMessages($langs->trans(
$object->error),
null,
'errors');
1121 if (
$object->id > 0 && $action ==
'addin') {
1123 $permissiontoaddline =
false;
1130 $propal =
new Propal($db);
1131 $result = $propal->fetch(
GETPOSTINT(
'propalid'));
1133 dol_print_error($db, $propal->error);
1136 $thirdpartyid = $propal->socid;
1137 $permissiontoaddline = $user->hasRight(
'propal',
'creer');
1140 $result = $commande->fetch(
GETPOSTINT(
'commandeid'));
1142 dol_print_error($db, $commande->error);
1145 $thirdpartyid = $commande->socid;
1146 $permissiontoaddline = $user->hasRight(
'commande',
'creer');
1149 $result = $facture->fetch(
GETPOSTINT(
'factureid'));
1151 dol_print_error($db, $facture->error);
1154 $thirdpartyid = $facture->socid;
1155 $permissiontoaddline = $user->hasRight(
'facture',
'creer');
1158 if ($thirdpartyid > 0) {
1160 $result = $soc->fetch($thirdpartyid);
1162 dol_print_error($db, $soc->error);
1170 if (empty($tva_tx)) {
1178 $price_base_type =
$object->price_base_type;
1182 $pu_ht =
$object->multiprices[$soc->price_level];
1183 $pu_ttc =
$object->multiprices_ttc[$soc->price_level];
1184 $price_base_type =
$object->multiprices_base_type[$soc->price_level];
1186 require_once DOL_DOCUMENT_ROOT.
'/product/class/productcustomerprice.class.php';
1190 $filter = array(
't.fk_product' => (
string)
$object->id,
't.fk_soc' => (
string) $soc->id);
1192 $result = $prodcustprice->fetchAll(
'',
'', 0, 0, $filter);
1194 if (count($prodcustprice->lines) > 0) {
1195 $date_now = (int) floor(
dol_now() / 86400) * 86400;
1196 foreach ($prodcustprice->lines as $k => $custprice_line) {
1197 if ($custprice_line->date_begin <= $date_now && (empty($custprice_line->date_end) || $date_now <= $custprice_line->date_end)) {
1198 $pu_ht =
price($custprice_line->price);
1199 $pu_ttc =
price($custprice_line->price_ttc);
1200 $price_base_type = $custprice_line->price_base_type;
1201 $tva_tx = $custprice_line->tva_tx;
1209 $tmpvat =
price2num(preg_replace(
'/\s*\(.*\)/',
'', $tva_tx));
1210 $tmpprodvat =
price2num(preg_replace(
'/\s*\(.*\)/',
'',
$object->tva_tx));
1214 if ($tmpvat != $tmpprodvat) {
1215 if ($price_base_type !=
'HT') {
1216 $pu_ht =
price2num($pu_ttc / (1 + ((
float) $tmpvat / 100)),
'MU');
1218 $pu_ttc =
price2num($pu_ht * (1 + ((
float) $tmpvat / 100)),
'MU');
1222 if (
GETPOSTINT(
'propalid') > 0 && $permissiontoaddline && is_object($propal)) {
1225 if (($result = $propal->defineBuyPrice($pu_ht, (
float)
price2num(
GETPOST(
'remise_percent'),
'', 2),
$object->id)) < 0) {
1226 dol_syslog($langs->trans(
'FailedToGetCostPrice'));
1227 setEventMessages($langs->trans(
'FailedToGetCostPrice'),
null,
'errors');
1229 $buyprice = $result;
1232 $result = $propal->addline(
1257 header(
"Location: ".DOL_URL_ROOT.
"/comm/propal/card.php?id=".$propal->id);
1261 setEventMessages($langs->trans(
"ErrorUnknown").
": $result",
null,
'errors');
1262 } elseif (
GETPOST(
'commandeid') > 0 && $permissiontoaddline && is_object($commande)) {
1265 if (($result = $commande->defineBuyPrice($pu_ht, (
float)
price2num(
GETPOST(
'remise_percent'),
'', 2),
$object->id)) < 0) {
1266 dol_syslog($langs->trans(
'FailedToGetCostPrice'));
1267 setEventMessages($langs->trans(
'FailedToGetCostPrice'),
null,
'errors');
1269 $buyprice = $result;
1272 $result = $commande->addline(
1299 header(
"Location: ".DOL_URL_ROOT.
"/commande/card.php?id=".urlencode((
string) ($commande->id)));
1303 setEventMessages($langs->trans(
"ErrorUnknown").
": $result",
null,
'errors');
1304 } elseif (
GETPOST(
'factureid') > 0 && $permissiontoaddline && is_object($facture)) {
1307 if (($result = $facture->defineBuyPrice($pu_ht, (
float)
price2num(
GETPOST(
'remise_percent'),
'', 2),
$object->id)) < 0) {
1308 dol_syslog($langs->trans(
'FailedToGetCostPrice'));
1309 setEventMessages($langs->trans(
'FailedToGetCostPrice'),
null,
'errors');
1311 $buyprice = $result;
1314 $result = $facture->addline(
1346 header(
"Location: ".DOL_URL_ROOT.
"/compta/facture/card.php?facid=".$facture->id);
1350 setEventMessages($langs->trans(
"ErrorUnknown").
": $result",
null,
'errors');
1354 setEventMessages($langs->trans(
"WarningSelectOneDocument"),
null,
'warnings');
1359 include DOL_DOCUMENT_ROOT.
'/core/actions_printing.inc.php';
1362 $triggersendname =
'PRODUCT_SENTBYMAIL';
1364 $autocopy =
'MAIN_MAIL_AUTOCOPY_PRODUCT_TO';
1365 $trackid =
'prod'.$object->id;
1366 include DOL_DOCUMENT_ROOT.
'/core/actions_sendmails.inc.php';
1375$form =
new Form($db);
1379$formaccounting =
null;
1383$sellOrEatByMandatoryList =
null;
1390 if ($disableSellBy) {
1391 unset($sellOrEatByMandatoryList[Product::SELL_OR_EAT_BY_MANDATORY_ID_SELL_BY]);
1392 unset($sellOrEatByMandatoryList[Product::SELL_OR_EAT_BY_MANDATORY_ID_SELL_AND_EAT]);
1394 if ($disableEatBy) {
1395 unset($sellOrEatByMandatoryList[Product::SELL_OR_EAT_BY_MANDATORY_ID_EAT_BY]);
1396 unset($sellOrEatByMandatoryList[Product::SELL_OR_EAT_BY_MANDATORY_ID_SELL_AND_EAT]);
1400$title = $langs->trans(
'ProductServiceCard');
1405 if ($action ==
'create') {
1406 $title = $langs->trans(
"NewProduct");
1408 $title = $langs->trans(
'Product').
" ".$shortlabel.
" - ".$langs->trans(
'Card');
1409 $help_url =
'EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos|DE:Modul_Produkte';
1413 if ($action ==
'create') {
1414 $title = $langs->trans(
"NewService");
1416 $title = $langs->trans(
'Service').
" ".$shortlabel.
" - ".$langs->trans(
'Card');
1417 $help_url =
'EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios|DE:Modul_Leistungen';
1421llxHeader(
'', $title, $help_url,
'', 0, 0,
'',
'',
'',
'mod-product page-card');
1425$modBarCodeProduct =
null;
1428 $dirbarcode = array_merge(array(
'/core/modules/barcode/'),
$conf->modules_parts[
'barcode']);
1429 foreach ($dirbarcode as $dirroot) {
1436 $modBarCodeProduct =
new $module();
1437 '@phan-var-force ModeleNumRefBarCode $modBarCodeProduct';
1441$canvasdisplayaction = $action;
1442if (in_array($canvasdisplayaction, array(
'merge',
'confirm_merge'))) {
1443 $canvasdisplayaction =
'view';
1446if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayaction)) {
1450 $objcanvas->assign_values($canvasdisplayaction,
$object->id,
$object->ref);
1451 $objcanvas->display_canvas($canvasdisplayaction);
1456 if ($action ==
'create' && $usercancreate) {
1458 require_once DOL_DOCUMENT_ROOT.
'/core/class/doleditor.class.php';
1460 if (!empty(
$conf->use_javascript_ajax)) {
1461 print
'<script type="text/javascript">';
1462 print
'$(document).ready(function () {
1463 $("#selectcountry_id").change(function() {
1464 console.log("selectcountry_id change");
1465 document.formprod.action.value="create";
1466 document.formprod.submit();
1469 print
'</script>'.
"\n";
1474 if (substr(
$module, 0, 16) ==
'mod_codeproduct_' && substr(
$module, -3) ==
'php') {
1479 $modCodeProduct =
new $module();
1485 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'" method="POST" name="formprod">';
1486 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1487 print
'<input type="hidden" name="action" value="add">';
1488 print
'<input type="hidden" name="type" value="'.$type.
'">'.
"\n";
1489 if (!empty($modCodeProduct->code_auto)) {
1490 print
'<input type="hidden" name="code_auto" value="1">';
1492 if (!empty($modBarCodeProduct->code_auto)) {
1493 print
'<input type="hidden" name="barcode_auto" value="1">';
1495 print
'<input type="hidden" name="backtopage" value="'.$backtopage.
'">';
1496 print
'<input type="hidden" name="dol_openinpopup" value="'.dol_escape_htmltag($dol_openinpopup).
'">';
1500 $title = $langs->trans(
"NewService");
1503 $title = $langs->trans(
"NewProduct");
1510 if (
$object->country_id > 0) {
1512 $object->country_code = $tmparray[
'code'];
1513 $object->country = $tmparray[
'label'];
1519 $parameters = array();
1521 $reshook = $hookmanager->executeHooks(
'tabContentCreateProduct', $parameters, $object, $action);
1522 if (empty($reshook)) {
1523 print
'<table class="border centpercent">';
1528 if (!empty($modCodeProduct->code_auto)) {
1530 $tmpcode = $modCodeProduct->getNextValue($object, $type);
1532 print
'<td class="titlefieldcreate fieldrequired">'.$langs->trans($refLabelKey).
'</td><td><input id="ref" name="ref" class="maxwidth200" maxlength="128" value="'.
dol_escape_htmltag(
GETPOSTISSET(
'ref') ?
GETPOST(
'ref',
'alphanohtml') : $tmpcode).
'">';
1533 if ($refalreadyexists) {
1534 print $langs->trans(
"RefAlreadyExists");
1540 print
'<tr><td class="fieldrequired">'.$langs->trans(
"Label").
'</td><td><input id="label" name="label" class="minwidth300 maxwidth400onsmartphone" maxlength="255" value="'.
dol_escape_htmltag(
GETPOST(
'label', $label_security_check)).
'"></td></tr>';
1543 print
'<tr><td class="fieldrequired">'.$langs->trans(
"Status").
' ('.$langs->trans(
"Sell").
')</td><td>';
1544 $statutarray = array(
'1' => $langs->trans(
"OnSell"),
'0' => $langs->trans(
"NotOnSell"));
1545 print $form->selectarray(
'statut', $statutarray,
GETPOST(
'statut'));
1549 print
'<tr><td class="fieldrequired">'.$langs->trans(
"Status").
' ('.$langs->trans(
"Buy").
')</td><td>';
1550 $statutarray = array(
'1' => $langs->trans(
"ProductStatusOnBuy"),
'0' => $langs->trans(
"ProductStatusNotOnBuy"));
1551 print $form->selectarray(
'statut_buy', $statutarray,
GETPOST(
'statut_buy'));
1556 print
'<tr><td>'.$langs->trans(
"ManageLotSerial").
'</td><td>';
1557 $statutarray = array(
'0' => $langs->trans(
"ProductStatusNotOnBatch"),
'1' => $langs->trans(
"ProductStatusOnBatch"),
'2' => $langs->trans(
"ProductStatusOnSerial"));
1558 print $form->selectarray(
'status_batch', $statutarray,
GETPOSTINT(
'status_batch'));
1562 if ($status_batch !==
'0') {
1563 $langs->load(
"admin");
1564 $tooltip = $langs->trans(
"GenericMaskCodes", $langs->transnoentities(
"Batch"), $langs->transnoentities(
"Batch"));
1565 $tooltip .= $langs->trans(
"GenericMaskCodes1");
1566 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes2");
1567 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes3");
1568 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes4a", $langs->transnoentities(
"Batch"), $langs->transnoentities(
"Batch"));
1569 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes5");
1574 print
'<tr><td id="mask_option">'.$langs->trans(
"ManageLotMask").
'</td>';
1577 print
'<td id="field_mask">';
1578 print $form->textwithpicto(
'<input type="text" class="flat minwidth175" name="batch_mask" id="batch_mask_input">', $tooltip, 1,
'help');
1579 print
'<script type="text/javascript">
1580 $(document).ready(function() {
1581 $("#field_mask, #mask_option").addClass("hideobject");
1582 $("#status_batch").on("change", function () {
1583 console.log("We change batch status");
1584 var optionSelected = $("option:selected", this);
1585 var valueSelected = this.value;
1586 $("#field_mask, #mask_option").addClass("hideobject");
1590 if (this.value == 1) {
1591 $("#field_mask, #mask_option").toggleClass("hideobject");
1592 $("#batch_mask_input").val("'.$inherited_mask_lot.
'");
1598 if (this.value == 2) {
1599 $("#field_mask, #mask_option").toggleClass("hideobject");
1600 $("#batch_mask_input").val("'.$inherited_mask_sn.
'");
1613 if (!empty($sellOrEatByMandatoryList)) {
1614 print
'<tr><td>'.$langs->trans(
'BatchSellOrEatByMandatoryList', $langs->transnoentities(
'SellByDate'), $langs->transnoentities(
'EatByDate')).
'</td><td>';
1615 print $form->selectarray(
'sell_or_eat_by_mandatory', $sellOrEatByMandatoryList,
GETPOSTINT(
'sell_or_eat_by_mandatory'));
1621 if (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && !$user->hasRight(
'barcode',
'lire_advance')) {
1626 print
'<tr><td>'.$langs->trans(
'BarcodeType').
'</td><td>';
1628 $fk_barcode_type =
GETPOST(
'fk_barcode_type') ?
GETPOST(
'fk_barcode_type') : 0;
1633 $fk_barcode_type = 0;
1636 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formbarcode.class.php';
1638 print $formbarcode->selectBarcodeType($fk_barcode_type,
'fk_barcode_type', 1);
1643 print
'<td'.((is_object($modBarCodeProduct) && $modBarCodeProduct->code_null) ?
'' :
' class="fieldrequired"').
'>'.$langs->trans(
"BarcodeValue").
'</td><td>';
1645 if (empty($tmpcode) && is_object($modBarCodeProduct) && !empty($modBarCodeProduct->code_auto)) {
1646 $tmpcode = $modBarCodeProduct->getNextValue($object, $fk_barcode_type);
1648 print img_picto(
'',
'barcode',
'class="pictofixedwidth"');
1649 print
'<input class="maxwidth150" type="text" name="barcode" value="'.dol_escape_htmltag($tmpcode).
'">';
1654 print
'<tr><td class="tdtop">'.$langs->trans(
"Description").
'</td><td>';
1655 $doleditor =
new DolEditor(
'desc',
GETPOST(
'desc',
'restricthtml'),
'', 160,
'dolibarr_details',
'',
false,
true,
getDolGlobalString(
'FCKEDITOR_ENABLE_DETAILS'), ROWS_4,
'90%');
1656 $doleditor->Create();
1661 print
'<tr><td>'.$langs->trans(
"PublicUrl").
'</td><td>';
1662 print img_picto(
'',
'globe',
'class="pictofixedwidth"');
1663 print
'<input type="text" name="url" class="quatrevingtpercent" value="'.GETPOST(
'url').
'">';
1669 print
'<tr><td>'.$langs->trans(
"DefaultWarehouse").
'</td><td>';
1670 print img_picto($langs->trans(
"DefaultWarehouse"),
'stock',
'class="pictofixedwidth"');
1671 print $formproduct->selectWarehouses(
GETPOSTINT(
'fk_default_warehouse'),
'fk_default_warehouse',
'warehouseopen', 1, 0, 0,
'', 0, 0, array(),
'minwidth300 widthcentpercentminusxx maxwidth500');
1672 print
' <a href="'.DOL_URL_ROOT.
'/product/stock/card.php?action=create&token='.
newToken().
'&backtopage='.urlencode($_SERVER[
'PHP_SELF'].
'?&action=create&type='.
GETPOSTINT(
'type')).
'">';
1673 print
'<span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans(
"AddWarehouse").
'"></span>';
1681 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"StockLimit"), $langs->trans(
"StockLimitDesc"), 1).
'</td><td>';
1682 print
'<input name="seuil_stock_alerte" class="maxwidth50" value="'.GETPOST(
'seuil_stock_alerte').
'">';
1687 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"DesiredStock"), $langs->trans(
"DesiredStockDesc"), 1).
'</td><td>';
1688 print
'<input name="desiredstock" class="maxwidth50" value="'.GETPOST(
'desiredstock').
'">';
1693 print
'<input name="seuil_stock_alerte" type="hidden" value="0">';
1694 print
'<input name="desiredstock" type="hidden" value="0">';
1698 if ($type == $object::TYPE_SERVICE &&
isModEnabled(
"workstation")) {
1700 print
'<tr><td>'.$langs->trans(
"DefaultWorkstation").
'</td><td>';
1701 print img_picto($langs->trans(
"DefaultWorkstation"),
'workstation',
'class="pictofixedwidth"');
1702 print $formproduct->selectWorkstations((
GETPOSTISSET(
'fk_default_workstation') ?
GETPOSTINT(
'fk_default_workstation') :
''),
'fk_default_workstation', 1);
1708 print
'<tr><td>'.$langs->trans(
"Duration").
'</td><td>';
1709 print img_picto(
'',
'clock',
'class="pictofixedwidth"');
1710 print
'<input name="duration_value" class="width50 valignmiddle" value="'.(GETPOSTISSET(
'duration_value') ?
GETPOST(
'duration_value') :
'').
'">';
1711 print $formproduct->selectMeasuringUnits(
"duration_unit",
"time", (
GETPOSTISSET(
'duration_unit') ?
GETPOST(
'duration_unit',
'alpha') :
'h'), 0, 1);
1714 if (
$object->duration_value > 0) {
1715 print
' ';
1717 print
'<input type="checkbox" class="marginleftonly valignmiddle" id="mandatoryperiod" name="mandatoryperiod"'.(GETPOSTISSET(
'mandatoryperiod') ?
' checked="checked"' :
'').
'>';
1718 print
'<label for="mandatoryperiod">';
1719 $htmltooltip = $langs->trans(
"mandatoryHelper");
1721 $htmltooltip .=
'<br>'.$langs->trans(
"mandatoryHelper2");
1723 print $form->textwithpicto($langs->trans(
"mandatoryperiod"), $htmltooltip, 1,
'info');
1732 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"NatureOfProductShort"), $langs->trans(
"NatureOfProductDesc")).
'</td><td>';
1733 print $formproduct->selectProductNature(
'finished', (
GETPOSTISSET(
'finished') ?
GETPOST(
'finished') : (string)
$object->finished));
1741 print
'<tr><td>'.$langs->trans(
"Weight").
'</td><td>';
1742 print img_picto(
'',
'fa-balance-scale',
'class="pictofixedwidth"');
1743 print
'<input name="weight" size="4" value="'.GETPOST(
'weight').
'">';
1744 print $formproduct->selectMeasuringUnits(
"weight_units",
"weight",
GETPOSTISSET(
'weight_units') ?
GETPOST(
'weight_units',
'alpha') : (
GETPOST(
'weight_units',
'alpha') ?:
getDolGlobalString(
'MAIN_WEIGHT_DEFAULT_UNIT', 0)), 0, 2);
1750 print
'<tr><td>'.$langs->trans(
"Length").
' x '.$langs->trans(
"Width").
' x '.$langs->trans(
"Height").
'</td><td>';
1751 print img_picto(
'',
'fa-ruler',
'class="pictofixedwidth"');
1752 print
'<input name="size" class="width50" value="'.GETPOST(
'size').
'"> x ';
1753 print
'<input name="sizewidth" class="width50" value="'.GETPOST(
'sizewidth').
'"> x ';
1754 print
'<input name="sizeheight" class="width50" value="'.GETPOST(
'sizeheight').
'">';
1755 print $formproduct->selectMeasuringUnits(
"size_units",
"size",
GETPOSTISSET(
'size_units') ?
GETPOST(
'size_units',
'alpha') : (
GETPOST(
'size_units',
'alpha') ?:
'0'), 0, 2);
1760 print
'<tr><td>'.$langs->trans(
"Surface").
'</td><td>';
1761 print
'<input name="surface" size="4" value="'.GETPOST(
'surface').
'">';
1762 print $formproduct->selectMeasuringUnits(
"surface_units",
"surface",
GETPOSTISSET(
'surface_units') ?
GETPOST(
'surface_units',
'alpha') : (
GETPOST(
'surface_units',
'alpha') ?:
'0'), 0, 2);
1767 print
'<tr><td>'.$langs->trans(
"Volume").
'</td><td>';
1768 print
'<input name="volume" size="4" value="'.GETPOST(
'volume').
'">';
1769 print $formproduct->selectMeasuringUnits(
"volume_units",
"volume",
GETPOSTISSET(
'volume_units') ?
GETPOST(
'volume_units',
'alpha') : (
GETPOST(
'volume_units',
'alpha') ?:
'0'), 0, 2);
1775 print
'<tr><td>'.$langs->trans(
"NetMeasure").
'</td><td>';
1776 print
'<input name="net_measure" size="4" value="'.GETPOST(
'net_measure').
'">';
1777 print $formproduct->selectMeasuringUnits(
"net_measure_units",
'',
GETPOSTISSET(
'net_measure_units') ?
GETPOST(
'net_measure_units',
'alpha') : (
GETPOST(
'net_measure_units',
'alpha') ?:
getDolGlobalString(
'MAIN_WEIGHT_DEFAULT_UNIT', 0)), 0, 0);
1784 print
'<tr><td>'.$langs->trans(
'DefaultUnitToShow').
'</td>';
1792 print
'<tr><td class="wordbreak">'.$form->textwithpicto($langs->trans(
"CustomsCode"), $langs->trans(
"CustomsCodeHelp")).
'</td><td><input name="customcode" class="maxwidth100onsmartphone" value="'.
GETPOST(
'customcode').
'"></td></tr>';
1795 print
'<tr><td>'.$langs->trans(
"CountryOrigin").
'</td>';
1797 print img_picto(
'',
'globe-americas',
'class="pictofixedwidth"');
1798 print $form->select_country((
GETPOSTISSET(
'country_id') ?
GETPOST(
'country_id') :
$object->country_id),
'country_id',
'', 0,
'minwidth300 widthcentpercentminusx maxwidth500');
1800 print
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1808 print
'<td>'.$form->editfieldkey(
'RegionStateOrigin',
'state_id',
'', $object, 0).
'</td><td>';
1810 print
'<td>'.$form->editfieldkey(
'StateOrigin',
'state_id',
'', $object, 0).
'</td><td>';
1813 print img_picto(
'',
'state',
'class="pictofixedwidth"');
1814 print $formcompany->select_state(
$object->state_id,
$object->country_code);
1821 print
'<tr><td>'.$langs->trans(
"LifeTime").
'</td><td><input name="lifetime" class="maxwidth50" value="'.
GETPOST(
'lifetime').
'"></td></tr>';
1822 print
'<tr><td>'.$langs->trans(
"QCFrequency").
'</td><td><input name="qc_frequency" class="maxwidth50" value="'.
GETPOST(
'qc_frequency').
'"></td></tr>';
1826 $parameters = array(
'colspan' =>
' colspan="2"',
'cols' => 2);
1827 $reshook = $hookmanager->executeHooks(
'formObjectOptions', $parameters, $object, $action);
1828 print $hookmanager->resPrint;
1829 if (empty($reshook)) {
1830 print
$object->showOptionals($extrafields,
'create', $parameters);
1834 print
'<tr><td class="tdtop">'.$langs->trans(
"NoteNotVisibleOnBill").
'</td><td>';
1837 $doleditor =
new DolEditor(
'note_private',
GETPOST(
'note_private',
'restricthtml'),
'', 140,
'dolibarr_details',
'',
false,
true,
getDolGlobalString(
'FCKEDITOR_ENABLE_NOTE_PRIVATE'), ROWS_8,
'90%');
1838 $doleditor->Create();
1844 print
'<tr><td>'.$langs->trans(
"Categories").
'</td><td>';
1845 print $form->selectCategories(Categorie::TYPE_PRODUCT,
'categories', $object);
1857 print
'<table class="border centpercent">';
1859 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"VATRate").
'</td><td>';
1861 print $form->load_tva(
"tva_tx", $defaultva,
$mysoc,
$mysoc, 0, 0,
'',
false, 1);
1869 print
'<table class="border centpercent">';
1872 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"SellingPrice").
'</td>';
1873 print
'<td><input name="price" class="maxwidth50" value="'.(GETPOSTISSET(
'price') ?
GETPOST(
'price') :
$object->
price).
'">';
1874 print $form->selectPriceBaseType(
getDolGlobalString(
'PRODUCT_PRICE_BASE_TYPE'),
"price_base_type");
1879 print
'<tr><td>'.$langs->trans(
"MinPrice").
'</td>';
1880 print
'<td><input name="price_min" class="maxwidth50" value="'.(GETPOSTISSET(
'price_min') ?
GETPOST(
'price_min') :
$object->price_min).
'">';
1884 print
'<tr><td>'.$langs->trans(
"VATRate").
'</td><td>';
1886 print $form->load_tva(
"tva_tx", $defaultva,
$mysoc,
$mysoc, 0, 0,
'',
false, 1);
1897 print
'<!-- accountancy codes -->'.
"\n";
1898 print
'<table class="border centpercent">';
1901 if (
isModEnabled(
'accounting') && is_object($formaccounting)) {
1904 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellCode").
'</td>';
1911 print $formaccounting->select_account($accountancy_code_sell,
'accountancy_code_sell', 1, array(), 1, 1,
'minwidth150 maxwidth300',
'1');
1916 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellIntraCode").
'</td>';
1919 $accountancy_code_sell_intra = (
GETPOSTISSET(
'accountancy_code_sell_intra') ?
GETPOST(
'accountancy_code_sell_intra',
'alpha') :
getDolGlobalString(
"ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT"));
1921 $accountancy_code_sell_intra = (
GETPOSTISSET(
'accountancy_code_sell_intra') ?
GETPOST(
'accountancy_code_sell_intra',
'alpha') :
getDolGlobalString(
"ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT"));
1923 print $formaccounting->select_account($accountancy_code_sell_intra,
'accountancy_code_sell_intra', 1, array(), 1, 1,
'minwidth150 maxwidth300',
'1');
1928 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellExportCode").
'</td>';
1931 $accountancy_code_sell_export = (
GETPOST(
'accountancy_code_sell_export') ?
GETPOST(
'accountancy_code_sell_export',
'alpha') :
getDolGlobalString(
"ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT"));
1933 $accountancy_code_sell_export = (
GETPOST(
'accountancy_code_sell_export') ?
GETPOST(
'accountancy_code_sell_export',
'alpha') :
getDolGlobalString(
"ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT"));
1935 print $formaccounting->select_account($accountancy_code_sell_export,
'accountancy_code_sell_export', 1, array(), 1, 1,
'minwidth150 maxwidth300',
'1');
1939 print
'<tr><td>'.$langs->trans(
"ProductAccountancyBuyCode").
'</td>';
1942 $accountancy_code_buy = (
GETPOST(
'accountancy_code_buy',
'alpha') ? (
GETPOST(
'accountancy_code_buy',
'alpha')) :
getDolGlobalString(
"ACCOUNTING_PRODUCT_BUY_ACCOUNT"));
1944 $accountancy_code_buy = (
GETPOST(
'accountancy_code_buy',
'alpha') ? (
GETPOST(
'accountancy_code_buy',
'alpha')) :
getDolGlobalString(
"ACCOUNTING_SERVICE_BUY_ACCOUNT"));
1946 print $formaccounting->select_account($accountancy_code_buy,
'accountancy_code_buy', 1, array(), 1, 1,
'minwidth150 maxwidth300',
'1');
1951 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyIntraCode").
'</td>';
1954 $accountancy_code_buy_intra = (
GETPOSTISSET(
'accountancy_code_buy_intra') ?
GETPOST(
'accountancy_code_buy_intra',
'alpha') :
getDolGlobalString(
"ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT"));
1956 $accountancy_code_buy_intra = (
GETPOSTISSET(
'accountancy_code_buy_intra') ?
GETPOST(
'accountancy_code_buy_intra',
'alpha') :
getDolGlobalString(
"ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT"));
1958 print $formaccounting->select_account($accountancy_code_buy_intra,
'accountancy_code_buy_intra', 1, array(), 1, 1,
'minwidth150 maxwidth300',
'1');
1963 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyExportCode").
'</td>';
1966 $accountancy_code_buy_export = (
GETPOST(
'accountancy_code_buy_export') ?
GETPOST(
'accountancy_code_buy_export',
'alpha') :
getDolGlobalString(
"ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT"));
1968 $accountancy_code_buy_export = (
GETPOST(
'accountancy_code_buy_export') ?
GETPOST(
'accountancy_code_buy_export',
'alpha') :
getDolGlobalString(
"ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT"));
1970 print $formaccounting->select_account($accountancy_code_buy_export,
'accountancy_code_buy_export', 1, array(), 1, 1,
'minwidth150 maxwidth300',
'1');
1973 if (!empty($accountancy_code_sell)) {
1974 $object->accountancy_code_sell = $accountancy_code_sell;
1976 if (!empty($accountancy_code_sell_intra)) {
1977 $object->accountancy_code_sell_intra = $accountancy_code_sell_intra;
1979 if (!empty($accountancy_code_sell_export)) {
1980 $object->accountancy_code_sell_export = $accountancy_code_sell_export;
1982 if (!empty($accountancy_code_buy)) {
1983 $object->accountancy_code_buy = $accountancy_code_buy;
1985 if (!empty($accountancy_code_buy_intra)) {
1986 $object->accountancy_code_buy_intra = $accountancy_code_buy_intra;
1988 if (!empty($accountancy_code_buy_export)) {
1989 $object->accountancy_code_buy_export = $accountancy_code_buy_export;
1993 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellCode").
'</td>';
1994 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_sell" value="'.$object->accountancy_code_sell.
'">';
1999 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellIntraCode").
'</td>';
2000 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_sell_intra" value="'.$object->accountancy_code_sell_intra.
'">';
2005 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellExportCode").
'</td>';
2006 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_sell_export" value="'.$object->accountancy_code_sell_export.
'">';
2010 print
'<tr><td>'.$langs->trans(
"ProductAccountancyBuyCode").
'</td>';
2011 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_buy" value="'.$object->accountancy_code_buy.
'">';
2016 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyIntraCode").
'</td>';
2017 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_buy_intra" value="'.$object->accountancy_code_buy_intra.
'">';
2022 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyExportCode").
'</td>';
2023 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_buy_export" value="'.$object->accountancy_code_buy_export.
'">';
2032 print $form->buttonsSaveCancel(
"Create",
"Cancel", array(),
false,
'', $dol_openinpopup);
2036 $iskit =
$object->hasFatherOrChild(1);
2039 if ($action ==
'edit' && $usercancreate) {
2041 require_once DOL_DOCUMENT_ROOT.
'/core/class/doleditor.class.php';
2043 if (!empty(
$conf->use_javascript_ajax)) {
2044 print
'<script type="text/javascript">';
2045 print
'$(document).ready(function () {
2046 $("#selectcountry_id").change(function () {
2047 document.formprod.action.value="edit";
2048 document.formprod.submit();
2051 print
'</script>'.
"\n";
2058 $object->country_code = $tmparray[
'code'];
2059 $object->country = $tmparray[
'label'];
2062 $type = $langs->trans(
'Product');
2064 $type = $langs->trans(
'Service');
2069 print
'<form action="'.$_SERVER[
'PHP_SELF'].
'?id='.
$object->id.
'" method="POST" name="formprod">'.
"\n";
2070 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2071 print
'<input type="hidden" name="action" value="update">';
2072 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
2073 print
'<input type="hidden" name="canvas" value="'.$object->canvas.
'">';
2076 $titre = $langs->trans(
"CardProduct".
$object->type);
2078 print
dol_get_fiche_head($head,
'card', $titre, 0, $picto, 0,
'',
'', 0,
'', 0);
2081 $parameters = array();
2083 $reshook = $hookmanager->executeHooks(
'tabContentEditProduct', $parameters, $object, $action);
2085 if (empty($reshook)) {
2086 print
'<table class="border allwidth">';
2090 print
'<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans(
"Ref").
'</td><td colspan="3"><input name="ref" class="maxwidth200" maxlength="128" value="'.
dol_escape_htmltag(
GETPOSTISSET(
'ref') ?
GETPOST(
'ref') :
$object->
ref).
'"></td></tr>';
2092 print
'<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans(
"Ref").
'</td><td colspan="3"><input name="ref" class="maxwidth200" maxlength="128" value="'.
dol_escape_htmltag(
$object->ref).
'" readonly="true"></td></tr>';
2096 print
'<tr><td class="fieldrequired">'.$langs->trans(
"Label").
'</td><td colspan="3"><input name="label" class="minwidth300 maxwidth400onsmartphone" maxlength="255" value="'.
dol_escape_htmltag(
GETPOSTISSET(
'label') ?
GETPOST(
'label') :
$object->label).
'"></td></tr>';
2099 print
'<tr><td class="fieldrequired">'.$langs->trans(
"Status").
' ('.$langs->trans(
"Sell").
')</td><td colspan="3">';
2100 print
'<select class="flat" name="statut">';
2102 print
'<option value="1" selected>'.$langs->trans(
"OnSell").
'</option>';
2103 print
'<option value="0">'.$langs->trans(
"NotOnSell").
'</option>';
2105 print
'<option value="1">'.$langs->trans(
"OnSell").
'</option>';
2106 print
'<option value="0" selected>'.$langs->trans(
"NotOnSell").
'</option>';
2112 print
'<tr><td class="fieldrequired">'.$langs->trans(
"Status").
' ('.$langs->trans(
"Buy").
')</td><td colspan="3">';
2113 print
'<select class="flat" name="statut_buy">';
2115 print
'<option value="1" selected>'.$langs->trans(
"ProductStatusOnBuy").
'</option>';
2116 print
'<option value="0">'.$langs->trans(
"ProductStatusNotOnBuy").
'</option>';
2118 print
'<option value="1">'.$langs->trans(
"ProductStatusOnBuy").
'</option>';
2119 print
'<option value="0" selected>'.$langs->trans(
"ProductStatusNotOnBuy").
'</option>';
2127 print
'<tr><td>'.$langs->trans(
"ManageLotSerial").
'</td><td>';
2128 $statutarray = array(
'0' => $langs->trans(
"ProductStatusNotOnBatch"),
'1' => $langs->trans(
"ProductStatusOnBatch"),
'2' => $langs->trans(
"ProductStatusOnSerial"));
2132 print
'<span id="statusBatchWarning" class="warning" style="display: none;">';
2133 print img_warning().
' '.$langs->trans(
"WarningConvertFromBatchToSerial").
'</span>';
2135 print
'<span id="statusBatchMouvToGlobal" class="warning" style="display: none;">';
2136 print img_warning().
' '.$langs->trans(
"WarningTransferBatchStockMouvToGlobal").
'</span>';
2140 print
'<script type="text/javascript">
2141 $(document).ready(function() {
2142 console.log($("#statusBatchWarning"))
2143 $("#status_batch").on("change", function() {
2144 if ($("#status_batch")[0].value == 0) {
2145 $("#statusBatchMouvToGlobal").show()
2147 $("#statusBatchMouvToGlobal").hide()
2153 if (
$object->status_batch == 1) {
2154 print
'<script type="text/javascript">
2155 $(document).ready(function() {
2156 console.log($("#statusBatchWarning"))
2157 $("#status_batch").on("change", function() {
2158 if ($("#status_batch")[0].value == 2) {
2159 $("#statusBatchWarning").show()
2161 $("#statusBatchWarning").hide()
2169 if (!empty(
$object->status_batch) || !empty(
$conf->use_javascript_ajax)) {
2170 $langs->load(
"admin");
2171 $tooltip = $langs->trans(
"GenericMaskCodes", $langs->transnoentities(
"Batch"), $langs->transnoentities(
"Batch"));
2172 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes2");
2173 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes3");
2174 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes4a", $langs->transnoentities(
"Batch"), $langs->transnoentities(
"Batch"));
2175 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes5");
2178 print
'<tr><td id="mask_option">'.$langs->trans(
"ManageLotMask").
'</td>';
2188 print
'<td id="field_mask">';
2189 print $form->textwithpicto(
'<input type="text" class="flat minwidth175" name="batch_mask" id="batch_mask_input" value="'.$mask.
'">', $tooltip, 1,
'help');
2191 if (!empty(
$conf->use_javascript_ajax)) {
2192 print
'<script type="text/javascript">
2193 $(document).ready(function() {
2194 $("#field_mask").parent().addClass("hideobject");
2195 var preselect = document.getElementById("status_batch");';
2197 print
'if (preselect.value == "2") {
2198 $("#field_mask").parent().removeClass("hideobject");
2202 print
'if (preselect.value == "1") {
2203 $("#field_mask").parent().removeClass("hideobject");
2206 print
'$("#status_batch").on("change", function () {
2207 var optionSelected = $("option:selected", this);
2208 var valueSelected = this.value;
2209 $("#field_mask").parent().addClass("hideobject");
2213 if (this.value == 1) {
2214 $("#field_mask").parent().removeClass("hideobject");
2215 $("#batch_mask_input").val("'.$inherited_mask_lot.
'");
2221 if (this.value == 2) {
2222 $("#field_mask").parent().removeClass("hideobject");
2223 $("#batch_mask_input").val("'.$inherited_mask_sn.
'");
2237 if (!empty($sellOrEatByMandatoryList)) {
2239 $sellOrEatByMandatorySelectedId =
GETPOSTINT(
'sell_or_eat_by_mandatory');
2241 $sellOrEatByMandatorySelectedId =
$object->sell_or_eat_by_mandatory;
2243 print
'<tr><td>'.$langs->trans(
'BatchSellOrEatByMandatoryList', $langs->transnoentities(
'SellByDate'), $langs->transnoentities(
'EatByDate')).
'</td><td>';
2244 print $form->selectarray(
'sell_or_eat_by_mandatory', $sellOrEatByMandatoryList, $sellOrEatByMandatorySelectedId);
2251 if (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && !$user->hasRight(
'barcode',
'lire_advance')) {
2256 print
'<tr><td>'.$langs->trans(
'BarcodeType').
'</td><td>';
2258 $fk_barcode_type =
GETPOST(
'fk_barcode_type');
2260 $fk_barcode_type =
$object->barcode_type;
2265 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formbarcode.class.php';
2267 print $formbarcode->selectBarcodeType($fk_barcode_type,
'fk_barcode_type', 1);
2269 print
'<tr><td>'.$langs->trans(
"BarcodeValue").
'</td><td>';
2271 if (empty($tmpcode) && !empty($modBarCodeProduct->code_auto)) {
2272 $tmpcode = $modBarCodeProduct->getNextValue($object, $fk_barcode_type);
2274 print
'<input class="maxwidth150 maxwidthonsmartphone" type="text" name="barcode" value="'.dol_escape_htmltag($tmpcode).
'">';
2279 print
'<tr><td class="tdtop">'.$langs->trans(
"Description").
'</td><td>';
2282 $doleditor =
new DolEditor(
'desc',
GETPOSTISSET(
'desc') ?
GETPOST(
'desc',
'restricthtml') :
$object->
description,
'', 160,
'dolibarr_details',
'', false, true,
getDolGlobalInt(
'FCKEDITOR_ENABLE_DETAILS'), ROWS_4,
'90%');
2283 $doleditor->Create();
2290 print
'<tr><td>'.$langs->trans(
"PublicUrl").
'</td><td>';
2291 print img_picto(
'',
'globe',
'class="pictofixedwidth"');
2292 print
'<input type="text" name="url" class="maxwidth500 widthcentpercentminusx" value="'.(GETPOSTISSET(
'url') ?
GETPOST(
'url') :
$object->url).
'">';
2299 print
'<tr><td><input type="hidden" id="stockable_product" name="stockable_product" value="on" /></td><td></td></tr>';
2301 print
'<tr><td><label for="stockable_product">' . $langs->trans(
"StockableProduct") .
'</label></td>';
2302 $checked = empty(
$object->stockable_product) ?
"" :
"checked";
2303 print
'<td><input type="checkbox" id="stockable_product" name="stockable_product" '. $checked .
' /></td></tr>';
2307 print
'<tr class="showifstockable'.(empty(
$object->stockable_product) ?
' hidden' :
'').
'"><td>'.$langs->trans(
"DefaultWarehouse").
'</td><td>';
2308 print img_picto($langs->trans(
"DefaultWarehouse"),
'stock',
'class="pictofixedwidth"');
2309 print $formproduct->selectWarehouses((
GETPOSTISSET(
'fk_default_warehouse') ?
GETPOST(
'fk_default_warehouse') :
$object->fk_default_warehouse),
'fk_default_warehouse',
'warehouseopen', 1, 0, 0,
'', 0, 0, array(),
'minwidth200 maxwidth500 widthcentpercentminusxx');
2310 print
' <a href="'.DOL_URL_ROOT.
'/product/stock/card.php?action=create&backtopage='.urlencode($_SERVER[
'PHP_SELF'].
'?action=edit&id='.((
int)
$object->id)).
'">';
2311 print
'<span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans(
"AddWarehouse").
'"></span></a>';
2327 print
'<tr><td>'.$langs->trans(
"DefaultWorkstation").
'</td><td>';
2328 print img_picto($langs->trans(
"DefaultWorkstation"),
'workstation',
'class="pictofixedwidth"');
2329 print $formproduct->selectWorkstations(
$object->fk_default_workstation,
'fk_default_workstation', 1);
2342 print
'<tr><td>'.$langs->trans(
"Duration").
'</td><td>';
2343 print
'<input name="duration_value" class="width50" value="'.($object->duration_value ?
$object->duration_value :
'').
'"> ';
2345 print $formproduct->selectMeasuringUnits(
"duration_unit",
"time", (
$object->duration_unit ?
$object->duration_unit :
'h'), 0, 1);
2349 print
' ';
2351 print
'<input type="checkbox" class="valignmiddle" id="mandatoryperiod" name="mandatoryperiod"'.($object->mandatory_period == 1 ?
' checked="checked"' :
'').
'>';
2352 print
'<label for="mandatoryperiod">';
2353 $htmltooltip = $langs->trans(
"mandatoryHelper");
2355 $htmltooltip .=
'<br>'.$langs->trans(
"mandatoryHelper2");
2357 print $form->textwithpicto($langs->trans(
"mandatoryperiod"), $htmltooltip, 1,
'info');
2364 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"NatureOfProductShort"), $langs->trans(
"NatureOfProductDesc")).
'</td><td>';
2371 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"DefaultBOM"), $langs->trans(
"DefaultBOMDesc", $langs->transnoentitiesnoconv(
"Finished"))).
'</td><td>';
2372 $bomkey =
"Bom:bom/class/bom.class.php:0:(t.status:=:1) AND (t.fk_product:=:".((int)
$object->id).
')';
2373 print img_picto($langs->trans(
"DefaultBOM"),
'bom',
'class="pictofixedwidth"');
2374 print $form->selectForForms($bomkey,
'fk_default_bom', (
GETPOSTISSET(
'fk_default_bom') ?
GETPOST(
'fk_default_bom') :
$object->fk_default_bom), 1);
2381 print
'<tr><td>'.$langs->trans(
"Weight").
'</td><td>';
2382 print
'<input name="weight" size="5" value="'.(GETPOSTISSET(
'weight') ?
GETPOST(
'weight') :
$object->weight).
'"> ';
2383 print $formproduct->selectMeasuringUnits(
"weight_units",
"weight",
GETPOSTISSET(
'weight_units') ?
GETPOST(
'weight_units') : (int)
$object->weight_units, 0, 2);
2389 print
'<tr><td>'.$langs->trans(
"Length").
' x '.$langs->trans(
"Width").
' x '.$langs->trans(
"Height").
'</td><td>';
2390 print
'<input name="size" size="5" value="'.(GETPOSTISSET(
'size') ?
GETPOST(
'size') :
$object->length).
'">x';
2391 print
'<input name="sizewidth" size="5" value="'.(GETPOSTISSET(
'sizewidth') ?
GETPOST(
'sizewidth') :
$object->width).
'">x';
2392 print
'<input name="sizeheight" size="5" value="'.(GETPOSTISSET(
'sizeheight') ?
GETPOST(
'sizeheight') :
$object->height).
'"> ';
2393 print $formproduct->selectMeasuringUnits(
"size_units",
"size",
GETPOSTISSET(
'size_units') ?
GETPOST(
'size_units') : (int)
$object->length_units, 0, 2);
2398 print
'<tr><td>'.$langs->trans(
"Surface").
'</td><td>';
2399 print
'<input name="surface" size="5" value="'.(GETPOSTISSET(
'surface') ?
GETPOST(
'surface') :
$object->surface).
'"> ';
2400 print $formproduct->selectMeasuringUnits(
"surface_units",
"surface",
GETPOSTISSET(
'surface_units') ?
GETPOST(
'surface_units') : (int)
$object->surface_units, 0, 2);
2405 print
'<tr><td>'.$langs->trans(
"Volume").
'</td><td>';
2406 print
'<input name="volume" size="5" value="'.(GETPOSTISSET(
'volume') ?
GETPOST(
'volume') :
$object->volume).
'"> ';
2407 print $formproduct->selectMeasuringUnits(
"volume_units",
"volume",
GETPOSTISSET(
'volume_units') ?
GETPOST(
'volume_units') : (int)
$object->volume_units, 0, 2);
2413 print
'<tr><td>'.$langs->trans(
"NetMeasure").
'</td><td>';
2414 print
'<input name="net_measure" size="5" value="'.(GETPOSTISSET(
'net_measure') ?
GETPOST(
'net_measure') :
$object->net_measure).
'"> ';
2415 print $formproduct->selectMeasuringUnits(
"net_measure_units",
"",
GETPOSTISSET(
'net_measure_units') ?
GETPOST(
'net_measure_units') : (int)
$object->net_measure_units, 0, 0);
2421 print
'<tr><td>'.$langs->trans(
'DefaultUnitToShow').
'</td>';
2423 print $form->selectUnits(
$object->fk_unit,
'units');
2429 print
'<tr><td class="wordbreak">'.$form->textwithpicto($langs->trans(
"CustomsCode"), $langs->trans(
"CustomsCodeHelp")).
'</td>';
2430 print
'<td>' . img_picto(
'',
'fa-clipboard-check',
'class="pictofixedwidth"') .
'<input name="customcode" class="maxwidth100onsmartphone" value="'.(GETPOSTISSET(
'customcode') ?
GETPOST(
'customcode') :
$object->customcode).
'"></td></tr>';
2432 print
'<tr><td>'.$langs->trans(
"CountryOrigin").
'</td>';
2434 print img_picto(
'',
'globe-americas',
'class="pictofixedwidth"');
2435 print $form->select_country((
string) (
GETPOSTISSET(
'country_id') ?
GETPOSTINT(
'country_id') :
$object->country_id),
'country_id',
'', 0,
'minwidth100 maxwidthonsmartphone');
2437 print
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
2445 print
'<td>'.$form->editfieldkey(
'RegionStateOrigin',
'state_id',
'', $object, 0).
'</td><td>';
2447 print
'<td>'.$form->editfieldkey(
'StateOrigin',
'state_id',
'', $object, 0).
'</td><td>';
2450 print img_picto(
'',
'state',
'class="pictofixedwidth"');
2459 print
'<tr><td>'.$langs->trans(
"LifeTime").
'</td><td><input name="lifetime" class="maxwidth100onsmartphone" value="'.
$object->lifetime.
'"></td></tr>';
2460 print
'<tr><td>'.$langs->trans(
"QCFrequency").
'</td><td><input name="qc_frequency" class="maxwidth100onsmartphone" value="'.
$object->qc_frequency.
'"></td></tr>';
2464 $parameters = array(
'colspan' =>
' colspan="2"',
'cols' => 2);
2465 $reshook = $hookmanager->executeHooks(
'formObjectOptions', $parameters, $object, $action);
2466 print $hookmanager->resPrint;
2467 if (empty($reshook)) {
2468 print
$object->showOptionals($extrafields,
'edit', $parameters);
2473 print
'<tr><td>'.$langs->trans(
"Categories").
'</td><td>';
2474 print $form->selectCategories(Categorie::TYPE_PRODUCT,
'categories', $object);
2480 print
'<tr><td class="tdtop">'.$langs->trans(
"NoteNotVisibleOnBill").
'</td><td>';
2482 $doleditor =
new DolEditor(
'note_private',
$object->note_private,
'', 140,
'dolibarr_notes',
'',
false,
true,
getDolGlobalInt(
'FCKEDITOR_ENABLE_NOTE_PRIVATE'), ROWS_4,
'90%');
2483 $doleditor->Create();
2493 print
'<table class="border centpercent">';
2499 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellCode").
'</td>';
2501 print $formaccounting->select_account((
GETPOSTISSET(
'accountancy_code_sell') ?
GETPOST(
'accountancy_code_sell') :
$object->accountancy_code_sell),
'accountancy_code_sell', 1, array(), 1, 1,
'minwidth150 maxwidth300');
2502 $nb = $formaccounting->nbaccounts;
2504 print
' <a href="'.DOL_URL_ROOT.
'/accountancy/admin/account.php">'.$langs->trans(
"SetupOn", $langs->trans(
"Chartofaccounts")).
'</a>';
2510 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellIntraCode").
'</td>';
2512 print $formaccounting->select_account((
GETPOSTISSET(
'accountancy_code_sell_intra') ?
GETPOST(
'accountancy_code_sell_intra') :
$object->accountancy_code_sell_intra),
'accountancy_code_sell_intra', 1, array(), 1, 1,
'minwidth150 maxwidth300');
2517 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellExportCode").
'</td>';
2519 print $formaccounting->select_account((
GETPOSTISSET(
'accountancy_code_sell_export') ?
GETPOST(
'accountancy_code_sell_export') :
$object->accountancy_code_sell_export),
'accountancy_code_sell_export', 1, array(), 1, 1,
'minwidth150 maxwidth300');
2523 print
'<tr><td>'.$langs->trans(
"ProductAccountancyBuyCode").
'</td>';
2525 print $formaccounting->select_account((
GETPOSTISSET(
'accountancy_code_buy') ?
GETPOST(
'accountancy_code_buy') :
$object->accountancy_code_buy),
'accountancy_code_buy', 1, array(), 1, 1,
'minwidth150 maxwidth300');
2530 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyIntraCode").
'</td>';
2532 print $formaccounting->select_account((
GETPOSTISSET(
'accountancy_code_buy_intra') ?
GETPOST(
'accountancy_code_buy_intra') :
$object->accountancy_code_buy_intra),
'accountancy_code_buy_intra', 1, array(), 1, 1,
'minwidth150 maxwidth300');
2537 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyExportCode").
'</td>';
2539 print $formaccounting->select_account((
GETPOSTISSET(
'accountancy_code_buy_export') ?
GETPOST(
'accountancy_code_buy_export') :
$object->accountancy_code_buy_export),
'accountancy_code_buy_export', 1, array(), 1, 1,
'minwidth150 maxwidth300');
2544 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellCode").
'</td>';
2545 print
'<td><input name="accountancy_code_sell" class="maxwidth200" value="'.(GETPOSTISSET(
'accountancy_code_sell') ?
GETPOST(
'accountancy_code_sell') :
$object->accountancy_code_sell).
'">';
2550 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellIntraCode").
'</td>';
2551 print
'<td><input name="accountancy_code_sell_intra" class="maxwidth200" value="'.(GETPOSTISSET(
'accountancy_code_sell_intra') ?
GETPOST(
'accountancy_code_sell_intra') :
$object->accountancy_code_sell_intra).
'">';
2556 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellExportCode").
'</td>';
2557 print
'<td><input name="accountancy_code_sell_export" class="maxwidth200" value="'.(GETPOSTISSET(
'accountancy_code_sell_export') ?
GETPOST(
'accountancy_code_sell_export') :
$object->accountancy_code_sell_export).
'">';
2561 print
'<tr><td>'.$langs->trans(
"ProductAccountancyBuyCode").
'</td>';
2562 print
'<td><input name="accountancy_code_buy" class="maxwidth200" value="'.(GETPOSTISSET(
'accountancy_code_buy') ?
GETPOST(
'accountancy_code_buy') :
$object->accountancy_code_buy).
'">';
2567 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyIntraCode").
'</td>';
2568 print
'<td><input name="accountancy_code_buy_intra" class="maxwidth200" value="'.(GETPOSTISSET(
'accountancy_code_buy_intra') ?
GETPOST(
'accountancy_code_buy_intra') :
$object->accountancy_code_buy_intra).
'">';
2573 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyExportCode").
'</td>';
2574 print
'<td><input name="accountancy_code_buy_export" class="maxwidth200" value="'.(GETPOSTISSET(
'accountancy_code_buy_export') ?
GETPOST(
'accountancy_code_buy_export') :
$object->accountancy_code_buy_export).
'">';
2583 print
'$(document).ready(function() {
2584 $("#stockable_product").change(function() {
2585 $(".showifstockable").toggle(this.checked);
2594 print $form->buttonsSaveCancel();
2601 if (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && !$user->hasRight(
'barcode',
'lire_advance')) {
2606 $titre = $langs->trans(
"CardProduct".
$object->type);
2609 print
dol_get_fiche_head($head,
'card', $titre, -1, $picto, 0,
'',
'', 0,
'', 1);
2611 $linkback =
'<a href="'.DOL_URL_ROOT.
'/product/list.php?restore_lastsearch_values=1&type='.
$object->type.
'">'.$langs->trans(
"BackToList").
'</a>';
2612 $object->next_prev_filter =
"(te.fk_product_type:=:".((int)
$object->type).
")";
2615 if ($user->socid && !in_array(
'product', explode(
',',
getDolGlobalString(
'MAIN_MODULES_FOR_EXTERNAL')))) {
2619 dol_banner_tab($object,
'ref', $linkback, $shownav,
'ref');
2622 $parameters = array();
2624 $reshook = $hookmanager->executeHooks(
'tabContentViewProduct', $parameters, $object, $action);
2625 if (empty($reshook)) {
2626 print
'<div class="fichecenter">';
2627 print
'<div class="fichehalfleft">';
2629 print
'<div class="underbanner clearboth"></div>';
2630 print
'<table class="border tableforfield centpercent">';
2634 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
2635 print
'<tr><td class="titlefieldmiddle">';
2636 print (!
getDolGlobalString(
'PRODUCT_DENY_CHANGE_PRODUCT_TYPE')) ? $form->editfieldkey(
"Type",
'fk_product_type', (
string)
$object->type, $object, (
int) $usercancreate, $typeformat) : $langs->trans(
'Type');
2638 print $form->editfieldval(
"Type",
'fk_product_type',
$object->type, $object, $usercancreate, $typeformat);
2644 print
'<tr><td class="titlefieldmiddle nowrap">';
2645 print
'<table class="centpercent nobordernopadding"><tr><td class="nowrap">';
2646 print $langs->trans(
"BarcodeType");
2648 if (($action !=
'editbarcodetype') && $usercancreate && $createbarcode) {
2649 print
'<td class="right"><a class="editfielda" href="'.$_SERVER[
"PHP_SELF"].
'?action=editbarcodetype&id='.
$object->id.
'&token='.
newToken().
'">'.img_edit($langs->trans(
'Edit'), 1).
'</a></td>';
2651 print
'</tr></table>';
2653 if ($action ==
'editbarcodetype' || $action ==
'editbarcode') {
2654 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formbarcode.class.php';
2658 $fk_barcode_type =
'';
2659 if ($action ==
'editbarcodetype' && is_object($formbarcode)) {
2660 print $formbarcode->formBarcodeType($_SERVER[
'PHP_SELF'].
'?id='.
$object->id,
$object->barcode_type,
'fk_barcode_type');
2661 $fk_barcode_type =
$object->barcode_type;
2664 $fk_barcode_type =
$object->barcode_type;
2665 print
$object->barcode_type_label ?
$object->barcode_type_label : (
$object->barcode ?
'<div class="warning">'.$langs->trans(
"SetDefaultBarcodeType").
'<div>' :
'');
2667 print
'</td></tr>'.
"\n";
2670 print
'<tr><td class="nowrap">';
2671 print
'<table class="centpercent nobordernopadding"><tr><td class="nowrap">';
2672 print $langs->trans(
"BarcodeValue");
2674 if (($action !=
'editbarcode') && $usercancreate && $createbarcode) {
2675 print
'<td class="right"><a class="editfielda" href="'.$_SERVER[
"PHP_SELF"].
'?action=editbarcode&id='.
$object->id.
'&token='.
newToken().
'">'.img_edit($langs->trans(
'Edit'), 1).
'</a></td>';
2677 print
'</tr></table>';
2678 print
'</td><td class="wordbreak">';
2679 if ($action ==
'editbarcode') {
2681 if (empty($tmpcode) && !empty($modBarCodeProduct->code_auto)) {
2682 $tmpcode = $modBarCodeProduct->getNextValue($object, (
string) $fk_barcode_type);
2685 print
'<form method="post" action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'">';
2686 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2687 print
'<input type="hidden" name="action" value="setbarcode">';
2688 print
'<input type="hidden" name="barcode_type_code" value="'.$object->barcode_type_code.
'">';
2689 print
'<input class="width300" class="maxwidthonsmartphone" type="text" name="barcode" value="'.$tmpcode.
'">';
2690 print
' <input type="submit" class="button smallpaddingimp" value="'.$langs->trans(
"Modify").
'">';
2695 print
'</td></tr>'.
"\n";
2700 print
'<tr><td class="titlefieldmiddle">' . $form->textwithpicto($langs->trans(
"StockableProduct"), $langs->trans(
'StockableProductDescription')) .
'</td>';
2703 print
'<input type="checkbox" readonly disabled> <span class="opacitymedium">' . $langs->trans(
"NotSupportedOnKits").
'</span>';
2705 print
'<input type="checkbox" readonly disabled '.($object->stockable_product == 1 ?
'checked' :
'').
'>';
2709 if (
$object->isStockManaged() && !$iskit) {
2711 $warehouse->fetch(
$object->fk_default_warehouse);
2713 print
'<tr><td>'.$langs->trans(
"DefaultWarehouse").
'</td><td>';
2714 print(!empty($warehouse->id) ? $warehouse->getNomUrl(1) :
'');
2722 print
'<tr><td class="titlefieldmiddle">'.$langs->trans(
"ManageLotSerial").
'</td><td>';
2723 if (
$object->status_batch == 0) {
2724 print
'<span class="opacitymedium">'.yn(0).
'</span>';
2726 print
$object->getLibStatut(0, 2);
2731 print
'<tr><td>'.$langs->trans(
"ManageLotMask").
'</td><td>';
2737 print
'<tr><td class="titlefieldmiddle">'.$langs->trans(
'BatchSellOrEatByMandatoryList', $langs->transnoentities(
'SellByDate'), $langs->transnoentities(
'EatByDate')).
'</td><td>';
2738 if (
$object->sell_or_eat_by_mandatory == $object::SELL_OR_EAT_BY_MANDATORY_ID_NONE) {
2739 print
'<span class="opacitymedium">'.yn(0).
'</span>';
2741 print
$object->getSellOrEatByMandatoryLabel();
2748 $collapse = !empty($_COOKIE[
'DOLUSER_COLLAPSE_product_separator_accounting']);
2750 print
'<tr id="trseparatoraccounting" class="trseparator trseparatoraccounting">';
2751 print
'<td class="titlefieldmiddle firstcol"><span class="cursorpointer far fa-'.($collapse ?
'plus' :
'minus').
'-square"></span> <strong>'.$langs->trans(
"AccountancyCodes").
'</strong></td>';
2752 print
'<td class="secondcol">';
2753 $nbOfAccountingCodes = 0;
2754 $nbOfAccountingCodes += (
isModEnabled(
'accounting') && !empty(
$object->accountancy_code_sell)) ? 1 : 0;
2755 $nbOfAccountingCodes += (
isModEnabled(
'accounting') && !empty(
$object->accountancy_code_sell_intra)) ? 1 : 0;
2756 $nbOfAccountingCodes += (
isModEnabled(
'accounting') && !empty(
$object->accountancy_code_sell_export)) ? 1 : 0;
2757 $nbOfAccountingCodes += (
isModEnabled(
'accounting') && !empty(
$object->accountancy_code_buy)) ? 1 : 0;
2758 $nbOfAccountingCodes += (
isModEnabled(
'accounting') && !empty(
$object->accountancy_code_buy_intra)) ? 1 : 0;
2759 $nbOfAccountingCodes += (
isModEnabled(
'accounting') && !empty(
$object->accountancy_code_buy_export)) ? 1 : 0;
2760 print
'<span class="badge badge-secondary'.($collapse ?
'' :
' hidden').
'">'.$nbOfAccountingCodes.
'</span>';
2763 print
'<!-- Add js script to manage the collapse/uncollapse of separator accounting -->
2764 <script nonce="'.getNonce().
'" type="text/javascript">
2765 jQuery(document).ready(function(){
2766 console.log("Inject js for collapsing of separatoraccounting - keep visible and set cookie");
2767 /* document.cookie = "DOLUSER_COLLAPSE_product_separator_accounting=1; path='.DOL_URL_ROOT.
'/product/card.php"; */
2768 jQuery("#trseparatoraccounting").click(function(){
2769 console.log("We click on collapse/uncollapse to hide/show .tr_collapseaccounting");
2770 jQuery(".tr_collapseaccounting").toggle(100, function(){
2771 if (jQuery(".tr_collapseaccounting").first().is(":hidden")) {
2772 jQuery("#trseparatoraccounting td.firstcol span").addClass("fa-plus-square").removeClass("fa-minus-square");
2773 jQuery("#trseparatoraccounting td.secondcol span").removeClass("hidden");
2774 document.cookie = "DOLUSER_COLLAPSE_product_separator_accounting=1; path='.DOL_URL_ROOT.
'/product/card.php"
2776 jQuery("#trseparatoraccounting td.firstcol span").addClass("fa-minus-square").removeClass("fa-plus-square");
2777 jQuery("#trseparatoraccounting td.secondcol span").addClass("hidden");
2778 document.cookie = "DOLUSER_COLLAPSE_product_separator_accounting=0; path='.DOL_URL_ROOT.
'/product/card.php"
2786 print
'<tr class="tr_collapseaccounting'.($collapse ?
' hidden' :
'').
'"><td class="nowrap">';
2787 print $langs->trans(
"ProductAccountancySellCode");
2790 if (!empty(
$object->accountancy_code_sell)) {
2792 $accountingaccount->fetch(0,
$object->accountancy_code_sell, 1);
2794 print $accountingaccount->getNomUrl(0, 1, 1,
'', 1);
2797 print dolPrintHTML(
$object->accountancy_code_sell);
2803 print
'<tr class="tr_collapseaccounting'.($collapse ?
' hidden' :
'').
'"><td class="nowrap">';
2804 print $langs->trans(
"ProductAccountancySellIntraCode");
2807 if (!empty(
$object->accountancy_code_sell_intra)) {
2809 $accountingaccount2->fetch(0,
$object->accountancy_code_sell_intra, 1);
2811 print $accountingaccount2->getNomUrl(0, 1, 1,
'', 1);
2814 print dolPrintHTML(
$object->accountancy_code_sell_intra);
2820 print
'<tr class="tr_collapseaccounting'.($collapse ?
' hidden' :
'').
'"><td class="nowrap">';
2821 print $langs->trans(
"ProductAccountancySellExportCode");
2824 if (!empty(
$object->accountancy_code_sell_export)) {
2826 $accountingaccount3->fetch(0,
$object->accountancy_code_sell_export, 1);
2828 print $accountingaccount3->getNomUrl(0, 1, 1,
'', 1);
2831 print dolPrintHTML(
$object->accountancy_code_sell_export);
2836 print
'<tr class="tr_collapseaccounting'.($collapse ?
' hidden' :
'').
'"><td class="nowrap">';
2837 print $langs->trans(
"ProductAccountancyBuyCode");
2840 if (!empty(
$object->accountancy_code_buy)) {
2842 $accountingaccount4->fetch(0,
$object->accountancy_code_buy, 1);
2844 print $accountingaccount4->getNomUrl(0, 1, 1,
'', 1);
2847 print dolPrintHTML(
$object->accountancy_code_buy);
2853 print
'<tr class="tr_collapseaccounting'.($collapse ?
' hidden' :
'').
'"><td class="nowrap">';
2854 print $langs->trans(
"ProductAccountancyBuyIntraCode");
2857 if (!empty(
$object->accountancy_code_buy_intra)) {
2859 $accountingaccount5->fetch(0,
$object->accountancy_code_buy_intra, 1);
2861 print $accountingaccount5->getNomUrl(0, 1, 1,
'', 1);
2864 print dolPrintHTML(
$object->accountancy_code_buy_intra);
2870 print
'<tr class="tr_collapseaccounting'.($collapse ?
' hidden' :
'').
'"><td class="nowrap">';
2871 print $langs->trans(
"ProductAccountancyBuyExportCode");
2874 if (!empty(
$object->accountancy_code_buy_export)) {
2876 $accountingaccount6->fetch(0,
$object->accountancy_code_buy_export, 1);
2878 print $accountingaccount6->getNomUrl(0, 1, 1,
'', 1);
2881 print dolPrintHTML(
$object->accountancy_code_buy_export);
2887 print
'<tr><td class="tdtop">'.$langs->trans(
"Description").
'</td>';
2888 print
'<td class="wordbreakimp wrapimp"><div class="longmessagecut">'.(dol_textishtml(
$object->description) ?
$object->description :
dol_nl2br(
$object->description, 1,
true)).
'</div></td></tr>';
2892 print
'<tr><td>'.$langs->trans(
"PublicUrl").
'</td><td>';
2899 $res = $workstation->fetch(
$object->fk_default_workstation);
2901 print
'<tr><td>'.$langs->trans(
"DefaultWorkstation").
'</td><td>';
2902 print(!empty($workstation->id) ? $workstation->getNomUrl(1) :
'');
2910 if ($combination->fetchByFkProductChild(
$object->id) > 0) {
2911 $prodstatic =
new Product($db);
2912 $prodstatic->fetch($combination->fk_product_parent);
2915 print
'<tr><td>'.$langs->trans(
"ParentProduct").
'</td><td>';
2916 print $prodstatic->getNomUrl(1);
2924 print
'<div class="fichehalfright">';
2925 print
'<div class="underbanner clearboth"></div>';
2927 print
'<table class="border tableforfield centpercent">';
2931 print
'<tr><td class="valignmiddle">'.$langs->trans(
"Categories").
'</td><td>';
2932 print $form->showCategories(
$object->id, Categorie::TYPE_PRODUCT, 1);
2938 require_once DOL_DOCUMENT_ROOT.
'/core/class/cunits.class.php';
2939 $measuringUnits =
new CUnits($db);
2942 if (
$object->duration_value > 1) {
2945 $result = $measuringUnits->fetchAll(
'',
'scale', 0, 0, [
't.active' => 1,
't.unit_type' =>
'time']);
2946 if ($result !== -1) {
2947 foreach ($measuringUnits->records as $record) {
2948 $durations[$record->short_label] =
dol_ucfirst((
string) $record->label) . $plural;
2951 print
'<tr><td class="titlefieldmiddle">'.$langs->trans(
"Duration").
'</td><td>';
2952 if (
$object->duration_value) {
2953 print
$object->duration_value;
2954 print(!empty(
$object->duration_unit) && isset($durations[
$object->duration_unit]) ?
" ".$langs->trans($durations[
$object->duration_unit]).
" " :
'');
2958 $htmltooltip = $langs->trans(
"mandatoryHelper");
2960 $htmltooltip .=
'<br>'.$langs->trans(
"mandatoryHelper2");
2962 if (
$object->duration_value > 0) {
2963 print
' ';
2965 print
'<input type="checkbox" class="valignmiddle" name="mandatoryperiod"'.($object->mandatory_period == 1 ?
' checked="checked"' :
'').
' disabled>';
2966 print $form->textwithpicto($langs->trans(
"mandatoryperiod"), $htmltooltip, 1,
'info');
2972 print
'<tr><td class="titlefieldmiddle">'.$form->textwithpicto($langs->trans(
"NatureOfProductShort"), $langs->trans(
"NatureOfProductDesc")).
'</td><td>';
2973 print
$object->getLibFinished();
2979 print
'<tr><td class="titlefieldmiddle">'.$form->textwithpicto($langs->trans(
"DefaultBOM"), $langs->trans(
"DefaultBOMDesc", $langs->transnoentitiesnoconv(
"Finished"))).
'</td><td>';
2980 if (
$object->fk_default_bom) {
2981 $bom_static =
new BOM($db);
2982 $bom_static->fetch(
$object->fk_default_bom);
2983 print $bom_static->getNomUrl(1);
2991 print
'<tr><td class="titlefieldmiddle">'.$langs->trans(
"Weight").
'</td><td>';
2997 print
"</td></tr>\n";
3002 print
'<tr><td>'.$langs->trans(
"Length").
' x '.$langs->trans(
"Width").
' x '.$langs->trans(
"Height").
'</td><td>';
3006 print
" x ".$object->width;
3009 print
" x ".$object->height;
3011 print
' '.measuringUnitString(0,
"size",
$object->length_units);
3015 print
"</td></tr>\n";
3020 print(
getDolGlobalString(
'PRODUCT_DISABLE_SURFACE') ?
'' : $langs->trans(
"Surface"));
3022 print (
getDolGlobalString(
'PRODUCT_DISABLE_VOLUME') ?
'' : $langs->trans(
"Volume")).
'</td><td>';
3030 print
"</td></tr>\n";
3035 print
'<tr><td class="titlefieldmiddle">'.$langs->trans(
"NetMeasure").
'</td><td>';
3036 if (
$object->net_measure !=
'') {
3047 $unit =
$object->getLabelOfUnit(
'long', $langs);
3049 print
'<tr><td>'.$langs->trans(
'DefaultUnitToShow').
'</td><td>';
3056 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"CustomsCode"), $langs->trans(
"CustomsCodeHelp")).
'</td><td>'.dolPrintHTML(
$object->customcode).
'</td></tr>';
3059 print
'<tr><td>'.$langs->trans(
"Origin").
'</td><td>'.
getCountry(
$object->country_id,
'', $db);
3060 if (!empty(
$object->state_id)) {
3061 print
' - '.getState(
$object->state_id,
'0', $db);
3068 print
'<tr><td>'.$langs->trans(
"LifeTime").
'</td><td>'.
$object->lifetime.
'</td></tr>';
3069 print
'<tr><td>'.$langs->trans(
"QCFrequency").
'</td><td>'.
$object->qc_frequency.
'</td></tr>';
3073 $parameters = array();
3074 include DOL_DOCUMENT_ROOT.
'/core/tpl/extrafields_view.tpl.php';
3078 print
'<!-- show Note --> '.
"\n";
3080 print
'<!-- End show Note --> '.
"\n";
3087 print
'<div class="clearboth"></div>';
3092 } elseif ($action !=
'create') {
3098if (!empty($modCodeProduct->code_auto)) {
3100 $tmpcode = $modCodeProduct->getNextValue($object,
$object->type);
3106if (($action ==
'delete' && (empty(
$conf->use_javascript_ajax) || !empty(
$conf->dol_use_jmobile)))
3107 || (!empty(
$conf->use_javascript_ajax) && empty(
$conf->dol_use_jmobile))) {
3108 $formconfirm = $form->formconfirm(
"card.php?id=".
$object->id, $langs->trans(
"DeleteProduct"), $langs->trans(
"ConfirmDeleteProduct"),
"confirm_delete",
'', 0,
"action-delete");
3110if ($action ==
'merge') {
3111 $formquestion = array(
3113 'name' =>
'product_origin',
3114 'label' => $langs->trans(
'MergeOriginProduct'),
3116 'value' => $form->select_produits(0,
'product_origin',
'', 0, 0, 1, 2,
'', 1, array(), 0, 1, 0,
'minwidth200', 0,
'',
null, 1),
3119 $formconfirm = $form->formconfirm($_SERVER[
"PHP_SELF"].
"?id=".
$object->id, $langs->trans(
"MergeProducts"), $langs->trans(
"ConfirmMergeProducts"),
"confirm_merge", $formquestion,
'no', 1, 250);
3123if (($action ==
'clone' && (empty(
$conf->use_javascript_ajax) || !empty(
$conf->dol_use_jmobile)))
3124 || (!empty(
$conf->use_javascript_ajax) && empty(
$conf->dol_use_jmobile))) {
3126 $formquestionclone = array(
3127 'text' => $langs->trans(
"ConfirmClone"),
3128 0 => array(
'type' =>
'text',
'name' =>
'clone_ref',
'label' => $langs->trans(
"NewRefForClone"),
'value' => empty($tmpcode) ? $langs->trans(
"CopyOf").
' '.
$object->ref : $tmpcode,
'morecss' =>
'width150'),
3129 1 => array(
'type' =>
'checkbox',
'name' =>
'clone_content',
'label' => $langs->trans(
"CloneContentProduct"),
'value' => 1),
3130 2 => array(
'type' =>
'checkbox',
'name' =>
'clone_categories',
'label' => $langs->trans(
"CloneCategoriesProduct"),
'value' => 1),
3133 $formquestionclone[] = array(
'type' =>
'checkbox',
'name' =>
'clone_prices',
'label' => $langs->trans(
"ClonePricesProduct").
' ('.$langs->trans(
"MultiPrices").
')',
'value' => 0);
3136 $formquestionclone[] = array(
'type' =>
'checkbox',
'name' =>
'clone_prices',
'label' => $langs->trans(
"ClonePricesProduct").
' ('.$langs->trans(
"CustomerPerPrices").
')',
'value' => 0);
3139 $formquestionclone[] = array(
'type' =>
'checkbox',
'name' =>
'clone_prices',
'label' => $langs->trans(
"ClonePricesProduct").
' ('.$langs->trans(
"MultiPricesAndCustomerPerPrices").
')',
'value' => 0);
3142 $formquestionclone[] = array(
'type' =>
'checkbox',
'name' =>
'clone_composition',
'label' => $langs->trans(
'CloneCompositionProduct'),
'value' => 1);
3144 if (
isModEnabled(
'bom') && $user->hasRight(
'bom',
'write')) {
3145 if (
$object->fk_default_bom > 0) {
3146 $formquestionclone[] = array(
'type' =>
'checkbox',
'name' =>
'clone_defbom',
'label' => $langs->trans(
"CloneDefBomProduct"),
'value' =>
getDolGlobalInt(
'BOM_CLONE_DEFBOM'));
3148 $bomstatic =
new BOM($db);
3149 $bomlist = $bomstatic->fetchAll(
"",
"", 0, 0,
'fk_product:=:'.(
int)
$object->id);
3150 if (is_array($bomlist) && count($bomlist) > 0) {
3151 $formquestionclone[] = array(
'type' =>
'checkbox',
'name' =>
'clone_otherboms',
'label' => $langs->trans(
"CloneOtherBomsProduct"),
'value' => 0);
3154 $formconfirm .= $form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.
$object->id, $langs->trans(
'ToClone'), $langs->trans(
'ConfirmCloneProduct',
$object->ref),
'confirm_clone', $formquestionclone,
'yes',
'action-clone', 0, 600);
3158$parameters = array(
'formConfirm' => $formconfirm,
'object' => $object);
3159$reshook = $hookmanager->executeHooks(
'formConfirm', $parameters, $object, $action);
3160if (empty($reshook)) {
3161 $formconfirm .= $hookmanager->resPrint;
3162} elseif ($reshook > 0) {
3163 $formconfirm = $hookmanager->resPrint;
3172if ($action !=
'create' && $action !=
'edit') {
3173 $cloneProductUrl =
dolBuildUrl($_SERVER[
"PHP_SELF"], [
'action' =>
'clone'],
true);
3174 $cloneButtonId =
'action-clone-no-ajax';
3176 print
"\n".
'<div class="tabsAction">'.
"\n";
3178 $parameters = array();
3179 $reshook = $hookmanager->executeHooks(
'addMoreActionsButtons', $parameters, $object, $action);
3180 if (empty($reshook)) {
3181 if ($usercancreate) {
3182 if (!isset($hookmanager->resArray[
'no_button_edit']) || $hookmanager->resArray[
'no_button_edit'] != 1) {
3183 print dolGetButtonAction(
'', $langs->trans(
'Modify'),
'default',
dolBuildUrl($_SERVER[
"PHP_SELF"], [
'action' =>
'edit',
'id' =>
$object->id],
true),
'', $usercancreate);
3187 print dolGetButtonAction(
'', $langs->trans(
'SendMail'),
'email',
dolBuildUrl($_SERVER[
"PHP_SELF"], [
'id' =>
$object->id,
'action' =>
'presend',
'mode' =>
'init'],
true).
'#formmailbeforetitle');
3189 if (!isset($hookmanager->resArray[
'no_button_copy']) || $hookmanager->resArray[
'no_button_copy'] != 1) {
3190 if (!empty(
$conf->use_javascript_ajax) && empty(
$conf->dol_use_jmobile)) {
3191 $cloneProductUrl =
'';
3192 $cloneButtonId =
'action-clone';
3194 print dolGetButtonAction($langs->trans(
'ToClone'), $langs->trans(
'ToClone'),
'clone', $cloneProductUrl, $cloneButtonId, $usercancreate, array(
'attr' => array(
'class' =>
'reposition')));
3199 if ($usercandelete) {
3200 if (empty($object_is_used)) {
3201 if (!isset($hookmanager->resArray[
'no_button_delete']) || $hookmanager->resArray[
'no_button_delete'] != 1) {
3202 if (!empty(
$conf->use_javascript_ajax) && empty(
$conf->dol_use_jmobile)) {
3203 print dolGetButtonAction($langs->trans(
'Delete'), $langs->trans(
'Delete'),
'delete',
'#',
'action-delete',
true, array(
'attr' => array(
'class' =>
'reposition'))).
"\n";
3205 print dolGetButtonAction($langs->trans(
'Delete'), $langs->trans(
'Delete'),
'delete',
dolBuildUrl($_SERVER[
"PHP_SELF"], [
'action' =>
'delete',
'id' =>
$object->id],
true),
'',
true, array(
'attr' => array(
'class' =>
'reposition'))).
"\n";
3209 print dolGetButtonAction($langs->trans(
"ProductIsUsed"), $langs->trans(
'Delete'),
'delete',
'#',
'',
false);
3212 print
'<a class="butActionDelete" href="card.php?action=merge&id='.$object->id.
'&token='.
newToken().
'" title="'.
dol_escape_htmltag($langs->trans(
"MergeProducts")).
'">'.$langs->trans(
'Merge').
'</a>'.
"\n";
3215 print dolGetButtonAction($langs->trans(
"NotEnoughPermissions"), $langs->trans(
'Delete'),
'delete',
'#',
'',
false);
3233 if (
isModEnabled(
"propal") && $user->hasRight(
'propal',
'creer')) {
3234 $propal =
new Propal($db);
3236 $langs->load(
"propal");
3238 $otherprop = $propal->liste_array(2, 1, 0);
3240 if (is_array($otherprop) && count($otherprop)) {
3241 $html .=
'<tr><td style="width: 200px;">';
3242 $html .= $langs->trans(
"AddToDraftProposals").
'</td><td>';
3243 $html .= $form->selectarray(
"propalid", $otherprop, 0, 1);
3244 $html .=
'</td></tr>';
3246 $html .=
'<tr><td style="width: 200px;">';
3247 $html .= $langs->trans(
"AddToDraftProposals").
'</td><td>';
3248 $html .= $langs->trans(
"NoDraftProposals");
3249 $html .=
'</td></tr>';
3254 if (
isModEnabled(
'order') && $user->hasRight(
'commande',
'creer')) {
3257 $langs->load(
"orders");
3259 $othercom = $commande->liste_array(2, 1,
null);
3260 if (is_array($othercom) && count($othercom)) {
3261 $html .=
'<tr><td style="width: 200px;">';
3262 $html .= $langs->trans(
"AddToDraftOrders").
'</td><td>';
3263 $html .= $form->selectarray(
"commandeid", $othercom, 0, 1);
3264 $html .=
'</td></tr>';
3266 $html .=
'<tr><td style="width: 200px;">';
3267 $html .= $langs->trans(
"AddToDraftOrders").
'</td><td>';
3268 $html .= $langs->trans(
"NoDraftOrders");
3269 $html .=
'</td></tr>';
3274 if (
isModEnabled(
'invoice') && $user->hasRight(
'facture',
'creer')) {
3277 $langs->load(
"bills");
3279 $otherinvoice = $invoice->liste_array(2, 1,
null);
3280 if (is_array($otherinvoice) && count($otherinvoice)) {
3281 $html .=
'<tr><td style="width: 200px;">';
3282 $html .= $langs->trans(
"AddToDraftInvoices").
'</td><td>';
3283 $html .= $form->selectarray(
"factureid", $otherinvoice, 0, 1);
3284 $html .=
'</td></tr>';
3286 $html .=
'<tr><td style="width: 200px;">';
3287 $html .= $langs->trans(
"AddToDraftInvoices").
'</td><td>';
3288 $html .= $langs->trans(
"NoDraftInvoices");
3289 $html .=
'</td></tr>';
3294 if (!empty($html)) {
3295 print
'<form method="POST" action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'">';
3296 print
'<input type="hidden" name="token" value="'.newToken().
'">';
3297 print
'<input type="hidden" name="action" value="addin">';
3303 $html .=
'<tr><td class="nowrap">'.$langs->trans(
"Quantity").
' ';
3304 $html .=
'<input type="text" class="flat" name="qty" size="1" value="1"></td>';
3305 $html .=
'<td class="nowrap">'.$langs->trans(
"ReductionShort").
'(%) ';
3306 $html .=
'<input type="text" class="flat" name="remise_percent" size="1" value="0">';
3307 $html .=
'</td></tr>';
3309 print
'<table class="centpercent border">';
3313 print
'<div class="center">';
3314 print
'<input type="submit" class="button button-add" value="'.$langs->trans(
"Add").
'">';
3328if (
GETPOST(
'modelselected')) {
3329 $action =
'presend';
3332if ($action !=
'create' && $action !=
'edit' && $action !=
'delete') {
3333 print
'<div class="fichecenter"><div class="fichehalfleft">';
3334 print
'<a name="builddoc"></a>';
3338 if (!empty(
$conf->product->multidir_output[
$object->entity ??
$conf->entity])) {
3339 $filedir =
$conf->product->multidir_output[
$object->entity ??
$conf->entity].
'/'.$objectref;
3341 $filedir =
$conf->product->dir_output.
'/'.$objectref;
3343 $urlsource = $_SERVER[
"PHP_SELF"].
"?id=".
$object->id;
3344 $genallowed = $usercanread;
3345 $delallowed = $usercancreate;
3347 print $formfile->showdocuments($modulepart,
$object->ref, $filedir, $urlsource, (
int) $genallowed, (
int) $delallowed,
'', 0, 0, 0, 28, 0,
'',
'',
'', $langs->getDefaultLang(),
'', $object);
3348 $somethingshown = $formfile->numoffiles;
3350 print
'</div><div class="fichehalfright">';
3353 $morehtmlcenter =
'<div class="nowraponall">';
3354 $morehtmlcenter .=
dolGetButtonTitle($langs->trans(
'FullConversation'),
'',
'fa fa-comments imgforviewmode', DOL_URL_ROOT.
'/product/messaging.php?id='.
$object->id);
3355 $morehtmlcenter .=
dolGetButtonTitle($langs->trans(
'SeeAll'),
'',
'fa fa-bars imgforviewmode', DOL_URL_ROOT.
'/product/agenda.php?id='.
$object->id);
3356 $morehtmlcenter .=
'</div>';
3359 include_once DOL_DOCUMENT_ROOT.
'/core/class/html.formactions.class.php';
3361 $somethingshown = $formactions->showactions($object,
'product', 0, 1,
'', $MAXEVENT,
'', $morehtmlcenter);
3363 print
'</div></div>';
3366 $modelmail =
'product_send';
3367 $defaulttopic =
$object->label;
3369 $trackid =
'prod' .
$object->id;
3371 include DOL_DOCUMENT_ROOT.
'/core/tpl/card_presend.tpl.php';
$id
Support class for third parties, contacts, members, users or resources.
if(! $sortfield) if(! $sortorder) $object
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='', $placeholder='')
Convert a html select field into an ajax combobox.
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Class to manage accounting accounts.
Class of dictionary type of thirdparty (used by imports)
Class to manage categories.
Class to manage customers orders.
Class to manage a WYSIWYG editor.
Class to manage warehouses.
Class to manage invoices.
const TYPE_STANDARD
Standard invoice.
Class of a generic business object.
Class ProductCombination Used to represent the relation between a product and one of its variants.
File of class to manage predefined price products or services by customer.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
static getSellOrEatByMandatoryList()
Get the array of labels of Sell by or Eat by all mandatory flags for each status.
const TYPE_SERVICE
Service.
Class to manage proposals.
Class to manage third parties objects (customers, suppliers, prospects...)
if(! $sortfield) if(! $sortorder) $module
getCountry($searchkey, $withcode='', $dbtouse=null, $outputlangs=null, $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_move($srcfile, $destfile, $newmask='0', $overwriteifexists=1, $testvirus=0, $indexdatabase=1, $moreinfo=array(), $entity=null)
Move a file into another name.
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
dol_is_dir($folder)
Test if filename is a directory.
dol_now($mode='gmt')
Return date for now.
dol_ucfirst($string, $encoding="UTF-8")
Convert first character of the first word of a string to upper.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
dol_nl2br($stringtoencode, $nl2brmode=0, $forxml=false)
Replace CRLF in string with a HTML BR tag.
dol_print_url($url, $target='_blank', $max=32, $withpicto=0, $morecss='')
Show Url link.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTFLOAT($paramname, $rounding='', $option=2)
Return the value of a $_GET or $_POST supervariable, converted into float.
dol_htmlcleanlastbr($stringtodecode)
This function remove all ending and br at end.
get_default_npr(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that returns whether VAT must be recoverable collected VAT (e.g.: VAT NPR in France)
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
dol_textishtml($msg, $option=0)
Return if a text is a html content.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
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.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
get_localtax($vatrate, $local, $thirdparty_buyer=null, $thirdparty_seller=null, $vatnpr=0)
Return localtax rate for a particular VAT rate, when selling a product with vat $vatrate,...
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
showValueWithClipboardCPButton($valuetocopy, $showonlyonhover=1, $texttoshow='')
Create a button to copy $valuetocopy in the clipboard (for copy and paste feature).
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_set_focus($selector)
Set focus onto field with selector (similar behaviour of 'autofocus' HTML5 tag)
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='', $textonpictotooltip='', $cssfordropdown='info_admin')
Show information in HTML for admin users or standard users.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
measuringUnitString($unitid, $measuring_style='', $unitscale=null, $use_short_label=0, $outputlangs=null)
Return translation label of a unit key.
product_prepare_head($object)
Prepare array with list of tabs.
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $nodie=0, $mode='')
Check permissions of a user to show a page and an object.