46require
'../main.inc.php';
47require_once DOL_DOCUMENT_ROOT.
'/core/class/canvas.class.php';
48require_once DOL_DOCUMENT_ROOT.
'/core/class/extrafields.class.php';
49require_once DOL_DOCUMENT_ROOT.
'/core/class/genericobject.class.php';
50require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formcompany.class.php';
51require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formfile.class.php';
52require_once DOL_DOCUMENT_ROOT.
'/core/lib/company.lib.php';
53require_once DOL_DOCUMENT_ROOT.
'/core/lib/product.lib.php';
54require_once DOL_DOCUMENT_ROOT.
'/core/modules/product/modules_product.class.php';
55require_once DOL_DOCUMENT_ROOT.
'/categories/class/categorie.class.php';
56require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
57require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
60if (isModEnabled(
'propal')) {
61 require_once DOL_DOCUMENT_ROOT.
'/comm/propal/class/propal.class.php';
63if (isModEnabled(
'facture')) {
64 require_once DOL_DOCUMENT_ROOT.
'/compta/facture/class/facture.class.php';
66if (isModEnabled(
'commande')) {
67 require_once DOL_DOCUMENT_ROOT.
'/commande/class/commande.class.php';
69if (isModEnabled(
'accounting')) {
70 require_once DOL_DOCUMENT_ROOT.
'/core/lib/accounting.lib.php';
71 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formaccounting.class.php';
72 require_once DOL_DOCUMENT_ROOT.
'/accountancy/class/accountingaccount.class.php';
74if (isModEnabled(
'bom')) {
75 require_once DOL_DOCUMENT_ROOT.
'/bom/class/bom.class.php';
77if (isModEnabled(
'workstation')) {
78 require_once DOL_DOCUMENT_ROOT.
'/workstation/class/workstation.class.php';
82$langs->loadLangs(array(
'products',
'other'));
83if (isModEnabled(
'stock')) {
84 $langs->load(
"stocks");
86if (isModEnabled(
'facture')) {
87 $langs->load(
"bills");
89if (isModEnabled(
'productbatch')) {
90 $langs->load(
"productbatch");
93$mesg =
''; $error = 0; $errors = array();
100 $ref = (GETPOSTISSET(
'ref') ?
GETPOST(
'ref',
'nohtml') : null);
102 $ref = (GETPOSTISSET(
'ref') ?
GETPOST(
'ref',
'alpha') : null);
104$type = (GETPOSTISSET(
'type') ?
GETPOST(
'type',
'int') :
Product::TYPE_PRODUCT);
105$action = (
GETPOST(
'action',
'alpha') ?
GETPOST(
'action',
'alpha') :
'view');
106$cancel =
GETPOST(
'cancel',
'alpha');
107$backtopage =
GETPOST(
'backtopage',
'alpha');
108$confirm =
GETPOST(
'confirm',
'alpha');
109$socid =
GETPOST(
'socid',
'int');
110$duration_value =
GETPOST(
'duration_value',
'int');
111$duration_unit =
GETPOST(
'duration_unit',
'alpha');
113$accountancy_code_sell =
GETPOST(
'accountancy_code_sell',
'alpha');
114$accountancy_code_sell_intra =
GETPOST(
'accountancy_code_sell_intra',
'alpha');
115$accountancy_code_sell_export =
GETPOST(
'accountancy_code_sell_export',
'alpha');
116$accountancy_code_buy =
GETPOST(
'accountancy_code_buy',
'alpha');
117$accountancy_code_buy_intra =
GETPOST(
'accountancy_code_buy_intra',
'alpha');
118$accountancy_code_buy_export =
GETPOST(
'accountancy_code_buy_export',
'alpha');
120$checkmandatory =
GETPOST(
'accountancy_code_buy_export',
'alpha');
124 $label_security_check =
'nohtml';
126 $label_security_check = !
getDolGlobalString(
'MAIN_SECURITY_ALLOW_UNSECURED_LABELS_WITH_HTML') ?
'alphanohtml' :
'restricthtml';
129if (!empty($user->socid)) {
130 $socid = $user->socid;
134$module = (
getDolGlobalString(
'PRODUCT_CODEPRODUCT_ADDON') ? $conf->global->PRODUCT_CODEPRODUCT_ADDON :
'mod_codeproduct_leopard');
135if (substr($module, 0, 16) ==
'mod_codeproduct_' && substr($module, -3) ==
'php') {
136 $module = substr($module, 0,
dol_strlen($module) - 4);
140 $modCodeProduct =
new $module();
144$object->type = $type;
148$extrafields->fetch_name_optionals_label($object->table_element);
150if ($id > 0 || !empty($ref)) {
151 $result = $object->fetch($id, $ref);
155 $entity = (empty($object->entity) ? $conf->entity : $object->entity);
156 if (isModEnabled(
"product")) {
157 $upload_dir = $conf->product->multidir_output[$entity].
'/'.
get_exdir(0, 0, 0, 0, $object,
'product').dol_sanitizeFileName($object->ref);
158 } elseif (isModEnabled(
"service")) {
159 $upload_dir = $conf->service->multidir_output[$entity].
'/'.
get_exdir(0, 0, 0, 0, $object,
'product').dol_sanitizeFileName($object->ref);
163 if (isModEnabled(
"product")) {
164 $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";
166 $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";
171$modulepart =
'product';
174$canvas = !empty($object->canvas) ? $object->canvas :
GETPOST(
"canvas");
176if (!empty($canvas)) {
177 require_once DOL_DOCUMENT_ROOT.
'/core/class/canvas.class.php';
178 $objcanvas =
new Canvas($db, $action);
179 $objcanvas->getCanvas(
'product',
'card', $canvas);
183$fieldvalue = (!empty($id) ? $id : (!empty($ref) ? $ref :
''));
184$fieldtype = (!empty($id) ?
'rowid' :
'ref');
186if ($object->id > 0) {
187 if ($object->type == $object::TYPE_PRODUCT) {
188 restrictedArea($user,
'produit', $object->id,
'product&product',
'',
'');
190 if ($object->type == $object::TYPE_SERVICE) {
191 restrictedArea($user,
'service', $object->id,
'product&product',
'',
'');
194 restrictedArea($user,
'produit|service', 0,
'product&product',
'',
'', $fieldtype);
198$hookmanager->initHooks(array(
'productcard',
'globalcard'));
214$createbarcode = isModEnabled(
'barcode');
215if (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && !$user->hasRight(
'barcode',
'creer_advance')) {
219$parameters = array(
'id'=>$id,
'ref'=>$ref,
'objcanvas'=>$objcanvas);
220$reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
225if (empty($reshook)) {
226 $backurlforlist = DOL_URL_ROOT.
'/product/list.php?type='.$type;
228 if (empty($backtopage) || ($cancel && empty($id))) {
229 if (empty($backtopage) || ($cancel && strpos($backtopage,
'__ID__'))) {
230 if (empty($id) && (($action !=
'add' && $action !=
'create') || $cancel)) {
231 $backtopage = $backurlforlist;
233 $backtopage = DOL_URL_ROOT.
'/product/card.php?id='.((!empty($id) && $id > 0) ? $id :
'__ID__');
239 if (!empty($backtopageforcancel)) {
240 header(
"Location: ".$backtopageforcancel);
242 } elseif (!empty($backtopage)) {
243 header(
"Location: ".$backtopage);
249 if ($action ==
'confirm_merge' && $confirm ==
'yes' && $user->hasRight(
'societe',
'creer')) {
251 $productOriginId =
GETPOST(
'product_origin',
'int');
252 $productOrigin =
new Product($db);
254 if ($productOriginId <= 0) {
255 $langs->load(
'errors');
256 setEventMessages($langs->trans(
'ErrorProductIdIsMandatory', $langs->transnoentitiesnoconv(
'MergeOriginProduct')),
null,
'errors');
258 if (!$error && $productOrigin->fetch($productOriginId) < 1) {
268 $listofproperties = array(
278 'accountancy_code_buy',
279 'accountancy_code_buy_intra',
280 'accountancy_code_buy_export',
281 'accountancy_code_sell',
282 'accountancy_code_sell_intra',
283 'accountancy_code_sell_export'
285 foreach ($listofproperties as $property) {
286 if (empty($object->$property)) {
287 $object->$property = $productOrigin->$property;
291 $listofproperties = array(
292 'note_public',
'note_private'
294 foreach ($listofproperties as $property) {
295 $object->$property =
dol_concatdesc($object->$property, $productOrigin->$property);
299 if (is_array($productOrigin->array_options)) {
300 foreach ($productOrigin->array_options as $key => $val) {
301 if (empty($object->array_options[$key])) {
302 $object->array_options[$key] = $val;
309 $custcats_ori = $static_cat->containing($productOrigin->id,
'product',
'id');
310 $custcats = $static_cat->containing($object->id,
'product',
'id');
311 $custcats = array_merge($custcats, $custcats_ori);
312 $object->setCategories($custcats);
315 if ($productOrigin->barcode == $object->barcode) {
316 dol_syslog(
"We clean customer and supplier code so we will be able to make the update of target");
317 $productOrigin->barcode =
'';
322 $result = $object->update($object->id, $user, 0,
'merge');
333 'ActionComm' =>
'/comm/action/class/actioncomm.class.php',
334 'Bom' =>
'/bom/class/bom.class.php',
337 'Commande' =>
'/commande/class/commande.class.php',
338 'CommandeFournisseur' =>
'/fourn/class/fournisseur.commande.class.php',
339 'Contrat' =>
'/contrat/class/contrat.class.php',
340 'Delivery' =>
'/delivery/class/delivery.class.php',
341 'Facture' =>
'/compta/facture/class/facture.class.php',
342 'FactureFournisseur' =>
'/fourn/class/fournisseur.facture.class.php',
343 'FactureRec' =>
'/compta/facture/class/facture-rec.class.php',
344 'FichinterRec' =>
'/fichinter/class/fichinterrec.class.php',
345 'ProductFournisseur' =>
'/fourn/class/fournisseur.product.class.php',
346 'Propal' =>
'/comm/propal/class/propal.class.php',
347 'Reception' =>
'/reception/class/reception.class.php',
348 'SupplierProposal' =>
'/supplier_proposal/class/supplier_proposal.class.php',
352 foreach ($objects as $object_name => $object_file) {
353 require_once DOL_DOCUMENT_ROOT.$object_file;
355 if (!$error && !$object_name::replaceProduct($db, $productOrigin->id, $object->id)) {
365 $parameters = array(
'soc_origin' => $productOrigin->id,
'soc_dest' => $object->id);
366 $reshook = $hookmanager->executeHooks(
381 $object->context = array(
383 'mergefromid' => $productOrigin->id,
387 $result = $object->call_trigger(
'PRODUCT_MODIFY', $user);
398 if ($productOrigin->delete($user) < 1) {
407 $langs->load(
"errors");
416 if ($action ==
'setfk_product_type' && $usercancreate) {
417 $result = $object->setValueFrom(
'fk_product_type',
GETPOST(
'fk_product_type'),
'',
null,
'text',
'', $user,
'PRODUCT_MODIFY');
418 header(
"Location: ".$_SERVER[
'PHP_SELF'].
"?id=".$object->id);
423 $upload_dir = $conf->product->dir_output;
424 $permissiontoadd = $usercancreate;
425 include DOL_DOCUMENT_ROOT.
'/core/actions_builddoc.inc.php';
427 include DOL_DOCUMENT_ROOT.
'/core/actions_printing.inc.php';
430 if ($action ==
'setfk_barcode_type' && $createbarcode) {
431 $result = $object->setValueFrom(
'fk_barcode_type',
GETPOST(
'fk_barcode_type'),
'',
null,
'text',
'', $user,
'PRODUCT_MODIFY');
432 header(
"Location: ".$_SERVER[
'PHP_SELF'].
"?id=".$object->id);
437 if ($action ==
'setbarcode' && $createbarcode) {
438 $result = $object->check_barcode(
GETPOST(
'barcode'),
GETPOST(
'barcode_type_code'));
441 $result = $object->setValueFrom(
'barcode',
GETPOST(
'barcode'),
'',
null,
'text',
'', $user,
'PRODUCT_MODIFY');
442 header(
"Location: ".$_SERVER[
'PHP_SELF'].
"?id=".$object->id);
445 $langs->load(
"errors");
447 $errors[] =
'ErrorBadBarCodeSyntax';
448 } elseif ($result == -2) {
449 $errors[] =
'ErrorBarCodeRequired';
450 } elseif ($result == -3) {
451 $errors[] =
'ErrorBarCodeAlreadyUsed';
453 $errors[] =
'FailedToValidateBarCode';
462 if ($action ==
'update_extras') {
463 $object->oldcopy =
dol_clone($object, 2);
466 $ret = $extrafields->setOptionalsFromPost(
null, $object,
GETPOST(
'attribute',
'restricthtml'));
473 $result = $object->insertExtraFields(
'PRODUCT_MODIFY');
481 $action =
'edit_extras';
486 if ($action ==
'add' && $usercancreate) {
489 if (!
GETPOST(
'label', $label_security_check)) {
490 setEventMessages($langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'Label')),
null,
'errors');
496 setEventMessages($langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'ProductRef')),
null,
'errors');
501 if (!empty($duration_value) && empty($duration_unit)) {
502 setEventMessages($langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'Unit')),
null,
'errors');
508 $units =
GETPOST(
'units',
'int');
510 $object->entity = $conf->entity;
512 $object->label =
GETPOST(
'label', $label_security_check);
513 $object->price_base_type =
GETPOST(
'price_base_type',
'aZ09');
514 $object->mandatory_period = !empty(
GETPOST(
"mandatoryperiod",
'alpha')) ? 1 : 0;
515 if ($object->price_base_type ==
'TTC') {
516 $object->price_ttc =
GETPOST(
'price');
518 $object->price =
GETPOST(
'price');
520 if ($object->price_base_type ==
'TTC') {
521 $object->price_min_ttc =
GETPOST(
'price_min');
523 $object->price_min =
GETPOST(
'price_min');
526 $tva_tx_txt =
GETPOST(
'tva_tx',
'alpha');
530 $tva_tx = preg_replace(
'/[^0-9\.].*$/',
'', $tva_tx_txt);
531 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
534 $localtax1_type =
'0';
535 $localtax2_type =
'0';
538 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
540 $vatratecode = $reg[1];
542 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
543 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
544 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($mysoc->country_code).
"'";
545 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
546 $sql .=
" AND t.code = '".$db->escape($vatratecode).
"'";
547 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
548 $resql = $db->query($sql);
550 $obj = $db->fetch_object($resql);
551 $npr = $obj->recuperableonly;
552 $localtax1 = $obj->localtax1;
553 $localtax2 = $obj->localtax2;
554 $localtax1_type = $obj->localtax1_type;
555 $localtax2_type = $obj->localtax2_type;
559 $object->default_vat_code = $vatratecode;
560 $object->tva_tx = $tva_tx;
561 $object->tva_npr = $npr;
562 $object->localtax1_tx = $localtax1;
563 $object->localtax2_tx = $localtax2;
564 $object->localtax1_type = $localtax1_type;
565 $object->localtax2_type = $localtax2_type;
567 $object->type = $type;
568 $object->status =
GETPOST(
'statut');
569 $object->status_buy =
GETPOST(
'statut_buy');
570 $object->status_batch =
GETPOST(
'status_batch');
571 $object->batch_mask =
GETPOST(
'batch_mask');
573 $object->barcode_type =
GETPOST(
'fk_barcode_type');
574 $object->barcode =
GETPOST(
'barcode');
577 $stdobject->element =
'product';
578 $stdobject->barcode_type =
GETPOST(
'fk_barcode_type');
579 $result = $stdobject->fetch_barcode();
582 $mesg =
'Failed to get bar code type information ';
585 $object->barcode_type_code = $stdobject->barcode_type_code;
586 $object->barcode_type_coder = $stdobject->barcode_type_coder;
587 $object->barcode_type_label = $stdobject->barcode_type_label;
592 $object->note = $object->note_private;
593 $object->customcode =
GETPOST(
'customcode',
'alphanohtml');
594 $object->country_id =
GETPOST(
'country_id',
'int');
595 $object->state_id =
GETPOST(
'state_id',
'int');
596 $object->lifetime =
GETPOST(
'lifetime',
'int');
597 $object->qc_frequency =
GETPOST(
'qc_frequency',
'int');
598 $object->duration_value = $duration_value;
599 $object->duration_unit = $duration_unit;
600 $object->fk_default_warehouse =
GETPOST(
'fk_default_warehouse',
'int');
601 $object->fk_default_workstation =
GETPOST(
'fk_default_workstation',
'int');
602 $object->seuil_stock_alerte =
GETPOST(
'seuil_stock_alerte') ?
GETPOST(
'seuil_stock_alerte') : 0;
603 $object->desiredstock =
GETPOST(
'desiredstock') ?
GETPOST(
'desiredstock') : 0;
604 $object->canvas =
GETPOST(
'canvas');
605 $object->net_measure =
GETPOST(
'net_measure');
606 $object->net_measure_units =
GETPOST(
'net_measure_units');
607 $object->weight =
GETPOST(
'weight');
608 $object->weight_units =
GETPOST(
'weight_units');
609 $object->length =
GETPOST(
'size');
610 $object->length_units =
GETPOST(
'size_units');
611 $object->width =
GETPOST(
'sizewidth');
612 $object->height =
GETPOST(
'sizeheight');
613 $object->surface =
GETPOST(
'surface');
614 $object->surface_units =
GETPOST(
'surface_units');
615 $object->volume =
GETPOST(
'volume');
616 $object->volume_units =
GETPOST(
'volume_units');
617 $finished =
GETPOST(
'finished',
'int');
618 if ($finished >= 0) {
619 $object->finished = $finished;
621 $object->finished =
null;
624 $units =
GETPOST(
'units',
'int');
626 $object->fk_unit = $units;
628 $object->fk_unit =
null;
631 $accountancy_code_sell =
GETPOST(
'accountancy_code_sell',
'alpha');
632 $accountancy_code_sell_intra =
GETPOST(
'accountancy_code_sell_intra',
'alpha');
633 $accountancy_code_sell_export =
GETPOST(
'accountancy_code_sell_export',
'alpha');
634 $accountancy_code_buy =
GETPOST(
'accountancy_code_buy',
'alpha');
635 $accountancy_code_buy_intra =
GETPOST(
'accountancy_code_buy_intra',
'alpha');
636 $accountancy_code_buy_export =
GETPOST(
'accountancy_code_buy_export',
'alpha');
638 if (empty($accountancy_code_sell) || $accountancy_code_sell ==
'-1') {
639 $object->accountancy_code_sell =
'';
641 $object->accountancy_code_sell = $accountancy_code_sell;
643 if (empty($accountancy_code_sell_intra) || $accountancy_code_sell_intra ==
'-1') {
644 $object->accountancy_code_sell_intra =
'';
646 $object->accountancy_code_sell_intra = $accountancy_code_sell_intra;
648 if (empty($accountancy_code_sell_export) || $accountancy_code_sell_export ==
'-1') {
649 $object->accountancy_code_sell_export =
'';
651 $object->accountancy_code_sell_export = $accountancy_code_sell_export;
653 if (empty($accountancy_code_buy) || $accountancy_code_buy ==
'-1') {
654 $object->accountancy_code_buy =
'';
656 $object->accountancy_code_buy = $accountancy_code_buy;
658 if (empty($accountancy_code_buy_intra) || $accountancy_code_buy_intra ==
'-1') {
659 $object->accountancy_code_buy_intra =
'';
661 $object->accountancy_code_buy_intra = $accountancy_code_buy_intra;
663 if (empty($accountancy_code_buy_export) || $accountancy_code_buy_export ==
'-1') {
664 $object->accountancy_code_buy_export =
'';
666 $object->accountancy_code_buy_export = $accountancy_code_buy_export;
671 for ($i = 2; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) {
672 if (GETPOSTISSET(
"price_".$i)) {
674 $object->multiprices_base_type[
"$i"] =
GETPOST(
"multiprices_base_type_".$i);
676 $object->multiprices[
"$i"] =
"";
682 $ret = $extrafields->setOptionalsFromPost(
null, $object);
689 $ref = $modCodeProduct->getNextValue($object, $type);
693 $id = $object->create($user);
698 $categories =
GETPOST(
'categories',
'array');
699 $object->setCategories($categories);
701 if (!empty($backtopage)) {
702 $backtopage = preg_replace(
'/__ID__/', $object->id, $backtopage);
703 $backtopage = preg_replace(
'/--IDFORBACKTOPAGE--/', $object->id, $backtopage);
704 if (preg_match(
'/\?/', $backtopage)) {
705 $backtopage .=
'&productid='.$object->id;
708 header(
"Location: ".$backtopage);
711 header(
"Location: ".$_SERVER[
'PHP_SELF'].
"?id=".$id);
715 if (count($object->errors)) {
718 if ($object->error ==
'ErrorProductAlreadyExists') {
720 $reshook = $hookmanager->executeHooks(
'onProductAlreadyExists', $parameters, $object, $action);
724 if ($object->error) {
739 if ($action ==
'update' && $usercancreate) {
740 if (
GETPOST(
'cancel',
'alpha')) {
743 if ($object->id > 0) {
745 $object->oldcopy =
dol_clone($object, 1);
750 $object->label =
GETPOST(
'label', $label_security_check);
753 $object->description = $desc;
758 $object->note = $object->note_private;
760 $object->customcode =
GETPOST(
'customcode',
'alpha');
761 $object->country_id =
GETPOST(
'country_id',
'int');
762 $object->state_id =
GETPOST(
'state_id',
'int');
763 $object->lifetime =
GETPOST(
'lifetime',
'int');
764 $object->qc_frequency =
GETPOST(
'qc_frequency',
'int');
765 $object->status =
GETPOST(
'statut',
'int');
766 $object->status_buy =
GETPOST(
'statut_buy',
'int');
767 $object->status_batch =
GETPOST(
'status_batch',
'aZ09');
768 $object->batch_mask =
GETPOST(
'batch_mask',
'alpha');
769 $object->fk_default_warehouse =
GETPOST(
'fk_default_warehouse',
'int');
770 $object->fk_default_workstation =
GETPOST(
'fk_default_workstation',
'int');
776 $object->duration_value =
GETPOST(
'duration_value',
'int');
777 $object->duration_unit =
GETPOST(
'duration_unit',
'alpha');
779 $object->canvas =
GETPOST(
'canvas');
780 $object->net_measure =
GETPOST(
'net_measure');
781 $object->net_measure_units =
GETPOST(
'net_measure_units');
782 $object->weight =
GETPOST(
'weight');
783 $object->weight_units =
GETPOST(
'weight_units');
784 $object->length =
GETPOST(
'size');
785 $object->length_units =
GETPOST(
'size_units');
786 $object->width =
GETPOST(
'sizewidth');
787 $object->height =
GETPOST(
'sizeheight');
789 $object->surface =
GETPOST(
'surface');
790 $object->surface_units =
GETPOST(
'surface_units');
791 $object->volume =
GETPOST(
'volume');
792 $object->volume_units =
GETPOST(
'volume_units');
794 $finished =
GETPOST(
'finished',
'int');
795 if ($finished >= 0) {
796 $object->finished = $finished;
798 $object->finished =
null;
801 $fk_default_bom =
GETPOST(
'fk_default_bom',
'int');
802 if ($fk_default_bom >= 0) {
803 $object->fk_default_bom = $fk_default_bom;
805 $object->fk_default_bom =
null;
808 $units =
GETPOST(
'units',
'int');
810 $object->fk_unit = $units;
812 $object->fk_unit =
null;
815 $object->barcode_type =
GETPOST(
'fk_barcode_type');
816 $object->barcode =
GETPOST(
'barcode');
819 $stdobject->element =
'product';
820 $stdobject->barcode_type =
GETPOST(
'fk_barcode_type');
821 $result = $stdobject->fetch_barcode();
824 $mesg =
'Failed to get bar code type information ';
827 $object->barcode_type_code = $stdobject->barcode_type_code;
828 $object->barcode_type_coder = $stdobject->barcode_type_coder;
829 $object->barcode_type_label = $stdobject->barcode_type_label;
831 $accountancy_code_sell =
GETPOST(
'accountancy_code_sell',
'alpha');
832 $accountancy_code_sell_intra =
GETPOST(
'accountancy_code_sell_intra',
'alpha');
833 $accountancy_code_sell_export =
GETPOST(
'accountancy_code_sell_export',
'alpha');
834 $accountancy_code_buy =
GETPOST(
'accountancy_code_buy',
'alpha');
835 $accountancy_code_buy_intra =
GETPOST(
'accountancy_code_buy_intra',
'alpha');
836 $accountancy_code_buy_export =
GETPOST(
'accountancy_code_buy_export',
'alpha');
837 $checkmandatory =
GETPOST(
'mandatoryperiod',
'alpha');
838 if (empty($accountancy_code_sell) || $accountancy_code_sell ==
'-1') {
839 $object->accountancy_code_sell =
'';
841 $object->accountancy_code_sell = $accountancy_code_sell;
843 if (empty($accountancy_code_sell_intra) || $accountancy_code_sell_intra ==
'-1') {
844 $object->accountancy_code_sell_intra =
'';
846 $object->accountancy_code_sell_intra = $accountancy_code_sell_intra;
848 if (empty($accountancy_code_sell_export) || $accountancy_code_sell_export ==
'-1') {
849 $object->accountancy_code_sell_export =
'';
851 $object->accountancy_code_sell_export = $accountancy_code_sell_export;
853 if (empty($accountancy_code_buy) || $accountancy_code_buy ==
'-1') {
854 $object->accountancy_code_buy =
'';
856 $object->accountancy_code_buy = $accountancy_code_buy;
858 if (empty($accountancy_code_buy_intra) || $accountancy_code_buy_intra ==
'-1') {
859 $object->accountancy_code_buy_intra =
'';
861 $object->accountancy_code_buy_intra = $accountancy_code_buy_intra;
863 if (empty($accountancy_code_buy_export) || $accountancy_code_buy_export ==
'-1') {
864 $object->accountancy_code_buy_export =
'';
866 $object->accountancy_code_buy_export = $accountancy_code_buy_export;
868 if ($object->isService()) {
869 $object->mandatory_period = (!empty($checkmandatory)) ? 1 : 0 ;
875 $ret = $extrafields->setOptionalsFromPost(
null, $object,
'@GETPOSTISSET');
880 if (!$error && $object->check()) {
881 if ($object->update($object->id, $user) > 0) {
883 $categories =
GETPOST(
'categories',
'array');
884 $object->setCategories($categories);
888 if (count($object->errors)) {
896 if (count($object->errors)) {
899 setEventMessages($langs->trans(
"ErrorProductBadRefOrLabel"),
null,
'errors');
908 if ($action ==
'confirm_clone' && $confirm !=
'yes') {
911 if ($action ==
'confirm_clone' && $confirm ==
'yes' && $usercancreate) {
915 if ($object->id > 0) {
922 $clone->ref =
GETPOST(
'clone_ref',
'alphanohtml');
924 $clone->status_buy = 0;
925 $clone->barcode = -1;
927 if ($clone->check()) {
930 $clone->context[
'createfromclone'] =
'createfromclone';
931 $id = $clone->create($user);
933 if (
GETPOST(
'clone_composition')) {
934 $result = $clone->clone_associations($object->id, $id);
942 if (!$error &&
GETPOST(
'clone_categories')) {
943 $result = $clone->cloneCategories($object->id, $id);
951 if (!$error &&
GETPOST(
'clone_prices')) {
952 $result = $clone->clone_price($object->id, $id);
962 if ($clone->error ==
'ErrorProductAlreadyExists') {
966 $mesg = $langs->trans(
"ErrorProductAlreadyExists", $clone->ref);
967 $mesg .=
' <a href="' . $_SERVER[
"PHP_SELF"] .
'?ref=' . $clone->ref .
'">' . $langs->trans(
"ShowCardHere") .
'</a>.';
970 if (count($clone->errors)) {
981 unset($clone->context[
'createfromclone']);
988 header(
"Location: " . $_SERVER[
"PHP_SELF"] .
"?id=" . $id);
992 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"NewRefForClone")),
null,
'errors');
1002 if ($action ==
'confirm_delete' && $confirm !=
'yes') {
1005 if ($action ==
'confirm_delete' && $confirm ==
'yes' && $usercandelete) {
1006 $result = $object->delete($user);
1009 header(
'Location: '.DOL_URL_ROOT.
'/product/list.php?type='.$object->type.
'&delprod='.urlencode($object->ref));
1020 if ($object->id > 0 && $action ==
'addin') {
1022 if (
GETPOST(
'propalid') > 0) {
1023 $propal =
new Propal($db);
1024 $result = $propal->fetch(
GETPOST(
'propalid'));
1029 $thirpdartyid = $propal->socid;
1030 } elseif (
GETPOST(
'commandeid') > 0) {
1032 $result = $commande->fetch(
GETPOST(
'commandeid'));
1037 $thirpdartyid = $commande->socid;
1038 } elseif (
GETPOST(
'factureid') > 0) {
1040 $result = $facture->fetch(
GETPOST(
'factureid'));
1045 $thirpdartyid = $facture->socid;
1048 if ($thirpdartyid > 0) {
1050 $result = $soc->fetch($thirpdartyid);
1056 $desc = $object->description;
1060 if (empty($tva_tx)) {
1063 $localtax1_tx =
get_localtax($tva_tx, 1, $soc, $mysoc, $tva_npr);
1064 $localtax2_tx =
get_localtax($tva_tx, 2, $soc, $mysoc, $tva_npr);
1066 $pu_ht = $object->price;
1067 $pu_ttc = $object->price_ttc;
1068 $price_base_type = $object->price_base_type;
1071 if ($conf->global->PRODUIT_MULTIPRICES && $soc->price_level) {
1072 $pu_ht = $object->multiprices[$soc->price_level];
1073 $pu_ttc = $object->multiprices_ttc[$soc->price_level];
1074 $price_base_type = $object->multiprices_base_type[$soc->price_level];
1076 require_once DOL_DOCUMENT_ROOT.
'/product/class/productcustomerprice.class.php';
1080 $filter = array(
't.fk_product' => $object->id,
't.fk_soc' => $soc->id);
1082 $result = $prodcustprice->fetchAll(
'',
'', 0, 0, $filter);
1084 if (count($prodcustprice->lines) > 0) {
1085 $pu_ht =
price($prodcustprice->lines [0]->price);
1086 $pu_ttc =
price($prodcustprice->lines [0]->price_ttc);
1087 $price_base_type = $prodcustprice->lines [0]->price_base_type;
1088 $tva_tx = $prodcustprice->lines [0]->tva_tx;
1093 $tmpvat =
price2num(preg_replace(
'/\s*\(.*\)/',
'', $tva_tx));
1094 $tmpprodvat =
price2num(preg_replace(
'/\s*\(.*\)/',
'', $prod->tva_tx));
1098 if ($tmpvat != $tmpprodvat) {
1099 if ($price_base_type !=
'HT') {
1100 $pu_ht =
price2num($pu_ttc / (1 + ($tmpvat / 100)),
'MU');
1102 $pu_ttc =
price2num($pu_ht * (1 + ($tmpvat / 100)),
'MU');
1106 if (
GETPOST(
'propalid') > 0) {
1109 if (($result = $propal->defineBuyPrice($pu_ht,
price2num(
GETPOST(
'remise_percent'),
'', 2), $object->id)) < 0) {
1110 dol_syslog($langs->trans(
'FailedToGetCostPrice'));
1113 $buyprice = $result;
1116 $result = $propal->addline(
1141 header(
"Location: ".DOL_URL_ROOT.
"/comm/propal/card.php?id=".$propal->id);
1145 setEventMessages($langs->trans(
"ErrorUnknown").
": $result",
null,
'errors');
1146 } elseif (
GETPOST(
'commandeid') > 0) {
1149 if (($result = $commande->defineBuyPrice($pu_ht,
price2num(
GETPOST(
'remise_percent'),
'', 2), $object->id)) < 0) {
1150 dol_syslog($langs->trans(
'FailedToGetCostPrice'));
1153 $buyprice = $result;
1156 $result = $commande->addline(
1183 header(
"Location: ".DOL_URL_ROOT.
"/commande/card.php?id=".urlencode($commande->id));
1186 } elseif (
GETPOST(
'factureid') > 0) {
1189 if (($result = $facture->defineBuyPrice($pu_ht,
price2num(
GETPOST(
'remise_percent'),
'', 2), $object->id)) < 0) {
1190 dol_syslog($langs->trans(
'FailedToGetCostPrice'));
1193 $buyprice = $result;
1196 $result = $facture->addline(
1228 header(
"Location: ".DOL_URL_ROOT.
"/compta/facture/card.php?facid=".$facture->id);
1234 setEventMessages($langs->trans(
"WarningSelectOneDocument"),
null,
'warnings');
1245$form =
new Form($db);
1249if (isModEnabled(
'accounting')) {
1254$title = $langs->trans(
'ProductServiceCard');
1257$shortlabel =
dol_trunc($object->label, 16);
1259 if ($action ==
'create') {
1260 $title = $langs->trans(
"NewProduct");
1262 $title = $langs->trans(
'Product').
" ".$shortlabel.
" - ".$langs->trans(
'Card');
1263 $help_url =
'EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos|DE:Modul_Produkte';
1267 if ($action ==
'create') {
1268 $title = $langs->trans(
"NewService");
1270 $title = $langs->trans(
'Service').
" ".$shortlabel.
" - ".$langs->trans(
'Card');
1271 $help_url =
'EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios|DE:Modul_Leistungen';
1280 $module = strtolower($conf->global->BARCODE_PRODUCT_ADDON_NUM);
1281 $dirbarcode = array_merge(array(
'/core/modules/barcode/'), $conf->modules_parts[
'barcode']);
1282 foreach ($dirbarcode as $dirroot) {
1289 $modBarCodeProduct =
new $module();
1293$canvasdisplayaction = $action;
1294if (in_array($canvasdisplayaction, array(
'merge',
'confirm_merge'))) {
1295 $canvasdisplayaction =
'view';
1298if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayaction)) {
1302 $objcanvas->assign_values($canvasdisplayaction, $object->id, $object->ref);
1303 $objcanvas->display_canvas($canvasdisplayaction);
1308 if ($action ==
'create' && $usercancreate) {
1310 require_once DOL_DOCUMENT_ROOT.
'/core/class/doleditor.class.php';
1312 if (!empty($conf->use_javascript_ajax)) {
1313 print
'<script type="text/javascript">';
1314 print
'$(document).ready(function () {
1315 $("#selectcountry_id").change(function() {
1316 document.formprod.action.value="create";
1317 document.formprod.submit();
1320 print
'</script>'.
"\n";
1324 $module = (
getDolGlobalString(
'PRODUCT_CODEPRODUCT_ADDON') ? $conf->global->PRODUCT_CODEPRODUCT_ADDON :
'mod_codeproduct_leopard');
1325 if (substr($module, 0, 16) ==
'mod_codeproduct_' && substr($module, -3) ==
'php') {
1326 $module = substr($module, 0,
dol_strlen($module) - 4);
1330 $modCodeProduct =
new $module();
1335 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'" method="POST" name="formprod">';
1336 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1337 print
'<input type="hidden" name="action" value="add">';
1338 print
'<input type="hidden" name="type" value="'.$type.
'">'.
"\n";
1339 if (!empty($modCodeProduct->code_auto)) {
1340 print
'<input type="hidden" name="code_auto" value="1">';
1342 if (!empty($modBarCodeProduct->code_auto)) {
1343 print
'<input type="hidden" name="barcode_auto" value="1">';
1345 print
'<input type="hidden" name="backtopage" value="'.$backtopage.
'">';
1349 $title = $langs->trans(
"NewService");
1352 $title = $langs->trans(
"NewProduct");
1358 $object->country_id = GETPOSTISSET(
'country_id') ?
GETPOST(
'country_id',
'int') : null;
1359 if ($object->country_id > 0) {
1360 $tmparray =
getCountry($object->country_id,
'all');
1361 $object->country_code = $tmparray[
'code'];
1362 $object->country = $tmparray[
'label'];
1368 $parameters = array();
1370 $reshook = $hookmanager->executeHooks(
'tabContentCreateProduct', $parameters, $object, $action);
1371 if (empty($reshook)) {
1372 print
'<table class="border centpercent">';
1377 if (!empty($modCodeProduct->code_auto)) {
1378 $tmpcode = $modCodeProduct->getNextValue($object, $type);
1380 print
'<td class="titlefieldcreate fieldrequired">'.$langs->trans(
"ProductRef").
'</td><td><input id="ref" name="ref" class="maxwidth200" maxlength="128" value="'.
dol_escape_htmltag(GETPOSTISSET(
'ref') ?
GETPOST(
'ref',
'alphanohtml') : $tmpcode).
'">';
1381 if ($refalreadyexists) {
1382 print $langs->trans(
"RefAlreadyExists");
1388 print
'<tr><td class="fieldrequired">'.$langs->trans(
"Label").
'</td><td><input name="label" class="minwidth300 maxwidth400onsmartphone" maxlength="255" value="'.
dol_escape_htmltag(
GETPOST(
'label', $label_security_check)).
'"></td></tr>';
1391 print
'<tr><td class="fieldrequired">'.$langs->trans(
"Status").
' ('.$langs->trans(
"Sell").
')</td><td>';
1392 $statutarray = array(
'1' => $langs->trans(
"OnSell"),
'0' => $langs->trans(
"NotOnSell"));
1393 print $form->selectarray(
'statut', $statutarray,
GETPOST(
'statut'));
1397 print
'<tr><td class="fieldrequired">'.$langs->trans(
"Status").
' ('.$langs->trans(
"Buy").
')</td><td>';
1398 $statutarray = array(
'1' => $langs->trans(
"ProductStatusOnBuy"),
'0' => $langs->trans(
"ProductStatusNotOnBuy"));
1399 print $form->selectarray(
'statut_buy', $statutarray,
GETPOST(
'statut_buy'));
1403 if (isModEnabled(
'productbatch')) {
1404 print
'<tr><td>'.$langs->trans(
"ManageLotSerial").
'</td><td>';
1405 $statutarray = array(
'0' => $langs->trans(
"ProductStatusNotOnBatch"),
'1' => $langs->trans(
"ProductStatusOnBatch"),
'2' => $langs->trans(
"ProductStatusOnSerial"));
1406 print $form->selectarray(
'status_batch', $statutarray,
GETPOST(
'status_batch'));
1409 $status_batch =
GETPOST(
'status_batch');
1410 if ($status_batch !==
'0') {
1411 $langs->load(
"admin");
1412 $tooltip = $langs->trans(
"GenericMaskCodes", $langs->transnoentities(
"Batch"), $langs->transnoentities(
"Batch"));
1413 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes2");
1414 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes3");
1415 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes4a", $langs->transnoentities(
"Batch"), $langs->transnoentities(
"Batch"));
1416 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes5");
1419 print
'<tr><td id="mask_option">'.$langs->trans(
"ManageLotMask").
'</td>';
1422 print
'<td id="field_mask">';
1423 print $form->textwithpicto(
'<input type="text" class="flat minwidth175" name="batch_mask" id="batch_mask_input">', $tooltip, 1, 1);
1424 print
'<script type="text/javascript">
1425 $(document).ready(function() {
1426 $("#field_mask, #mask_option").addClass("hideobject");
1427 $("#status_batch").on("change", function () {
1428 console.log("We change batch status");
1429 var optionSelected = $("option:selected", this);
1430 var valueSelected = this.value;
1431 $("#field_mask, #mask_option").addClass("hideobject");
1435 if (this.value == 1) {
1436 $("#field_mask, #mask_option").toggleClass("hideobject");
1437 $("#batch_mask_input").val("'.$inherited_mask_lot.
'");
1441 if (isset($conf->global->PRODUCTBATCH_SN_USE_PRODUCT_MASKS) &&
getDolGlobalString(
'PRODUCTBATCH_SN_ADDON') ==
'mod_sn_advanced') {
1443 if (this.value == 2) {
1444 $("#field_mask, #mask_option").toggleClass("hideobject");
1445 $("#batch_mask_input").val("'.$inherited_mask_sn.
'");
1458 $showbarcode = isModEnabled(
'barcode');
1459 if (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && !$user->hasRight(
'barcode',
'lire_advance')) {
1464 print
'<tr><td>'.$langs->trans(
'BarcodeType').
'</td><td>';
1465 if (GETPOSTISSET(
'fk_barcode_type')) {
1466 $fk_barcode_type =
GETPOST(
'fk_barcode_type') ?
GETPOST(
'fk_barcode_type') : 0;
1474 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formbarcode.class.php';
1476 print $formbarcode->selectBarcodeType($fk_barcode_type,
'fk_barcode_type', 1);
1479 print
'<td>'.$langs->trans(
"BarcodeValue").
'</td><td>';
1480 $tmpcode = GETPOSTISSET(
'barcode') ?
GETPOST(
'barcode') : $object->barcode;
1481 if (empty($tmpcode) && !empty($modBarCodeProduct->code_auto)) {
1482 $tmpcode = $modBarCodeProduct->getNextValue($object, $fk_barcode_type);
1484 print
img_picto(
'',
'barcode',
'class="pictofixedwidth"');
1485 print
'<input class="maxwidth100" type="text" name="barcode" value="'.dol_escape_htmltag($tmpcode).
'">';
1490 print
'<tr><td class="tdtop">'.$langs->trans(
"Description").
'</td><td>';
1491 $doleditor =
new DolEditor(
'desc',
GETPOST(
'desc',
'restricthtml'),
'', 160,
'dolibarr_details',
'',
false,
true,
getDolGlobalString(
'FCKEDITOR_ENABLE_DETAILS'), ROWS_4,
'90%');
1492 $doleditor->Create();
1497 print
'<tr><td>'.$langs->trans(
"PublicUrl").
'</td><td>';
1498 print
img_picto(
'',
'globe',
'class="pictofixedwidth"');
1499 print
'<input type="text" name="url" class="quatrevingtpercent" value="'.GETPOST(
'url').
'">';
1503 if (($type != 1 ||
getDolGlobalInt(
'STOCK_SUPPORTS_SERVICES')) && isModEnabled(
'stock')) {
1505 print
'<tr><td>'.$langs->trans(
"DefaultWarehouse").
'</td><td>';
1506 print
img_picto($langs->trans(
"DefaultWarehouse"),
'stock',
'class="pictofixedwidth"');
1507 print $formproduct->selectWarehouses(
GETPOST(
'fk_default_warehouse',
'int'),
'fk_default_warehouse',
'warehouseopen', 1, 0, 0,
'', 0, 0, array(),
'minwidth300 widthcentpercentminusxx maxwidth500');
1508 print
' <a href="'.DOL_URL_ROOT.
'/product/stock/card.php?action=create&token='.newToken().
'&backtopage='.urlencode($_SERVER[
'PHP_SELF'].
'?&action=create&type='.
GETPOST(
'type',
'int')).
'">';
1509 print
'<span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans(
"AddWarehouse").
'"></span>';
1517 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"StockLimit"), $langs->trans(
"StockLimitDesc"), 1).
'</td><td>';
1518 print
'<input name="seuil_stock_alerte" class="maxwidth50" value="'.GETPOST(
'seuil_stock_alerte').
'">';
1523 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"DesiredStock"), $langs->trans(
"DesiredStockDesc"), 1).
'</td><td>';
1524 print
'<input name="desiredstock" class="maxwidth50" value="'.GETPOST(
'desiredstock').
'">';
1529 print
'<input name="seuil_stock_alerte" type="hidden" value="0">';
1530 print
'<input name="desiredstock" type="hidden" value="0">';
1534 if ($type == $object::TYPE_SERVICE && isModEnabled(
"workstation")) {
1536 print
'<tr><td>'.$langs->trans(
"DefaultWorkstation").
'</td><td>';
1537 print
img_picto($langs->trans(
"DefaultWorkstation"),
'workstation',
'class="pictofixedwidth"');
1538 print $formproduct->selectWorkstations($object->fk_default_workstation,
'fk_default_workstation', 1);
1544 print
'<tr><td>'.$langs->trans(
"Duration").
'</td><td>';
1545 print
img_picto(
'',
'clock',
'class="pictofixedwidth"');
1546 print
'<input name="duration_value" size="4" value="'.GETPOST(
'duration_value',
'int').
'">';
1547 print $formproduct->selectMeasuringUnits(
"duration_unit",
"time", (GETPOSTISSET(
'duration_unit') ?
GETPOST(
'duration_unit',
'alpha') :
'h'), 0, 1);
1550 print
' ';
1551 print
'<input type="checkbox" id="mandatoryperiod" name="mandatoryperiod"'.($object->mandatory_period == 1 ?
' checked="checked"' :
'').
'>';
1552 print
'<label for="mandatoryperiod">';
1553 $htmltooltip = $langs->trans(
"mandatoryHelper");
1554 print $form->textwithpicto($langs->trans(
"mandatoryperiod"), $htmltooltip, 1, 0);
1563 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"NatureOfProductShort"), $langs->trans(
"NatureOfProductDesc")).
'</td><td>';
1564 print $formproduct->selectProductNature(
'finished', $object->finished);
1572 print
'<tr><td>'.$langs->trans(
"Weight").
'</td><td>';
1573 print
img_picto(
'',
'fa-balance-scale',
'class="pictofixedwidth"');
1574 print
'<input name="weight" size="4" value="'.GETPOST(
'weight').
'">';
1575 print $formproduct->selectMeasuringUnits(
"weight_units",
"weight", GETPOSTISSET(
'weight_units') ?
GETPOST(
'weight_units',
'alpha') : (!
getDolGlobalString(
'MAIN_WEIGHT_DEFAULT_UNIT') ? 0 : $conf->global->MAIN_WEIGHT_DEFAULT_UNIT), 0, 2);
1581 print
'<tr><td>'.$langs->trans(
"Length").
' x '.$langs->trans(
"Width").
' x '.$langs->trans(
"Height").
'</td><td>';
1582 print
img_picto(
'',
'fa-ruler',
'class="pictofixedwidth"');
1583 print
'<input name="size" class="width50" value="'.GETPOST(
'size').
'"> x ';
1584 print
'<input name="sizewidth" class="width50" value="'.GETPOST(
'sizewidth').
'"> x ';
1585 print
'<input name="sizeheight" class="width50" value="'.GETPOST(
'sizeheight').
'">';
1586 print $formproduct->selectMeasuringUnits(
"size_units",
"size", GETPOSTISSET(
'size_units') ?
GETPOST(
'size_units',
'alpha') :
'0', 0, 2);
1591 print
'<tr><td>'.$langs->trans(
"Surface").
'</td><td>';
1592 print
'<input name="surface" size="4" value="'.GETPOST(
'surface').
'">';
1593 print $formproduct->selectMeasuringUnits(
"surface_units",
"surface", GETPOSTISSET(
'surface_units') ?
GETPOST(
'surface_units',
'alpha') :
'0', 0, 2);
1598 print
'<tr><td>'.$langs->trans(
"Volume").
'</td><td>';
1599 print
'<input name="volume" size="4" value="'.GETPOST(
'volume').
'">';
1600 print $formproduct->selectMeasuringUnits(
"volume_units",
"volume", GETPOSTISSET(
'volume_units') ?
GETPOST(
'volume_units',
'alpha') :
'0', 0, 2);
1606 print
'<tr><td>'.$langs->trans(
"NetMeasure").
'</td><td>';
1607 print
'<input name="net_measure" size="4" value="'.GETPOST(
'net_measure').
'">';
1608 print $formproduct->selectMeasuringUnits(
"net_measure_units",
'', GETPOSTISSET(
'net_measure_units') ?
GETPOST(
'net_measure_units',
'alpha') : (!
getDolGlobalString(
'MAIN_WEIGHT_DEFAULT_UNIT') ? 0 : $conf->global->MAIN_WEIGHT_DEFAULT_UNIT), 0, 0);
1615 print
'<tr><td>'.$langs->trans(
'DefaultUnitToShow').
'</td>';
1617 print $form->selectUnits(empty($line->fk_unit) ? $conf->global->PRODUCT_USE_UNITS : $line->fk_unit,
'units');
1623 print
'<tr><td class="wordbreak">'.$langs->trans(
"CustomCode").
'</td><td><input name="customcode" class="maxwidth100onsmartphone" value="'.
GETPOST(
'customcode').
'"></td></tr>';
1626 print
'<tr><td>'.$langs->trans(
"CountryOrigin").
'</td>';
1628 print
img_picto(
'',
'globe-americas',
'class="pictofixedwidth"');
1629 print $form->select_country((GETPOSTISSET(
'country_id') ?
GETPOST(
'country_id') : $object->country_id),
'country_id',
'', 0,
'minwidth300 widthcentpercentminusx maxwidth500');
1631 print
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1639 print
'<td>'.$form->editfieldkey(
'RegionStateOrigin',
'state_id',
'', $object, 0).
'</td><td>';
1641 print
'<td>'.$form->editfieldkey(
'StateOrigin',
'state_id',
'', $object, 0).
'</td><td>';
1644 print
img_picto(
'',
'state',
'class="pictofixedwidth"');
1645 print $formcompany->select_state($object->state_id, $object->country_code);
1652 print
'<tr><td>'.$langs->trans(
"LifeTime").
'</td><td><input name="lifetime" class="maxwidth50" value="'.
GETPOST(
'lifetime').
'"></td></tr>';
1653 print
'<tr><td>'.$langs->trans(
"QCFrequency").
'</td><td><input name="qc_frequency" class="maxwidth50" value="'.
GETPOST(
'qc_frequency').
'"></td></tr>';
1657 $parameters = array(
'colspan' =>
' colspan="2"',
'cols'=>2);
1658 $reshook = $hookmanager->executeHooks(
'formObjectOptions', $parameters, $object, $action);
1659 print $hookmanager->resPrint;
1660 if (empty($reshook)) {
1661 print $object->showOptionals($extrafields,
'create', $parameters);
1667 print
'<tr><td class="tdtop">'.$langs->trans(
"NoteNotVisibleOnBill").
'</td><td>';
1670 $doleditor =
new DolEditor(
'note_private',
GETPOST(
'note_private',
'restricthtml'),
'', 140,
'dolibarr_details',
'',
false,
true,
getDolGlobalString(
'FCKEDITOR_ENABLE_NOTE_PRIVATE'), ROWS_8,
'90%');
1671 $doleditor->Create();
1676 if (isModEnabled(
'categorie')) {
1678 print
'<tr><td>'.$langs->trans(
"Categories").
'</td><td>';
1679 $cate_arbo = $form->select_all_categories(Categorie::TYPE_PRODUCT,
'',
'parent', 64, 0, 1);
1680 print
img_picto(
'',
'category',
'class="pictofixedwidth"').$form->multiselectarray(
'categories', $cate_arbo,
GETPOST(
'categories',
'array'),
'', 0,
'quatrevingtpercent widthcentpercentminusx', 0, 0);
1692 print
'<table class="border centpercent">';
1694 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"VATRate").
'</td><td>';
1696 print $form->load_tva(
"tva_tx", $defaultva, $mysoc, $mysoc, 0, 0,
'',
false, 1);
1703 print
'<table class="border centpercent">';
1706 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"SellingPrice").
'</td>';
1707 print
'<td><input name="price" class="maxwidth50" value="'.$object->price.
'">';
1708 print $form->selectPriceBaseType($conf->global->PRODUCT_PRICE_BASE_TYPE,
"price_base_type");
1712 print
'<tr><td>'.$langs->trans(
"MinPrice").
'</td>';
1713 print
'<td><input name="price_min" class="maxwidth50" value="'.$object->price_min.
'">';
1717 print
'<tr><td>'.$langs->trans(
"VATRate").
'</td><td>';
1719 print $form->load_tva(
"tva_tx", $defaultva, $mysoc, $mysoc, 0, 0,
'',
false, 1);
1729 print
'<!-- accountancy codes -->'.
"\n";
1730 print
'<table class="border centpercent">';
1733 if (isModEnabled(
'accounting')) {
1735 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellCode").
'</td>';
1738 $accountancy_code_sell = (GETPOSTISSET(
'accountancy_code_sell') ?
GETPOST(
'accountancy_code_sell',
'alpha') :
getDolGlobalString(
"ACCOUNTING_PRODUCT_SOLD_ACCOUNT"));
1740 $accountancy_code_sell = (GETPOSTISSET(
'accountancy_code_sell') ?
GETPOST(
'accountancy_code_sell',
'alpha') :
getDolGlobalString(
"ACCOUNTING_SERVICE_SOLD_ACCOUNT"));
1742 print $formaccounting->select_account($accountancy_code_sell,
'accountancy_code_sell', 1,
null, 1, 1,
'minwidth150 maxwidth300', 1);
1746 if ($mysoc->isInEEC()) {
1747 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellIntraCode").
'</td>';
1750 $accountancy_code_sell_intra = (GETPOSTISSET(
'accountancy_code_sell_intra') ?
GETPOST(
'accountancy_code_sell_intra',
'alpha') :
getDolGlobalString(
"ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT"));
1752 $accountancy_code_sell_intra = (GETPOSTISSET(
'accountancy_code_sell_intra') ?
GETPOST(
'accountancy_code_sell_intra',
'alpha') :
getDolGlobalString(
"ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT"));
1754 print $formaccounting->select_account($accountancy_code_sell_intra,
'accountancy_code_sell_intra', 1,
null, 1, 1,
'minwidth150 maxwidth300', 1);
1759 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellExportCode").
'</td>';
1762 $accountancy_code_sell_export = (
GETPOST(
'accountancy_code_sell_export') ?
GETPOST(
'accountancy_code_sell_export',
'alpha') :
getDolGlobalString(
"ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT"));
1764 $accountancy_code_sell_export = (
GETPOST(
'accountancy_code_sell_export') ?
GETPOST(
'accountancy_code_sell_export',
'alpha') :
getDolGlobalString(
"ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT"));
1766 print $formaccounting->select_account($accountancy_code_sell_export,
'accountancy_code_sell_export', 1,
null, 1, 1,
'minwidth150 maxwidth300', 1);
1770 print
'<tr><td>'.$langs->trans(
"ProductAccountancyBuyCode").
'</td>';
1773 $accountancy_code_buy = (
GETPOST(
'accountancy_code_buy',
'alpha') ? (
GETPOST(
'accountancy_code_buy',
'alpha')) :
getDolGlobalString(
"ACCOUNTING_PRODUCT_BUY_ACCOUNT"));
1775 $accountancy_code_buy = (
GETPOST(
'accountancy_code_buy',
'alpha') ? (
GETPOST(
'accountancy_code_buy',
'alpha')) :
getDolGlobalString(
"ACCOUNTING_SERVICE_BUY_ACCOUNT"));
1777 print $formaccounting->select_account($accountancy_code_buy,
'accountancy_code_buy', 1,
null, 1, 1,
'minwidth150 maxwidth300', 1);
1781 if ($mysoc->isInEEC()) {
1782 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyIntraCode").
'</td>';
1785 $accountancy_code_buy_intra = (GETPOSTISSET(
'accountancy_code_buy_intra') ?
GETPOST(
'accountancy_code_buy_intra',
'alpha') :
getDolGlobalString(
"ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT"));
1787 $accountancy_code_buy_intra = (GETPOSTISSET(
'accountancy_code_buy_intra') ?
GETPOST(
'accountancy_code_buy_intra',
'alpha') :
getDolGlobalString(
"ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT"));
1789 print $formaccounting->select_account($accountancy_code_buy_intra,
'accountancy_code_buy_intra', 1,
null, 1, 1,
'minwidth150 maxwidth300', 1);
1794 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyExportCode").
'</td>';
1797 $accountancy_code_buy_export = (
GETPOST(
'accountancy_code_buy_export') ?
GETPOST(
'accountancy_code_buy_export',
'alpha') :
getDolGlobalString(
"ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT"));
1799 $accountancy_code_buy_export = (
GETPOST(
'accountancy_code_buy_export') ?
GETPOST(
'accountancy_code_buy_export',
'alpha') :
getDolGlobalString(
"ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT"));
1801 print $formaccounting->select_account($accountancy_code_buy_export,
'accountancy_code_buy_export', 1,
null, 1, 1,
'minwidth150 maxwidth300', 1);
1804 if (!empty($accountancy_code_sell)) {
1805 $object->accountancy_code_sell = $accountancy_code_sell;
1807 if (!empty($accountancy_code_sell_intra)) {
1808 $object->accountancy_code_sell_intra = $accountancy_code_sell_intra;
1810 if (!empty($accountancy_code_sell_export)) {
1811 $object->accountancy_code_sell_export = $accountancy_code_sell_export;
1813 if (!empty($accountancy_code_buy)) {
1814 $object->accountancy_code_buy = $accountancy_code_buy;
1816 if (!empty($accountancy_code_buy_intra)) {
1817 $object->accountancy_code_buy_intra = $accountancy_code_buy_intra;
1819 if (!empty($accountancy_code_buy_export)) {
1820 $object->accountancy_code_buy_export = $accountancy_code_buy_export;
1824 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellCode").
'</td>';
1825 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_sell" value="'.$object->accountancy_code_sell.
'">';
1829 if ($mysoc->isInEEC()) {
1830 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellIntraCode").
'</td>';
1831 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_sell_intra" value="'.$object->accountancy_code_sell_intra.
'">';
1836 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellExportCode").
'</td>';
1837 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_sell_export" value="'.$object->accountancy_code_sell_export.
'">';
1841 print
'<tr><td>'.$langs->trans(
"ProductAccountancyBuyCode").
'</td>';
1842 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_buy" value="'.$object->accountancy_code_buy.
'">';
1846 if ($mysoc->isInEEC()) {
1847 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyIntraCode").
'</td>';
1848 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_buy_intra" value="'.$object->accountancy_code_buy_intra.
'">';
1853 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyExportCode").
'</td>';
1854 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_buy_export" value="'.$object->accountancy_code_buy_export.
'">';
1863 print $form->buttonsSaveCancel(
"Create");
1866 } elseif ($object->id > 0) {
1872 if ($action ==
'edit' && $usercancreate) {
1874 require_once DOL_DOCUMENT_ROOT.
'/core/class/doleditor.class.php';
1876 if (!empty($conf->use_javascript_ajax)) {
1877 print
'<script type="text/javascript">';
1878 print
'$(document).ready(function () {
1879 $("#selectcountry_id").change(function () {
1880 document.formprod.action.value="edit";
1881 document.formprod.submit();
1884 print
'</script>'.
"\n";
1888 $object->country_id =
GETPOST(
'country_id') ?
GETPOST(
'country_id') : $object->country_id;
1889 if ($object->country_id) {
1890 $tmparray =
getCountry($object->country_id,
'all');
1891 $object->country_code = $tmparray[
'code'];
1892 $object->country = $tmparray[
'label'];
1895 $type = $langs->trans(
'Product');
1896 if ($object->isService()) {
1897 $type = $langs->trans(
'Service');
1902 print
'<form action="'.$_SERVER[
'PHP_SELF'].
'?id='.$object->id.
'" method="POST" name="formprod">'.
"\n";
1903 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1904 print
'<input type="hidden" name="action" value="update">';
1905 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
1906 print
'<input type="hidden" name="canvas" value="'.$object->canvas.
'">';
1909 $titre = $langs->trans(
"CardProduct".$object->type);
1914 $parameters = array();
1916 $reshook = $hookmanager->executeHooks(
'tabContentEditProduct', $parameters, $object, $action);
1918 if (empty($reshook)) {
1919 print
'<table class="border allwidth">';
1923 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>';
1925 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>';
1929 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>';
1932 print
'<tr><td class="fieldrequired">'.$langs->trans(
"Status").
' ('.$langs->trans(
"Sell").
')</td><td colspan="3">';
1933 print
'<select class="flat" name="statut">';
1934 if ((GETPOSTISSET(
'statut') &&
GETPOST(
'statut')) || (!GETPOSTISSET(
'statut') && $object->status)) {
1935 print
'<option value="1" selected>'.$langs->trans(
"OnSell").
'</option>';
1936 print
'<option value="0">'.$langs->trans(
"NotOnSell").
'</option>';
1938 print
'<option value="1">'.$langs->trans(
"OnSell").
'</option>';
1939 print
'<option value="0" selected>'.$langs->trans(
"NotOnSell").
'</option>';
1945 print
'<tr><td class="fieldrequired">'.$langs->trans(
"Status").
' ('.$langs->trans(
"Buy").
')</td><td colspan="3">';
1946 print
'<select class="flat" name="statut_buy">';
1947 if ((GETPOSTISSET(
'statut_buy') &&
GETPOST(
'statut_buy')) || (!GETPOSTISSET(
'statut_buy') && $object->status_buy)) {
1948 print
'<option value="1" selected>'.$langs->trans(
"ProductStatusOnBuy").
'</option>';
1949 print
'<option value="0">'.$langs->trans(
"ProductStatusNotOnBuy").
'</option>';
1951 print
'<option value="1">'.$langs->trans(
"ProductStatusOnBuy").
'</option>';
1952 print
'<option value="0" selected>'.$langs->trans(
"ProductStatusNotOnBuy").
'</option>';
1958 if (isModEnabled(
'productbatch')) {
1960 print
'<tr><td>'.$langs->trans(
"ManageLotSerial").
'</td><td>';
1961 $statutarray = array(
'0' => $langs->trans(
"ProductStatusNotOnBatch"),
'1' => $langs->trans(
"ProductStatusOnBatch"),
'2' => $langs->trans(
"ProductStatusOnSerial"));
1963 print $form->selectarray(
'status_batch', $statutarray, GETPOSTISSET(
'status_batch') ?
GETPOST(
'status_batch') : $object->status_batch);
1965 print
'<span id="statusBatchWarning" class="warning" style="display: none;">';
1966 print
img_warning().
' '.$langs->trans(
"WarningConvertFromBatchToSerial").
'</span>';
1968 print
'<span id="statusBatchMouvToGlobal" class="warning" style="display: none;">';
1969 print
img_warning().
' '.$langs->trans(
"WarningTransferBatchStockMouvToGlobal").
'</span>';
1971 if ($object->status_batch) {
1973 print
'<script type="text/javascript">
1974 $(document).ready(function() {
1975 console.log($("#statusBatchWarning"))
1976 $("#status_batch").on("change", function() {
1977 if ($("#status_batch")[0].value == 0){
1978 $("#statusBatchMouvToGlobal").show()
1980 $("#statusBatchMouvToGlobal").hide()
1986 if ($object->status_batch == 1) {
1987 print
'<script type="text/javascript">
1988 $(document).ready(function() {
1989 console.log($("#statusBatchWarning"))
1990 $("#status_batch").on("change", function() {
1991 if ($("#status_batch")[0].value == 2){
1992 $("#statusBatchWarning").show()
1994 $("#statusBatchWarning").hide()
2002 if (!empty($object->status_batch) || !empty($conf->use_javascript_ajax)) {
2003 $langs->load(
"admin");
2004 $tooltip = $langs->trans(
"GenericMaskCodes", $langs->transnoentities(
"Batch"), $langs->transnoentities(
"Batch"));
2005 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes2");
2006 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes3");
2007 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes4a", $langs->transnoentities(
"Batch"), $langs->transnoentities(
"Batch"));
2008 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes5");
2009 print
'<tr><td id="mask_option">'.$langs->trans(
"ManageLotMask").
'</td>';
2012 $mask = !empty($object->batch_mask) ? $object->batch_mask :
getDolGlobalString(
'LOT_ADVANCED_MASK');
2015 $mask = !empty($object->batch_mask) ? $object->batch_mask :
getDolGlobalString(
'SN_ADVANCED_MASK');
2019 print
'<td id="field_mask">';
2020 print $form->textwithpicto(
'<input type="text" class="flat minwidth175" name="batch_mask" id="batch_mask_input" value="'.$mask.
'">', $tooltip, 1, 1);
2022 if (!empty($conf->use_javascript_ajax)) {
2023 print
'<script type="text/javascript">
2024 $(document).ready(function() {
2025 $("#field_mask").parent().addClass("hideobject");
2026 var preselect = document.getElementById("status_batch");';
2028 print
'if (preselect.value == "2") {
2029 $("#field_mask").parent().removeClass("hideobject");
2033 print
'if (preselect.value == "1") {
2034 $("#field_mask").parent().removeClass("hideobject");
2037 print
'$("#status_batch").on("change", function () {
2038 var optionSelected = $("option:selected", this);
2039 var valueSelected = this.value;
2040 $("#field_mask").parent().addClass("hideobject");
2044 if (this.value == 1) {
2045 $("#field_mask").parent().removeClass("hideobject");
2046 $("#batch_mask_input").val("'.$inherited_mask_lot.
'");
2052 if (this.value == 2) {
2053 $("#field_mask").parent().removeClass("hideobject");
2054 $("#batch_mask_input").val("'.$inherited_mask_sn.
'");
2069 $showbarcode = isModEnabled(
'barcode');
2070 if (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && !$user->hasRight(
'barcode',
'lire_advance')) {
2075 print
'<tr><td>'.$langs->trans(
'BarcodeType').
'</td><td>';
2076 if (GETPOSTISSET(
'fk_barcode_type')) {
2077 $fk_barcode_type =
GETPOST(
'fk_barcode_type');
2079 $fk_barcode_type = $object->barcode_type;
2081 $fk_barcode_type = $conf->global->PRODUIT_DEFAULT_BARCODE_TYPE;
2084 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formbarcode.class.php';
2086 print $formbarcode->selectBarcodeType($fk_barcode_type,
'fk_barcode_type', 1);
2088 print
'<tr><td>'.$langs->trans(
"BarcodeValue").
'</td><td>';
2089 $tmpcode = GETPOSTISSET(
'barcode') ?
GETPOST(
'barcode') : $object->barcode;
2090 if (empty($tmpcode) && !empty($modBarCodeProduct->code_auto)) {
2091 $tmpcode = $modBarCodeProduct->getNextValue($object, $fk_barcode_type);
2093 print
'<input class="maxwidth150 maxwidthonsmartphone" type="text" name="barcode" value="'.dol_escape_htmltag($tmpcode).
'">';
2098 print
'<tr><td class="tdtop">'.$langs->trans(
"Description").
'</td><td>';
2101 $doleditor =
new DolEditor(
'desc', GETPOSTISSET(
'desc') ?
GETPOST(
'desc',
'restricthtml') : $object->
description,
'', 160,
'dolibarr_details',
'', false, true,
getDolGlobalInt(
'FCKEDITOR_ENABLE_DETAILS'), ROWS_4,
'90%');
2102 $doleditor->Create();
2109 print
'<tr><td>'.$langs->trans(
"PublicUrl").
'</td><td>';
2110 print
img_picto(
'',
'globe',
'class="pictofixedwidth"');
2111 print
'<input type="text" name="url" class="maxwidth500 widthcentpercentminusx" value="'.(GETPOSTISSET(
'url') ?
GETPOST(
'url') : $object->url).
'">';
2116 if (($object->isProduct() ||
getDolGlobalInt(
'STOCK_SUPPORTS_SERVICES')) && isModEnabled(
'stock')) {
2118 print
'<tr><td>'.$langs->trans(
"DefaultWarehouse").
'</td><td>';
2119 print
img_picto($langs->trans(
"DefaultWarehouse"),
'stock',
'class="pictofixedwidth"');
2120 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(),
'maxwidth500 widthcentpercentminusxx');
2121 print
' <a href="'.DOL_URL_ROOT.
'/product/stock/card.php?action=create&backtopage='.urlencode($_SERVER[
'PHP_SELF'].
'?action=edit&id='.((
int) $object->id)).
'">';
2122 print
'<span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans(
"AddWarehouse").
'"></span></a>';
2135 if ($object->isService() && isModEnabled(
'workstation')) {
2137 print
'<tr><td>'.$langs->trans(
"DefaultWorkstation").
'</td><td>';
2138 print
img_picto($langs->trans(
"DefaultWorkstation"),
'workstation',
'class="pictofixedwidth"');
2139 print $formproduct->selectWorkstations($object->fk_default_workstation,
'fk_default_workstation', 1);
2150 if ($object->isService()) {
2152 print
'<tr><td>'.$langs->trans(
"Duration").
'</td><td>';
2153 print
'<input name="duration_value" size="5" value="'.$object->duration_value.
'"> ';
2154 print $formproduct->selectMeasuringUnits(
"duration_unit",
"time", $object->duration_unit, 0, 1);
2157 print
' ';
2158 print
'<input type="checkbox" id="mandatoryperiod" name="mandatoryperiod"'.($object->mandatory_period == 1 ?
' checked="checked"' :
'').
'>';
2159 print
'<label for="mandatoryperiod">';
2160 $htmltooltip = $langs->trans(
"mandatoryHelper");
2161 print $form->textwithpicto($langs->trans(
"mandatoryperiod"), $htmltooltip, 1, 0);
2168 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"NatureOfProductShort"), $langs->trans(
"NatureOfProductDesc")).
'</td><td>';
2169 print $formproduct->selectProductNature(
'finished', (GETPOSTISSET(
'finished') ?
GETPOST(
'finished') : $object->finished));
2174 if (!$object->isService() && isModEnabled(
'bom')) {
2175 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"DefaultBOM"), $langs->trans(
"DefaultBOMDesc", $langs->transnoentitiesnoconv(
"Finished"))).
'</td><td>';
2176 $bomkey =
"Bom:bom/class/bom.class.php:0:(t.status:=:1) AND (t.fk_product:=:".((int) $object->id).
')';
2177 print $form->selectForForms($bomkey,
'fk_default_bom', (GETPOSTISSET(
'fk_default_bom') ?
GETPOST(
'fk_default_bom') : $object->fk_default_bom), 1);
2181 if (!$object->isService()) {
2184 print
'<tr><td>'.$langs->trans(
"Weight").
'</td><td>';
2185 print
'<input name="weight" size="5" value="'.(GETPOSTISSET(
'weight') ?
GETPOST(
'weight') : $object->weight).
'"> ';
2186 print $formproduct->selectMeasuringUnits(
"weight_units",
"weight", GETPOSTISSET(
'weight_units') ?
GETPOST(
'weight_units') : $object->weight_units, 0, 2);
2192 print
'<tr><td>'.$langs->trans(
"Length").
' x '.$langs->trans(
"Width").
' x '.$langs->trans(
"Height").
'</td><td>';
2193 print
'<input name="size" size="5" value="'.(GETPOSTISSET(
'size') ?
GETPOST(
'size') : $object->length).
'">x';
2194 print
'<input name="sizewidth" size="5" value="'.(GETPOSTISSET(
'sizewidth') ?
GETPOST(
'sizewidth') : $object->width).
'">x';
2195 print
'<input name="sizeheight" size="5" value="'.(GETPOSTISSET(
'sizeheight') ?
GETPOST(
'sizeheight') : $object->height).
'"> ';
2196 print $formproduct->selectMeasuringUnits(
"size_units",
"size", GETPOSTISSET(
'size_units') ?
GETPOST(
'size_units') : $object->length_units, 0, 2);
2201 print
'<tr><td>'.$langs->trans(
"Surface").
'</td><td>';
2202 print
'<input name="surface" size="5" value="'.(GETPOSTISSET(
'surface') ?
GETPOST(
'surface') : $object->surface).
'"> ';
2203 print $formproduct->selectMeasuringUnits(
"surface_units",
"surface", GETPOSTISSET(
'surface_units') ?
GETPOST(
'surface_units') : $object->surface_units, 0, 2);
2208 print
'<tr><td>'.$langs->trans(
"Volume").
'</td><td>';
2209 print
'<input name="volume" size="5" value="'.(GETPOSTISSET(
'volume') ?
GETPOST(
'volume') : $object->volume).
'"> ';
2210 print $formproduct->selectMeasuringUnits(
"volume_units",
"volume", GETPOSTISSET(
'volume_units') ?
GETPOST(
'volume_units') : $object->volume_units, 0, 2);
2216 print
'<tr><td>'.$langs->trans(
"NetMeasure").
'</td><td>';
2217 print
'<input name="net_measure" size="5" value="'.(GETPOSTISSET(
'net_measure') ?
GETPOST(
'net_measure') : $object->net_measure).
'"> ';
2218 print $formproduct->selectMeasuringUnits(
"net_measure_units",
"", GETPOSTISSET(
'net_measure_units') ?
GETPOST(
'net_measure_units') : $object->net_measure_units, 0, 0);
2224 print
'<tr><td>'.$langs->trans(
'DefaultUnitToShow').
'</td>';
2226 print $form->selectUnits($object->fk_unit,
'units');
2232 print
'<tr><td class="wordbreak">'.$langs->trans(
"CustomCode").
'</td><td><input name="customcode" class="maxwidth100onsmartphone" value="'.(GETPOSTISSET(
'customcode') ?
GETPOST(
'customcode') : $object->customcode).
'"></td></tr>';
2234 print
'<tr><td>'.$langs->trans(
"CountryOrigin").
'</td>';
2236 print
img_picto(
'',
'globe-americas',
'class="paddingrightonly"');
2237 print $form->select_country(GETPOSTISSET(
'country_id') ?
GETPOST(
'country_id',
'int') : $object->country_id,
'country_id',
'', 0,
'minwidth100 maxwidthonsmartphone');
2239 print
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
2247 print
'<td>'.$form->editfieldkey(
'RegionStateOrigin',
'state_id',
'', $object, 0).
'</td><td>';
2249 print
'<td>'.$form->editfieldkey(
'StateOrigin',
'state_id',
'', $object, 0).
'</td><td>';
2252 print
img_picto(
'',
'state',
'class="pictofixedwidth"');
2253 print $formcompany->select_state(GETPOSTISSET(
'state_id') ?
GETPOST(
'state_id',
'int') : $object->state_id, $object->country_code);
2261 print
'<tr><td>'.$langs->trans(
"LifeTime").
'</td><td><input name="lifetime" class="maxwidth100onsmartphone" value="'.$object->lifetime.
'"></td></tr>';
2262 print
'<tr><td>'.$langs->trans(
"QCFrequency").
'</td><td><input name="qc_frequency" class="maxwidth100onsmartphone" value="'.$object->qc_frequency.
'"></td></tr>';
2266 $parameters = array(
'colspan' =>
' colspan="2"',
'cols' => 2);
2267 $reshook = $hookmanager->executeHooks(
'formObjectOptions', $parameters, $object, $action);
2268 print $hookmanager->resPrint;
2269 if (empty($reshook)) {
2270 print $object->showOptionals($extrafields,
'edit', $parameters);
2274 if (isModEnabled(
'categorie')) {
2275 print
'<tr><td>'.$langs->trans(
"Categories").
'</td><td>';
2276 $cate_arbo = $form->select_all_categories(Categorie::TYPE_PRODUCT,
'',
'parent', 64, 0, 1);
2278 $cats = $c->containing($object->id, Categorie::TYPE_PRODUCT);
2279 $arrayselected = array();
2280 if (is_array($cats)) {
2281 foreach ($cats as $cat) {
2282 $arrayselected[] = $cat->id;
2286 foreach (
GETPOST(
'categories',
'array') as $cat) {
2287 $arrayselected[] = $cat;
2290 print
img_picto(
'',
'category',
'class="pictofixedwidth"').$form->multiselectarray(
'categories', $cate_arbo, $arrayselected,
'', 0,
'quatrevingtpercent widthcentpercentminusx', 0, 0);
2296 print
'<tr><td class="tdtop">'.$langs->trans(
"NoteNotVisibleOnBill").
'</td><td>';
2298 $doleditor =
new DolEditor(
'note_private', $object->note_private,
'', 140,
'dolibarr_notes',
'',
false,
true,
getDolGlobalInt(
'FCKEDITOR_ENABLE_NOTE_PRIVATE'), ROWS_4,
'90%');
2299 $doleditor->Create();
2308 print
'<table class="border centpercent">';
2311 if (isModEnabled(
'accounting')) {
2313 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellCode").
'</td>';
2315 print $formaccounting->select_account((GETPOSTISSET(
'accountancy_code_sell') ?
GETPOST(
'accountancy_code_sell') : $object->accountancy_code_sell),
'accountancy_code_sell', 1,
'', 1, 1,
'minwidth150 maxwidth300');
2319 if ($mysoc->isInEEC()) {
2320 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellIntraCode").
'</td>';
2322 print $formaccounting->select_account((GETPOSTISSET(
'accountancy_code_sell_intra') ?
GETPOST(
'accountancy_code_sell_intra') : $object->accountancy_code_sell_intra),
'accountancy_code_sell_intra', 1,
'', 1, 1,
'minwidth150 maxwidth300');
2327 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellExportCode").
'</td>';
2329 print $formaccounting->select_account((GETPOSTISSET(
'accountancy_code_sell_export') ?
GETPOST(
'accountancy_code_sell_export') : $object->accountancy_code_sell_export),
'accountancy_code_sell_export', 1,
'', 1, 1,
'minwidth150 maxwidth300');
2333 print
'<tr><td>'.$langs->trans(
"ProductAccountancyBuyCode").
'</td>';
2335 print $formaccounting->select_account((GETPOSTISSET(
'accountancy_code_buy') ?
GETPOST(
'accountancy_code_buy') : $object->accountancy_code_buy),
'accountancy_code_buy', 1,
'', 1, 1,
'minwidth150 maxwidth300');
2339 if ($mysoc->isInEEC()) {
2340 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyIntraCode").
'</td>';
2342 print $formaccounting->select_account((GETPOSTISSET(
'accountancy_code_buy_intra') ?
GETPOST(
'accountancy_code_buy_intra') : $object->accountancy_code_buy_intra),
'accountancy_code_buy_intra', 1,
'', 1, 1,
'minwidth150 maxwidth300');
2347 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyExportCode").
'</td>';
2349 print $formaccounting->select_account((GETPOSTISSET(
'accountancy_code_buy_export') ?
GETPOST(
'accountancy_code_buy_export') : $object->accountancy_code_buy_export),
'accountancy_code_buy_export', 1,
'', 1, 1,
'minwidth150 maxwidth300');
2354 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellCode").
'</td>';
2355 print
'<td><input name="accountancy_code_sell" class="maxwidth200" value="'.(GETPOSTISSET(
'accountancy_code_sell') ?
GETPOST(
'accountancy_code_sell') : $object->accountancy_code_sell).
'">';
2359 if ($mysoc->isInEEC()) {
2360 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellIntraCode").
'</td>';
2361 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).
'">';
2366 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellExportCode").
'</td>';
2367 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).
'">';
2371 print
'<tr><td>'.$langs->trans(
"ProductAccountancyBuyCode").
'</td>';
2372 print
'<td><input name="accountancy_code_buy" class="maxwidth200" value="'.(GETPOSTISSET(
'accountancy_code_buy') ?
GETPOST(
'accountancy_code_buy') : $object->accountancy_code_buy).
'">';
2376 if ($mysoc->isInEEC()) {
2377 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyIntraCode").
'</td>';
2378 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).
'">';
2383 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyExportCode").
'</td>';
2384 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).
'">';
2393 print $form->buttonsSaveCancel();
2399 $showbarcode = isModEnabled(
'barcode');
2400 if (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && !$user->hasRight(
'barcode',
'lire_advance')) {
2405 $titre = $langs->trans(
"CardProduct".$object->type);
2410 $linkback =
'<a href="'.DOL_URL_ROOT.
'/product/list.php?restore_lastsearch_values=1&type='.$object->type.
'">'.$langs->trans(
"BackToList").
'</a>';
2411 $object->next_prev_filter =
"fk_product_type = ".((int) $object->type);
2414 if ($user->socid && !in_array(
'product', explode(
',',
getDolGlobalString(
'MAIN_MODULES_FOR_EXTERNAL')))) {
2421 $parameters = array();
2423 $reshook = $hookmanager->executeHooks(
'tabContentViewProduct', $parameters, $object, $action);
2424 if (empty($reshook)) {
2425 print
'<div class="fichecenter">';
2426 print
'<div class="fichehalfleft">';
2428 print
'<div class="underbanner clearboth"></div>';
2429 print
'<table class="border tableforfield centpercent">';
2432 if (isModEnabled(
"product") && isModEnabled(
"service")) {
2433 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
2434 print
'<tr><td class="titlefield">';
2435 print (!
getDolGlobalString(
'PRODUCT_DENY_CHANGE_PRODUCT_TYPE')) ? $form->editfieldkey(
"Type",
'fk_product_type', $object->type, $object, $usercancreate, $typeformat) : $langs->trans(
'Type');
2437 print $form->editfieldval(
"Type",
'fk_product_type', $object->type, $object, $usercancreate, $typeformat);
2443 print
'<tr><td class="nowrap">';
2444 print
'<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
2445 print $langs->trans(
"BarcodeType");
2447 if (($action !=
'editbarcodetype') && $usercancreate && $createbarcode) {
2448 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>';
2450 print
'</tr></table>';
2452 if ($action ==
'editbarcodetype' || $action ==
'editbarcode') {
2453 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formbarcode.class.php';
2457 $fk_barcode_type =
'';
2458 if ($action ==
'editbarcodetype') {
2459 print $formbarcode->formBarcodeType($_SERVER[
'PHP_SELF'].
'?id='.$object->id, $object->barcode_type,
'fk_barcode_type');
2460 $fk_barcode_type = $object->barcode_type;
2462 $object->fetch_barcode();
2463 $fk_barcode_type = $object->barcode_type;
2464 print $object->barcode_type_label ? $object->barcode_type_label : ($object->barcode ?
'<div class="warning">'.$langs->trans(
"SetDefaultBarcodeType").
'<div>' :
'');
2466 print
'</td></tr>'.
"\n";
2469 print
'<tr><td class="nowrap">';
2470 print
'<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
2471 print $langs->trans(
"BarcodeValue");
2473 if (($action !=
'editbarcode') && $usercancreate && $createbarcode) {
2474 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>';
2476 print
'</tr></table>';
2478 if ($action ==
'editbarcode') {
2479 $tmpcode = GETPOSTISSET(
'barcode') ?
GETPOST(
'barcode') : $object->barcode;
2480 if (empty($tmpcode) && !empty($modBarCodeProduct->code_auto)) {
2481 $tmpcode = $modBarCodeProduct->getNextValue($object, $fk_barcode_type);
2484 print
'<form method="post" action="'.$_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'">';
2485 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2486 print
'<input type="hidden" name="action" value="setbarcode">';
2487 print
'<input type="hidden" name="barcode_type_code" value="'.$object->barcode_type_code.
'">';
2488 print
'<input class="width300" class="maxwidthonsmartphone" type="text" name="barcode" value="'.$tmpcode.
'">';
2489 print
' <input type="submit" class="button smallpaddingimp" value="'.$langs->trans(
"Modify").
'">';
2494 print
'</td></tr>'.
"\n";
2498 if (isModEnabled(
'productbatch')) {
2500 print
'<tr><td>'.$langs->trans(
"ManageLotSerial").
'</td><td>';
2501 print $object->getLibStatut(0, 2);
2505 print
'<tr><td>'.$langs->trans(
"ManageLotMask").
'</td><td>';
2506 print $object->batch_mask;
2514 print
'<tr><td class="nowrap">';
2515 print $langs->trans(
"ProductAccountancySellCode");
2517 if (isModEnabled(
'accounting')) {
2518 if (!empty($object->accountancy_code_sell)) {
2520 $accountingaccount->fetch(
'', $object->accountancy_code_sell, 1);
2522 print $accountingaccount->getNomUrl(0, 1, 1,
'', 1);
2525 print $object->accountancy_code_sell;
2530 if ($mysoc->isInEEC()) {
2531 print
'<tr><td class="nowrap">';
2532 print $langs->trans(
"ProductAccountancySellIntraCode");
2534 if (isModEnabled(
'accounting')) {
2535 if (!empty($object->accountancy_code_sell_intra)) {
2537 $accountingaccount2->fetch(
'', $object->accountancy_code_sell_intra, 1);
2539 print $accountingaccount2->getNomUrl(0, 1, 1,
'', 1);
2542 print $object->accountancy_code_sell_intra;
2548 print
'<tr><td class="nowrap">';
2549 print $langs->trans(
"ProductAccountancySellExportCode");
2551 if (isModEnabled(
'accounting')) {
2552 if (!empty($object->accountancy_code_sell_export)) {
2554 $accountingaccount3->fetch(
'', $object->accountancy_code_sell_export, 1);
2556 print $accountingaccount3->getNomUrl(0, 1, 1,
'', 1);
2559 print $object->accountancy_code_sell_export;
2564 print
'<tr><td class="nowrap">';
2565 print $langs->trans(
"ProductAccountancyBuyCode");
2567 if (isModEnabled(
'accounting')) {
2568 if (!empty($object->accountancy_code_buy)) {
2570 $accountingaccount4->fetch(
'', $object->accountancy_code_buy, 1);
2572 print $accountingaccount4->getNomUrl(0, 1, 1,
'', 1);
2575 print $object->accountancy_code_buy;
2580 if ($mysoc->isInEEC()) {
2581 print
'<tr><td class="nowrap">';
2582 print $langs->trans(
"ProductAccountancyBuyIntraCode");
2584 if (isModEnabled(
'accounting')) {
2585 if (!empty($object->accountancy_code_buy_intra)) {
2587 $accountingaccount5->fetch(
'', $object->accountancy_code_buy_intra, 1);
2589 print $accountingaccount5->getNomUrl(0, 1, 1,
'', 1);
2592 print $object->accountancy_code_buy_intra;
2598 print
'<tr><td class="nowrap">';
2599 print $langs->trans(
"ProductAccountancyBuyExportCode");
2601 if (isModEnabled(
'accounting')) {
2602 if (!empty($object->accountancy_code_buy_export)) {
2604 $accountingaccount6->fetch(
'', $object->accountancy_code_buy_export, 1);
2606 print $accountingaccount6->getNomUrl(0, 1, 1,
'', 1);
2609 print $object->accountancy_code_buy_export;
2615 print
'<tr><td class="tdtop">'.$langs->trans(
"Description").
'</td><td>'.(
dol_textishtml($object->description) ? $object->description :
dol_nl2br($object->description, 1,
true)).
'</td></tr>';
2619 print
'<tr><td>'.$langs->trans(
"PublicUrl").
'</td><td>';
2625 if (($object->isProduct() ||
getDolGlobalInt(
'STOCK_SUPPORTS_SERVICES')) && isModEnabled(
'stock')) {
2627 $warehouse->fetch($object->fk_default_warehouse);
2629 print
'<tr><td>'.$langs->trans(
"DefaultWarehouse").
'</td><td>';
2630 print(!empty($warehouse->id) ? $warehouse->getNomUrl(1) :
'');
2634 if ($object->isService() && isModEnabled(
'workstation')) {
2636 $res = $workstation->fetch($object->fk_default_workstation);
2638 print
'<tr><td>'.$langs->trans(
"DefaultWorkstation").
'</td><td>';
2639 print(!empty($workstation->id) ? $workstation->getNomUrl(1) :
'');
2644 if (isModEnabled(
'variants') && ($object->isProduct() || $object->isService())) {
2647 if ($combination->fetchByFkProductChild($object->id) > 0) {
2648 $prodstatic =
new Product($db);
2649 $prodstatic->fetch($combination->fk_product_parent);
2652 print
'<tr><td>'.$langs->trans(
"ParentProduct").
'</td><td>';
2653 print $prodstatic->getNomUrl(1);
2660 print
'<div class="fichehalfright">';
2662 print
'<div class="underbanner clearboth"></div>';
2663 print
'<table class="border tableforfield centpercent">';
2665 if ($object->isService()) {
2667 print
'<tr><td class="titlefield">'.$langs->trans(
"Duration").
'</td><td>';
2668 print $object->duration_value;
2669 if ($object->duration_value > 1) {
2670 $dur = array(
"i"=>$langs->trans(
"Minute"),
"h"=>$langs->trans(
"Hours"),
"d"=>$langs->trans(
"Days"),
"w"=>$langs->trans(
"Weeks"),
"m"=>$langs->trans(
"Months"),
"y"=>$langs->trans(
"Years"));
2671 } elseif ($object->duration_value > 0) {
2672 $dur = array(
"i"=>$langs->trans(
"Minute"),
"h"=>$langs->trans(
"Hour"),
"d"=>$langs->trans(
"Day"),
"w"=>$langs->trans(
"Week"),
"m"=>$langs->trans(
"Month"),
"y"=>$langs->trans(
"Year"));
2674 print(!empty($object->duration_unit) && isset($dur[$object->duration_unit]) ?
" ".$langs->trans($dur[$object->duration_unit]).
" " :
'');
2677 if ($object->duration_value > 0) {
2678 print
' ';
2680 $htmltooltip = $langs->trans(
"mandatoryHelper");
2681 print
'<input type="checkbox" class="" name="mandatoryperiod"'.($object->mandatory_period == 1 ?
' checked="checked"' :
'').
' disabled>';
2682 print $form->textwithpicto($langs->trans(
"mandatoryperiod"), $htmltooltip, 1, 0);
2688 print
'<tr><td class="titlefield">'.$form->textwithpicto($langs->trans(
"NatureOfProductShort"), $langs->trans(
"NatureOfProductDesc")).
'</td><td>';
2689 print $object->getLibFinished();
2694 if (!$object->isService() && isModEnabled(
'bom') && $object->finished) {
2695 print
'<tr><td class="titlefield">'.$form->textwithpicto($langs->trans(
"DefaultBOM"), $langs->trans(
"DefaultBOMDesc", $langs->transnoentitiesnoconv(
"Finished"))).
'</td><td>';
2696 if ($object->fk_default_bom) {
2697 $bom_static =
new BOM($db);
2698 $bom_static->fetch($object->fk_default_bom);
2699 print $bom_static->getNomUrl(1);
2704 if (!$object->isService()) {
2707 print
'<tr><td class="titlefield">'.$langs->trans(
"Weight").
'</td><td>';
2708 if ($object->weight !=
'') {
2713 print
"</td></tr>\n";
2718 print
'<tr><td>'.$langs->trans(
"Length").
' x '.$langs->trans(
"Width").
' x '.$langs->trans(
"Height").
'</td><td>';
2719 if ($object->length !=
'' || $object->width !=
'' || $object->height !=
'') {
2720 print $object->length;
2721 if ($object->width) {
2722 print
" x ".$object->width;
2724 if ($object->height) {
2725 print
" x ".$object->height;
2727 print
' '.measuringUnitString(0,
"size", $object->length_units);
2731 print
"</td></tr>\n";
2735 print
'<tr><td>'.$langs->trans(
"Surface").
'</td><td>';
2736 if ($object->surface !=
'') {
2741 print
"</td></tr>\n";
2745 print
'<tr><td>'.$langs->trans(
"Volume").
'</td><td>';
2746 if ($object->volume !=
'') {
2751 print
"</td></tr>\n";
2756 print
'<tr><td class="titlefield">'.$langs->trans(
"NetMeasure").
'</td><td>';
2757 if ($object->net_measure !=
'') {
2768 $unit = $object->getLabelOfUnit();
2770 print
'<tr><td>'.$langs->trans(
'DefaultUnitToShow').
'</td><td>';
2772 print $langs->trans($unit);
2779 print
'<tr><td>'.$langs->trans(
"CustomCode").
'</td><td>'.$object->customcode.
'</td></tr>';
2782 print
'<tr><td>'.$langs->trans(
"Origin").
'</td><td>'.
getCountry($object->country_id, 0, $db);
2783 if (!empty($object->state_id)) {
2784 print
' - '.getState($object->state_id, 0, $db);
2791 print
'<tr><td>'.$langs->trans(
"LifeTime").
'</td><td>'.$object->lifetime.
'</td></tr>';
2792 print
'<tr><td>'.$langs->trans(
"QCFrequency").
'</td><td>'.$object->qc_frequency.
'</td></tr>';
2796 $parameters = array();
2797 include DOL_DOCUMENT_ROOT.
'/core/tpl/extrafields_view.tpl.php';
2800 if (isModEnabled(
'categorie')) {
2801 print
'<tr><td class="valignmiddle">'.$langs->trans(
"Categories").
'</td><td>';
2802 print $form->showCategories($object->id, Categorie::TYPE_PRODUCT, 1);
2808 print
'<!-- show Note --> '.
"\n";
2809 print
'<tr><td class="tdtop">'.$langs->trans(
"NotePrivate").
'</td><td>'.(
dol_textishtml($object->note_private) ? $object->note_private :
dol_nl2br($object->note_private, 1,
true)).
'</td></tr>'.
"\n";
2810 print
'<!-- End show Note --> '.
"\n";
2817 print
'<div class="clearboth"></div>';
2822 } elseif ($action !=
'create') {
2828if (!empty($modCodeProduct->code_auto)) {
2829 $tmpcode = $modCodeProduct->getNextValue($object, $object->type);
2835if (($action ==
'delete' && (empty($conf->use_javascript_ajax) || !empty($conf->dol_use_jmobile)))
2836 || (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile))) {
2837 $formconfirm = $form->formconfirm(
"card.php?id=".$object->id, $langs->trans(
"DeleteProduct"), $langs->trans(
"ConfirmDeleteProduct"),
"confirm_delete",
'', 0,
"action-delete");
2839if ($action ==
'merge') {
2840 $formquestion = array(
2842 'name' =>
'product_origin',
2843 'label' => $langs->trans(
'MergeOriginProduct'),
2845 'value' => $form->select_produits(
'',
'product_origin',
'', 0, 0, 1, 2,
'', 1, array(), 0, 1, 0,
'minwidth200', 0,
'',
null, 1),
2848 $formconfirm = $form->formconfirm($_SERVER[
"PHP_SELF"].
"?id=".$object->id, $langs->trans(
"MergeProducts"), $langs->trans(
"ConfirmMergeProducts"),
"confirm_merge", $formquestion,
'no', 1, 250);
2852if (($action ==
'clone' && (empty($conf->use_javascript_ajax) || !empty($conf->dol_use_jmobile)))
2853 || (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile))) {
2855 $formquestionclone = array(
2856 'text' => $langs->trans(
"ConfirmClone"),
2857 array(
'type' =>
'text',
'name' =>
'clone_ref',
'label' => $langs->trans(
"NewRefForClone"),
'value' => empty($tmpcode) ? $langs->trans(
"CopyOf").
' '.$object->ref : $tmpcode,
'morecss'=>
'width150'),
2858 array(
'type' =>
'checkbox',
'name' =>
'clone_content',
'label' => $langs->trans(
"CloneContentProduct"),
'value' => 1),
2859 array(
'type' =>
'checkbox',
'name' =>
'clone_categories',
'label' => $langs->trans(
"CloneCategoriesProduct"),
'value' => 1),
2862 $formquestionclone[] = array(
'type' =>
'checkbox',
'name' =>
'clone_prices',
'label' => $langs->trans(
"ClonePricesProduct").
' ('.$langs->trans(
"CustomerPrices").
')',
'value' => 0);
2865 $formquestionclone[] = array(
'type' =>
'checkbox',
'name' =>
'clone_composition',
'label' => $langs->trans(
'CloneCompositionProduct'),
'value' => 1);
2868 $formconfirm .= $form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.$object->id, $langs->trans(
'ToClone'), $langs->trans(
'ConfirmCloneProduct', $object->ref),
'confirm_clone', $formquestionclone,
'yes',
'action-clone', 350, 600);
2872$parameters = array(
'formConfirm' => $formconfirm,
'object' => $object);
2873$reshook = $hookmanager->executeHooks(
'formConfirm', $parameters, $object, $action);
2874if (empty($reshook)) {
2875 $formconfirm .= $hookmanager->resPrint;
2876} elseif ($reshook > 0) {
2877 $formconfirm = $hookmanager->resPrint;
2886if ($action !=
'create' && $action !=
'edit') {
2887 $cloneProductUrl = $_SERVER[
"PHP_SELF"].
'?action=clone&token='.newToken();
2888 $cloneButtonId =
'action-clone-no-ajax';
2890 print
"\n".
'<div class="tabsAction">'.
"\n";
2892 $parameters = array();
2893 $reshook = $hookmanager->executeHooks(
'addMoreActionsButtons', $parameters, $object, $action);
2894 if (empty($reshook)) {
2895 if ($usercancreate) {
2896 if (!isset($object->no_button_edit) || $object->no_button_edit != 1) {
2897 print
dolGetButtonAction(
'', $langs->trans(
'Modify'),
'default', $_SERVER[
"PHP_SELF"].
'?action=edit&token='.newToken().
'&id='.$object->id,
'', $usercancreate);
2900 if (!isset($object->no_button_copy) || $object->no_button_copy != 1) {
2901 if (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile)) {
2902 $cloneProductUrl =
'';
2903 $cloneButtonId =
'action-clone';
2905 print
dolGetButtonAction($langs->trans(
'ToClone'),
'',
'default', $cloneProductUrl, $cloneButtonId, $usercancreate);
2908 $object_is_used = $object->isObjectUsed($object->id);
2910 if ($usercandelete) {
2911 if (empty($object_is_used) && (!isset($object->no_button_delete) || $object->no_button_delete != 1)) {
2912 if (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile)) {
2913 print
dolGetButtonAction($langs->trans(
'Delete'),
'',
'delete',
'#',
'action-delete',
true);
2915 print
dolGetButtonAction(
'', $langs->trans(
'Delete'),
'delete', $_SERVER[
"PHP_SELF"].
'?action=delete&token='.newToken().
'&id='.$object->id,
'');
2918 print
dolGetButtonAction($langs->trans(
"ProductIsUsed"), $langs->trans(
'Delete'),
'delete',
'#',
'',
false);
2921 print
'<a class="butActionDelete" href="card.php?action=merge&id='.$object->id.
'" title="'.
dol_escape_htmltag($langs->trans(
"MergeProducts")).
'">'.$langs->trans(
'Merge').
'</a>'.
"\n";
2924 print
dolGetButtonAction($langs->trans(
"NotEnoughPermissions"), $langs->trans(
'Delete'),
'delete',
'#',
'',
false);
2936if (
getDolGlobalString(
'PRODUCT_ADD_FORM_ADD_TO') && $object->id && ($action ==
'' || $action ==
'view') && $object->status) {
2942 if (isModEnabled(
"propal") && $user->hasRight(
'propal',
'creer')) {
2943 $propal =
new Propal($db);
2945 $langs->load(
"propal");
2947 $otherprop = $propal->liste_array(2, 1, 0);
2949 if (is_array($otherprop) && count($otherprop)) {
2950 $html .=
'<tr><td style="width: 200px;">';
2951 $html .= $langs->trans(
"AddToDraftProposals").
'</td><td>';
2952 $html .= $form->selectarray(
"propalid", $otherprop, 0, 1);
2953 $html .=
'</td></tr>';
2955 $html .=
'<tr><td style="width: 200px;">';
2956 $html .= $langs->trans(
"AddToDraftProposals").
'</td><td>';
2957 $html .= $langs->trans(
"NoDraftProposals");
2958 $html .=
'</td></tr>';
2963 if (isModEnabled(
'commande') && $user->hasRight(
'commande',
'creer')) {
2966 $langs->load(
"orders");
2968 $othercom = $commande->liste_array(2, 1,
null);
2969 if (is_array($othercom) && count($othercom)) {
2970 $html .=
'<tr><td style="width: 200px;">';
2971 $html .= $langs->trans(
"AddToDraftOrders").
'</td><td>';
2972 $html .= $form->selectarray(
"commandeid", $othercom, 0, 1);
2973 $html .=
'</td></tr>';
2975 $html .=
'<tr><td style="width: 200px;">';
2976 $html .= $langs->trans(
"AddToDraftOrders").
'</td><td>';
2977 $html .= $langs->trans(
"NoDraftOrders");
2978 $html .=
'</td></tr>';
2983 if (isModEnabled(
'facture') && $user->hasRight(
'facture',
'creer')) {
2986 $langs->load(
"bills");
2988 $otherinvoice = $invoice->liste_array(2, 1,
null);
2989 if (is_array($otherinvoice) && count($otherinvoice)) {
2990 $html .=
'<tr><td style="width: 200px;">';
2991 $html .= $langs->trans(
"AddToDraftInvoices").
'</td><td>';
2992 $html .= $form->selectarray(
"factureid", $otherinvoice, 0, 1);
2993 $html .=
'</td></tr>';
2995 $html .=
'<tr><td style="width: 200px;">';
2996 $html .= $langs->trans(
"AddToDraftInvoices").
'</td><td>';
2997 $html .= $langs->trans(
"NoDraftInvoices");
2998 $html .=
'</td></tr>';
3003 if (!empty($html)) {
3004 print
'<form method="POST" action="'.$_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'">';
3005 print
'<input type="hidden" name="token" value="'.newToken().
'">';
3006 print
'<input type="hidden" name="action" value="addin">';
3012 $html .=
'<tr><td class="nowrap">'.$langs->trans(
"Quantity").
' ';
3013 $html .=
'<input type="text" class="flat" name="qty" size="1" value="1"></td>';
3014 $html .=
'<td class="nowrap">'.$langs->trans(
"ReductionShort").
'(%) ';
3015 $html .=
'<input type="text" class="flat" name="remise_percent" size="1" value="0">';
3016 $html .=
'</td></tr>';
3018 print
'<table width="100%" class="border">';
3022 print
'<div class="center">';
3023 print
'<input type="submit" class="button button-add" value="'.$langs->trans(
"Add").
'">';
3037if ($action !=
'create' && $action !=
'edit' && $action !=
'delete') {
3038 print
'<div class="fichecenter"><div class="fichehalfleft">';
3039 print
'<a name="builddoc"></a>';
3043 if (!empty($conf->product->multidir_output[$object->entity])) {
3044 $filedir = $conf->product->multidir_output[$object->entity].
'/'.$objectref;
3046 $filedir = $conf->product->dir_output.
'/'.$objectref;
3048 $urlsource = $_SERVER[
"PHP_SELF"].
"?id=".$object->id;
3049 $genallowed = $usercanread;
3050 $delallowed = $usercancreate;
3052 print $formfile->showdocuments($modulepart, $object->ref, $filedir, $urlsource, $genallowed, $delallowed,
'', 0, 0, 0, 28, 0,
'', 0,
'', $langs->getDefaultLang(),
'', $object);
3053 $somethingshown = $formfile->numoffiles;
3055 print
'</div><div class="fichehalfright">';
3059 $morehtmlcenter =
dolGetButtonTitle($langs->trans(
'SeeAll'),
'',
'fa fa-bars imgforviewmode', DOL_URL_ROOT.
'/product/agenda.php?id='.$object->id);
3062 include_once DOL_DOCUMENT_ROOT.
'/core/class/html.formactions.class.php';
3064 $somethingshown =
$formactions->showactions($object,
'product', 0, 1,
'', $MAXEVENT,
'', $morehtmlcenter);
3066 print
'</div></div>';
if(preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) if(preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) if($action=='set') elseif( $action=='specimen') elseif($action=='setmodel') elseif( $action=='del') elseif($action=='setdoc') $formactions
View.
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Class to manage accounting accounts.
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 a product combination.
File of class to manage predefined price products or services by customer.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
Class to manage proposals.
Class to manage third parties objects (customers, suppliers, prospects...)
getCountry($searchkey, $withcode='', $dbtouse=0, $outputlangs='', $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_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='rowid', $fieldref='ref', $morehtmlref='', $moreparam='', $nodbprefix=0, $morehtmlleft='', $morehtmlstatus='', $onlybanner=0, $morehtmlright='')
Show tab footer of a card.
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
showValueWithClipboardCPButton($valuetocopy, $showonlyonhover=1, $texttoshow='')
Create a button to copy $valuetocopy in the clipboard (for copy and paste feature).
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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_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_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.
GETPOSTISARRAY($paramname, $method=0)
Return true if the parameter $paramname is submit from a POST OR GET as an array.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
dol_set_focus($selector)
Set focus onto field with selector (similar behaviour of 'autofocus' HTML5 tag)
dol_clone($object, $native=0)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
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.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='')
Show information for admin users or standard users.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
get_localtax($vatrate, $local, $thirdparty_buyer="", $thirdparty_seller="", $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate,...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
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.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
img_edit($titlealt='default', $float=0, $other='')
Show logo editer/modifier fiche.
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_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.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
product_prepare_head($object)
Prepare array with list of tabs.
measuringUnitString($unit, $measuring_style='', $scale='', $use_short_label=0, $outputlangs=null)
Return translation label of a unit key.
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.