46 require
'../main.inc.php';
47 require_once DOL_DOCUMENT_ROOT.
'/core/class/canvas.class.php';
48 require_once DOL_DOCUMENT_ROOT.
'/core/class/extrafields.class.php';
49 require_once DOL_DOCUMENT_ROOT.
'/core/class/genericobject.class.php';
50 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formcompany.class.php';
51 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formfile.class.php';
52 require_once DOL_DOCUMENT_ROOT.
'/core/lib/company.lib.php';
53 require_once DOL_DOCUMENT_ROOT.
'/core/lib/product.lib.php';
54 require_once DOL_DOCUMENT_ROOT.
'/core/modules/product/modules_product.class.php';
55 require_once DOL_DOCUMENT_ROOT.
'/categories/class/categorie.class.php';
56 require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
57 require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
58 require_once DOL_DOCUMENT_ROOT.
'/workstation/class/workstation.class.php';
61 require_once DOL_DOCUMENT_ROOT.
'/comm/propal/class/propal.class.php';
64 require_once DOL_DOCUMENT_ROOT.
'/compta/facture/class/facture.class.php';
67 require_once DOL_DOCUMENT_ROOT.
'/commande/class/commande.class.php';
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';
75 require_once DOL_DOCUMENT_ROOT.
'/bom/class/bom.class.php';
79 $langs->loadLangs(array(
'products',
'other'));
81 $langs->load(
"stocks");
84 $langs->load(
"bills");
87 $langs->load(
"productbatch");
90 $mesg =
''; $error = 0; $errors = array();
92 $refalreadyexists = 0;
98 $action = (
GETPOST(
'action',
'alpha') ?
GETPOST(
'action',
'alpha') :
'view');
99 $cancel =
GETPOST(
'cancel',
'alpha');
100 $backtopage =
GETPOST(
'backtopage',
'alpha');
101 $confirm =
GETPOST(
'confirm',
'alpha');
102 $socid =
GETPOST(
'socid',
'int');
103 $duration_value =
GETPOST(
'duration_value',
'int');
104 $duration_unit =
GETPOST(
'duration_unit',
'alpha');
106 $accountancy_code_sell =
GETPOST(
'accountancy_code_sell',
'alpha');
107 $accountancy_code_sell_intra =
GETPOST(
'accountancy_code_sell_intra',
'alpha');
108 $accountancy_code_sell_export =
GETPOST(
'accountancy_code_sell_export',
'alpha');
109 $accountancy_code_buy =
GETPOST(
'accountancy_code_buy',
'alpha');
110 $accountancy_code_buy_intra =
GETPOST(
'accountancy_code_buy_intra',
'alpha');
111 $accountancy_code_buy_export =
GETPOST(
'accountancy_code_buy_export',
'alpha');
113 $checkmandatory =
GETPOST(
'accountancy_code_buy_export',
'alpha');
116 $label_security_check = empty($conf->global->MAIN_SECURITY_ALLOW_UNSECURED_LABELS_WITH_HTML) ?
'alphanohtml' :
'restricthtml';
118 if (!empty($user->socid)) {
119 $socid = $user->socid;
123 $module = (!empty($conf->global->PRODUCT_CODEPRODUCT_ADDON) ? $conf->global->PRODUCT_CODEPRODUCT_ADDON :
'mod_codeproduct_leopard');
124 if (substr($module, 0, 16) ==
'mod_codeproduct_' && substr($module, -3) ==
'php') {
125 $module = substr($module, 0,
dol_strlen($module) - 4);
129 $modCodeProduct =
new $module();
133 $object->type = $type;
137 $extrafields->fetch_name_optionals_label($object->table_element);
139 if ($id > 0 || !empty($ref)) {
140 $result = $object->fetch($id, $ref);
144 $entity = (!empty($object->entity) ? $object->entity : $conf->entity);
146 $upload_dir = $conf->product->multidir_output[$entity].
'/'.
get_exdir(0, 0, 0, 0, $object,
'product').dol_sanitizeFileName($object->ref);
148 $upload_dir = $conf->service->multidir_output[$entity].
'/'.
get_exdir(0, 0, 0, 0, $object,
'product').dol_sanitizeFileName($object->ref);
153 $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";
155 $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";
160 $modulepart =
'product';
163 $canvas = !empty($object->canvas) ? $object->canvas :
GETPOST(
"canvas");
165 if (!empty($canvas)) {
166 require_once DOL_DOCUMENT_ROOT.
'/core/class/canvas.class.php';
167 $objcanvas =
new Canvas($db, $action);
168 $objcanvas->getCanvas(
'product',
'card', $canvas);
172 $fieldvalue = (!empty($id) ? $id : (!empty($ref) ? $ref :
''));
173 $fieldtype = (!empty($id) ?
'rowid' :
'ref');
175 if ($object->id > 0) {
176 if ($object->type == $object::TYPE_PRODUCT) {
177 restrictedArea($user,
'produit', $object->id,
'product&product',
'',
'');
179 if ($object->type == $object::TYPE_SERVICE) {
180 restrictedArea($user,
'service', $object->id,
'product&product',
'',
'');
183 restrictedArea($user,
'produit|service', 0,
'product&product',
'',
'', $fieldtype);
187 $hookmanager->initHooks(array(
'productcard',
'globalcard'));
203 $createbarcode = empty($conf->barcode->enabled) ? 0 : 1;
204 if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->barcode->creer_advance)) {
208 $parameters = array(
'id'=>$id,
'ref'=>$ref,
'objcanvas'=>$objcanvas);
209 $reshook = $hookmanager->executeHooks(
'doActions',
$parameters, $object, $action);
214 if (empty($reshook)) {
215 $backurlforlist = DOL_URL_ROOT.
'/product/list.php?type='.$type;
217 if (empty($backtopage) || ($cancel && empty($id))) {
218 if (empty($backtopage) || ($cancel && strpos($backtopage,
'__ID__'))) {
219 if (empty($id) && (($action !=
'add' && $action !=
'create') || $cancel)) {
220 $backtopage = $backurlforlist;
222 $backtopage = DOL_URL_ROOT.
'/product/card.php?id='.((!empty($id) && $id > 0) ? $id :
'__ID__');
228 if (!empty($backtopageforcancel)) {
229 header(
"Location: ".$backtopageforcancel);
231 } elseif (!empty($backtopage)) {
232 header(
"Location: ".$backtopage);
238 if ($action ==
'confirm_merge' && $confirm ==
'yes' && $user->rights->societe->creer) {
240 $productOriginId =
GETPOST(
'product_origin',
'int');
241 $productOrigin =
new Product($db);
243 if ($productOriginId <= 0) {
244 $langs->load(
'errors');
245 setEventMessages($langs->trans(
'ErrorProductIdIsMandatory', $langs->transnoentitiesnoconv(
'MergeOriginProduct')),
null,
'errors');
247 if (!$error && $productOrigin->fetch($productOriginId) < 1) {
257 $listofproperties = array(
267 'accountancy_code_buy',
268 'accountancy_code_buy_intra',
269 'accountancy_code_buy_export',
270 'accountancy_code_sell',
271 'accountancy_code_sell_intra',
272 'accountancy_code_sell_export'
274 foreach ($listofproperties as $property) {
275 if (empty($object->$property)) {
276 $object->$property = $productOrigin->$property;
280 $listofproperties = array(
281 'note_public',
'note_private'
283 foreach ($listofproperties as $property) {
284 $object->$property =
dol_concatdesc($object->$property, $productOrigin->$property);
288 if (is_array($productOrigin->array_options)) {
289 foreach ($productOrigin->array_options as $key => $val) {
290 if (empty($object->array_options[$key])) {
291 $object->array_options[$key] = $val;
298 $custcats_ori = $static_cat->containing($productOrigin->id,
'product',
'id');
299 $custcats = $static_cat->containing($object->id,
'product',
'id');
300 $custcats = array_merge($custcats, $custcats_ori);
301 $object->setCategories($custcats);
304 if ($productOrigin->barcode == $object->barcode) {
305 dol_syslog(
"We clean customer and supplier code so we will be able to make the update of target");
306 $productOrigin->barcode =
'';
311 $result = $object->update($object->id, $user, 0,
'merge');
322 'ActionComm' =>
'/comm/action/class/actioncomm.class.php',
323 'Bom' =>
'/bom/class/bom.class.php',
326 'Commande' =>
'/commande/class/commande.class.php',
327 'CommandeFournisseur' =>
'/fourn/class/fournisseur.commande.class.php',
328 'Contrat' =>
'/contrat/class/contrat.class.php',
329 'Delivery' =>
'/delivery/class/delivery.class.php',
330 'Facture' =>
'/compta/facture/class/facture.class.php',
331 'FactureFournisseur' =>
'/fourn/class/fournisseur.facture.class.php',
332 'FactureRec' =>
'/compta/facture/class/facture-rec.class.php',
333 'FichinterRec' =>
'/fichinter/class/fichinterrec.class.php',
334 'ProductFournisseur' =>
'/fourn/class/fournisseur.product.class.php',
335 'Propal' =>
'/comm/propal/class/propal.class.php',
336 'Reception' =>
'/reception/class/reception.class.php',
337 'SupplierProposal' =>
'/supplier_proposal/class/supplier_proposal.class.php',
341 foreach ($objects as $object_name => $object_file) {
342 require_once DOL_DOCUMENT_ROOT.$object_file;
344 if (!$error && !$object_name::replaceProduct($db, $productOrigin->id, $object->id)) {
354 $reshook = $hookmanager->executeHooks(
357 'soc_origin' => $productOrigin->id,
358 'soc_dest' => $object->id,
372 $object->context = array(
374 'mergefromid' => $productOrigin->id,
378 $result = $object->call_trigger(
'PRODUCT_MODIFY', $user);
389 if ($productOrigin->delete($user) < 1) {
398 $langs->load(
"errors");
407 if ($action ==
'setfk_product_type' && $usercancreate) {
408 $result = $object->setValueFrom(
'fk_product_type',
GETPOST(
'fk_product_type'),
'',
null,
'text',
'', $user,
'PRODUCT_MODIFY');
409 header(
"Location: ".$_SERVER[
'PHP_SELF'].
"?id=".$object->id);
414 $upload_dir = $conf->product->dir_output;
415 $permissiontoadd = $usercancreate;
416 include DOL_DOCUMENT_ROOT.
'/core/actions_builddoc.inc.php';
418 include DOL_DOCUMENT_ROOT.
'/core/actions_printing.inc.php';
421 if ($action ==
'setfk_barcode_type' && $createbarcode) {
422 $result = $object->setValueFrom(
'fk_barcode_type',
GETPOST(
'fk_barcode_type'),
'',
null,
'text',
'', $user,
'PRODUCT_MODIFY');
423 header(
"Location: ".$_SERVER[
'PHP_SELF'].
"?id=".$object->id);
428 if ($action ==
'setbarcode' && $createbarcode) {
429 $result = $object->check_barcode(
GETPOST(
'barcode'),
GETPOST(
'barcode_type_code'));
432 $result = $object->setValueFrom(
'barcode',
GETPOST(
'barcode'),
'',
null,
'text',
'', $user,
'PRODUCT_MODIFY');
433 header(
"Location: ".$_SERVER[
'PHP_SELF'].
"?id=".$object->id);
436 $langs->load(
"errors");
438 $errors[] =
'ErrorBadBarCodeSyntax';
439 } elseif ($result == -2) {
440 $errors[] =
'ErrorBarCodeRequired';
441 } elseif ($result == -3) {
442 $errors[] =
'ErrorBarCodeAlreadyUsed';
444 $errors[] =
'FailedToValidateBarCode';
453 if ($action ==
'update_extras') {
457 $ret = $extrafields->setOptionalsFromPost(
null, $object,
GETPOST(
'attribute',
'restricthtml'));
464 $result = $object->insertExtraFields(
'PRODUCT_MODIFY');
472 $action =
'edit_extras';
477 if ($action ==
'add' && $usercancreate) {
480 if (!
GETPOST(
'label', $label_security_check)) {
481 setEventMessages($langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'Label')),
null,
'errors');
486 if (empty($conf->global->PRODUCT_GENERATE_REF_AFTER_FORM)) {
487 setEventMessages($langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'Ref')),
null,
'errors');
492 if (!empty($duration_value) && empty($duration_unit)) {
493 setEventMessages($langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'Unit')),
null,
'errors');
499 $units =
GETPOST(
'units',
'int');
501 $object->entity = $conf->entity;
503 $object->label =
GETPOST(
'label', $label_security_check);
504 $object->price_base_type =
GETPOST(
'price_base_type',
'aZ09');
505 $object->mandatory_period = !empty(
GETPOST(
"mandatoryperiod",
'alpha')) ? 1 : 0;
506 if ($object->price_base_type ==
'TTC') {
507 $object->price_ttc =
GETPOST(
'price');
509 $object->price =
GETPOST(
'price');
511 if ($object->price_base_type ==
'TTC') {
512 $object->price_min_ttc =
GETPOST(
'price_min');
514 $object->price_min =
GETPOST(
'price_min');
517 $tva_tx_txt =
GETPOST(
'tva_tx',
'alpha');
521 $tva_tx = preg_replace(
'/[^0-9\.].*$/',
'', $tva_tx_txt);
522 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
523 $localtax1 = 0; $localtax2 = 0; $localtax1_type =
'0'; $localtax2_type =
'0';
526 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
528 $vatratecode = $reg[1];
530 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
531 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
532 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($mysoc->country_code).
"'";
533 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
534 $sql .=
" AND t.code = '".$db->escape($vatratecode).
"'";
535 $resql = $db->query($sql);
537 $obj = $db->fetch_object(
$resql);
538 $npr = $obj->recuperableonly;
539 $localtax1 = $obj->localtax1;
540 $localtax2 = $obj->localtax2;
541 $localtax1_type = $obj->localtax1_type;
542 $localtax2_type = $obj->localtax2_type;
546 $object->default_vat_code = $vatratecode;
547 $object->tva_tx = $tva_tx;
548 $object->tva_npr = $npr;
549 $object->localtax1_tx = $localtax1;
550 $object->localtax2_tx = $localtax2;
551 $object->localtax1_type = $localtax1_type;
552 $object->localtax2_type = $localtax2_type;
554 $object->type = $type;
555 $object->status =
GETPOST(
'statut');
556 $object->status_buy =
GETPOST(
'statut_buy');
557 $object->status_batch =
GETPOST(
'status_batch');
558 $object->batch_mask =
GETPOST(
'batch_mask');
560 $object->barcode_type =
GETPOST(
'fk_barcode_type');
561 $object->barcode =
GETPOST(
'barcode');
564 $stdobject->element =
'product';
565 $stdobject->barcode_type =
GETPOST(
'fk_barcode_type');
566 $result = $stdobject->fetch_barcode();
569 $mesg =
'Failed to get bar code type information ';
572 $object->barcode_type_code = $stdobject->barcode_type_code;
573 $object->barcode_type_coder = $stdobject->barcode_type_coder;
574 $object->barcode_type_label = $stdobject->barcode_type_label;
579 $object->note = $object->note_private;
580 $object->customcode =
GETPOST(
'customcode',
'alphanohtml');
581 $object->country_id =
GETPOST(
'country_id',
'int');
582 $object->state_id =
GETPOST(
'state_id',
'int');
583 $object->lifetime =
GETPOST(
'lifetime',
'int');
584 $object->qc_frequency =
GETPOST(
'qc_frequency',
'int');
585 $object->duration_value = $duration_value;
586 $object->duration_unit = $duration_unit;
587 $object->fk_default_warehouse =
GETPOST(
'fk_default_warehouse');
588 $object->fk_default_workstation =
GETPOST(
'fk_default_workstation');
589 $object->seuil_stock_alerte =
GETPOST(
'seuil_stock_alerte') ?
GETPOST(
'seuil_stock_alerte') : 0;
590 $object->desiredstock =
GETPOST(
'desiredstock') ?
GETPOST(
'desiredstock') : 0;
591 $object->canvas =
GETPOST(
'canvas');
592 $object->net_measure =
GETPOST(
'net_measure');
593 $object->net_measure_units =
GETPOST(
'net_measure_units');
594 $object->weight =
GETPOST(
'weight');
595 $object->weight_units =
GETPOST(
'weight_units');
596 $object->length =
GETPOST(
'size');
597 $object->length_units =
GETPOST(
'size_units');
598 $object->width =
GETPOST(
'sizewidth');
599 $object->height =
GETPOST(
'sizeheight');
600 $object->surface =
GETPOST(
'surface');
601 $object->surface_units =
GETPOST(
'surface_units');
602 $object->volume =
GETPOST(
'volume');
603 $object->volume_units =
GETPOST(
'volume_units');
604 $finished =
GETPOST(
'finished',
'int');
605 if ($finished >= 0) {
606 $object->finished = $finished;
608 $object->finished =
null;
611 $units =
GETPOST(
'units',
'int');
613 $object->fk_unit = $units;
615 $object->fk_unit =
null;
618 $accountancy_code_sell =
GETPOST(
'accountancy_code_sell',
'alpha');
619 $accountancy_code_sell_intra =
GETPOST(
'accountancy_code_sell_intra',
'alpha');
620 $accountancy_code_sell_export =
GETPOST(
'accountancy_code_sell_export',
'alpha');
621 $accountancy_code_buy =
GETPOST(
'accountancy_code_buy',
'alpha');
622 $accountancy_code_buy_intra =
GETPOST(
'accountancy_code_buy_intra',
'alpha');
623 $accountancy_code_buy_export =
GETPOST(
'accountancy_code_buy_export',
'alpha');
625 if (empty($accountancy_code_sell) || $accountancy_code_sell ==
'-1') {
626 $object->accountancy_code_sell =
'';
628 $object->accountancy_code_sell = $accountancy_code_sell;
630 if (empty($accountancy_code_sell_intra) || $accountancy_code_sell_intra ==
'-1') {
631 $object->accountancy_code_sell_intra =
'';
633 $object->accountancy_code_sell_intra = $accountancy_code_sell_intra;
635 if (empty($accountancy_code_sell_export) || $accountancy_code_sell_export ==
'-1') {
636 $object->accountancy_code_sell_export =
'';
638 $object->accountancy_code_sell_export = $accountancy_code_sell_export;
640 if (empty($accountancy_code_buy) || $accountancy_code_buy ==
'-1') {
641 $object->accountancy_code_buy =
'';
643 $object->accountancy_code_buy = $accountancy_code_buy;
645 if (empty($accountancy_code_buy_intra) || $accountancy_code_buy_intra ==
'-1') {
646 $object->accountancy_code_buy_intra =
'';
648 $object->accountancy_code_buy_intra = $accountancy_code_buy_intra;
650 if (empty($accountancy_code_buy_export) || $accountancy_code_buy_export ==
'-1') {
651 $object->accountancy_code_buy_export =
'';
653 $object->accountancy_code_buy_export = $accountancy_code_buy_export;
657 if (!empty($conf->global->PRODUIT_MULTIPRICES)) {
658 for ($i = 2; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) {
661 $object->multiprices_base_type[
"$i"] =
GETPOST(
"multiprices_base_type_".$i);
663 $object->multiprices[
"$i"] =
"";
669 $ret = $extrafields->setOptionalsFromPost(
null, $object);
674 if (!$ref && !empty($conf->global->PRODUCT_GENERATE_REF_AFTER_FORM)) {
676 $ref = $modCodeProduct->getNextValue($object, $type);
680 $id = $object->create($user);
685 $categories =
GETPOST(
'categories',
'array');
686 $object->setCategories($categories);
688 if (!empty($backtopage)) {
689 $backtopage = preg_replace(
'/__ID__/', $object->id, $backtopage);
690 if (preg_match(
'/\?/', $backtopage)) {
691 $backtopage .=
'&socid='.$object->id;
693 header(
"Location: ".$backtopage);
696 header(
"Location: ".$_SERVER[
'PHP_SELF'].
"?id=".$id);
700 if (count($object->errors)) {
703 if ($object->error ==
'ErrorProductAlreadyExists') {
705 $reshook = $hookmanager->executeHooks(
'onProductAlreadyExists',
$parameters, $object, $action);
709 if ($object->error) {
724 if ($action ==
'update' && $usercancreate) {
725 if (
GETPOST(
'cancel',
'alpha')) {
728 if ($object->id > 0) {
729 $object->oldcopy = clone $object;
731 if (empty($conf->global->PRODUCT_GENERATE_REF_AFTER_FORM)) {
734 $object->label =
GETPOST(
'label', $label_security_check);
737 $object->description = $desc;
740 if (!empty($conf->global->MAIN_DISABLE_NOTES_TAB)) {
742 $object->note = $object->note_private;
744 $object->customcode =
GETPOST(
'customcode',
'alpha');
745 $object->country_id =
GETPOST(
'country_id',
'int');
746 $object->state_id =
GETPOST(
'state_id',
'int');
747 $object->lifetime =
GETPOST(
'lifetime',
'int');
748 $object->qc_frequency =
GETPOST(
'qc_frequency',
'int');
749 $object->status =
GETPOST(
'statut',
'int');
750 $object->status_buy =
GETPOST(
'statut_buy',
'int');
751 $object->status_batch =
GETPOST(
'status_batch',
'aZ09');
752 $object->batch_mask =
GETPOST(
'batch_mask',
'alpha');
753 $object->fk_default_warehouse =
GETPOST(
'fk_default_warehouse');
754 $object->fk_default_workstation =
GETPOST(
'fk_default_workstation');
760 $object->duration_value =
GETPOST(
'duration_value',
'int');
761 $object->duration_unit =
GETPOST(
'duration_unit',
'alpha');
763 $object->canvas =
GETPOST(
'canvas');
764 $object->net_measure =
GETPOST(
'net_measure');
765 $object->net_measure_units =
GETPOST(
'net_measure_units');
766 $object->weight =
GETPOST(
'weight');
767 $object->weight_units =
GETPOST(
'weight_units');
768 $object->length =
GETPOST(
'size');
769 $object->length_units =
GETPOST(
'size_units');
770 $object->width =
GETPOST(
'sizewidth');
771 $object->height =
GETPOST(
'sizeheight');
773 $object->surface =
GETPOST(
'surface');
774 $object->surface_units =
GETPOST(
'surface_units');
775 $object->volume =
GETPOST(
'volume');
776 $object->volume_units =
GETPOST(
'volume_units');
778 $finished =
GETPOST(
'finished',
'int');
779 if ($finished >= 0) {
780 $object->finished = $finished;
782 $object->finished =
null;
785 $fk_default_bom =
GETPOST(
'fk_default_bom',
'int');
786 if ($fk_default_bom >= 0) {
787 $object->fk_default_bom = $fk_default_bom;
789 $object->fk_default_bom =
null;
792 $units =
GETPOST(
'units',
'int');
794 $object->fk_unit = $units;
796 $object->fk_unit =
null;
799 $object->barcode_type =
GETPOST(
'fk_barcode_type');
800 $object->barcode =
GETPOST(
'barcode');
803 $stdobject->element =
'product';
804 $stdobject->barcode_type =
GETPOST(
'fk_barcode_type');
805 $result = $stdobject->fetch_barcode();
808 $mesg =
'Failed to get bar code type information ';
811 $object->barcode_type_code = $stdobject->barcode_type_code;
812 $object->barcode_type_coder = $stdobject->barcode_type_coder;
813 $object->barcode_type_label = $stdobject->barcode_type_label;
815 $accountancy_code_sell =
GETPOST(
'accountancy_code_sell',
'alpha');
816 $accountancy_code_sell_intra =
GETPOST(
'accountancy_code_sell_intra',
'alpha');
817 $accountancy_code_sell_export =
GETPOST(
'accountancy_code_sell_export',
'alpha');
818 $accountancy_code_buy =
GETPOST(
'accountancy_code_buy',
'alpha');
819 $accountancy_code_buy_intra =
GETPOST(
'accountancy_code_buy_intra',
'alpha');
820 $accountancy_code_buy_export =
GETPOST(
'accountancy_code_buy_export',
'alpha');
821 $checkmandatory =
GETPOST(
'mandatoryperiod',
'alpha');
822 if (empty($accountancy_code_sell) || $accountancy_code_sell ==
'-1') {
823 $object->accountancy_code_sell =
'';
825 $object->accountancy_code_sell = $accountancy_code_sell;
827 if (empty($accountancy_code_sell_intra) || $accountancy_code_sell_intra ==
'-1') {
828 $object->accountancy_code_sell_intra =
'';
830 $object->accountancy_code_sell_intra = $accountancy_code_sell_intra;
832 if (empty($accountancy_code_sell_export) || $accountancy_code_sell_export ==
'-1') {
833 $object->accountancy_code_sell_export =
'';
835 $object->accountancy_code_sell_export = $accountancy_code_sell_export;
837 if (empty($accountancy_code_buy) || $accountancy_code_buy ==
'-1') {
838 $object->accountancy_code_buy =
'';
840 $object->accountancy_code_buy = $accountancy_code_buy;
842 if (empty($accountancy_code_buy_intra) || $accountancy_code_buy_intra ==
'-1') {
843 $object->accountancy_code_buy_intra =
'';
845 $object->accountancy_code_buy_intra = $accountancy_code_buy_intra;
847 if (empty($accountancy_code_buy_export) || $accountancy_code_buy_export ==
'-1') {
848 $object->accountancy_code_buy_export =
'';
850 $object->accountancy_code_buy_export = $accountancy_code_buy_export;
852 if ($object->isService()) {
853 $object->mandatory_period = (!empty($checkmandatory)) ? 1 : 0 ;
859 $ret = $extrafields->setOptionalsFromPost(
null, $object,
'@GETPOSTISSET');
864 if (!$error && $object->check()) {
865 if ($object->update($object->id, $user) > 0) {
867 $categories =
GETPOST(
'categories',
'array');
868 $object->setCategories($categories);
872 if (count($object->errors)) {
880 if (count($object->errors)) {
883 setEventMessages($langs->trans(
"ErrorProductBadRefOrLabel"),
null,
'errors');
892 if ($action ==
'confirm_clone' && $confirm !=
'yes') {
895 if ($action ==
'confirm_clone' && $confirm ==
'yes' && $usercancreate) {
902 if ($object->id > 0) {
903 $object->ref =
GETPOST(
'clone_ref',
'alphanohtml');
905 $object->status_buy = 0;
907 $object->barcode = -1;
909 if ($object->check()) {
910 $object->context[
'createfromclone'] =
'createfromclone';
911 $id = $object->create($user);
913 if (
GETPOST(
'clone_composition')) {
914 $result = $object->clone_associations($originalId, $id);
919 header(
"Location: ".$_SERVER[
"PHP_SELF"].
"?id=".$originalId);
924 if (
GETPOST(
'clone_categories')) {
925 $result = $object->cloneCategories($originalId, $id);
930 header(
"Location: ".$_SERVER[
"PHP_SELF"].
"?id=".$originalId);
936 $result = $object->clone_price($originalId, $id);
941 header(
'Location: '.$_SERVER[
'PHP_SELF'].
'?id='.$originalId);
951 header(
"Location: ".$_SERVER[
"PHP_SELF"].
"?id=".$id);
956 if ($object->error ==
'ErrorProductAlreadyExists') {
962 $mesg = $langs->trans(
"ErrorProductAlreadyExists", $object->ref);
963 $mesg .=
' <a href="'.$_SERVER[
"PHP_SELF"].
'?ref='.$object->ref.
'">'.$langs->trans(
"ShowCardHere").
'</a>.';
968 if (count($object->errors)) {
978 unset($object->context[
'createfromclone']);
988 if ($action ==
'confirm_delete' && $confirm !=
'yes') {
991 if ($action ==
'confirm_delete' && $confirm ==
'yes' && $usercandelete) {
992 $result = $object->delete($user);
995 header(
'Location: '.DOL_URL_ROOT.
'/product/list.php?type='.$object->type.
'&delprod='.urlencode($object->ref));
1006 if ($object->id > 0 && $action ==
'addin') {
1008 if (
GETPOST(
'propalid') > 0) {
1009 $propal =
new Propal($db);
1010 $result = $propal->fetch(
GETPOST(
'propalid'));
1015 $thirpdartyid = $propal->socid;
1016 } elseif (
GETPOST(
'commandeid') > 0) {
1018 $result = $commande->fetch(
GETPOST(
'commandeid'));
1023 $thirpdartyid = $commande->socid;
1024 } elseif (
GETPOST(
'factureid') > 0) {
1026 $result = $facture->fetch(
GETPOST(
'factureid'));
1031 $thirpdartyid = $facture->socid;
1034 if ($thirpdartyid > 0) {
1036 $result = $soc->fetch($thirpdartyid);
1042 $desc = $object->description;
1046 if (empty($tva_tx)) {
1049 $localtax1_tx =
get_localtax($tva_tx, 1, $soc, $mysoc, $tva_npr);
1050 $localtax2_tx =
get_localtax($tva_tx, 2, $soc, $mysoc, $tva_npr);
1052 $pu_ht = $object->price;
1053 $pu_ttc = $object->price_ttc;
1054 $price_base_type = $object->price_base_type;
1057 if ($conf->global->PRODUIT_MULTIPRICES && $soc->price_level) {
1058 $pu_ht = $object->multiprices[$soc->price_level];
1059 $pu_ttc = $object->multiprices_ttc[$soc->price_level];
1060 $price_base_type = $object->multiprices_base_type[$soc->price_level];
1061 } elseif (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
1062 require_once DOL_DOCUMENT_ROOT.
'/product/class/productcustomerprice.class.php';
1066 $filter = array(
't.fk_product' => $object->id,
't.fk_soc' => $soc->id);
1068 $result = $prodcustprice->fetchAll(
'',
'', 0, 0, $filter);
1070 if (count($prodcustprice->lines) > 0) {
1071 $pu_ht =
price($prodcustprice->lines [0]->price);
1072 $pu_ttc =
price($prodcustprice->lines [0]->price_ttc);
1073 $price_base_type = $prodcustprice->lines [0]->price_base_type;
1074 $tva_tx = $prodcustprice->lines [0]->tva_tx;
1079 $tmpvat =
price2num(preg_replace(
'/\s*\(.*\)/',
'', $tva_tx));
1080 $tmpprodvat =
price2num(preg_replace(
'/\s*\(.*\)/',
'', $prod->tva_tx));
1084 if ($tmpvat != $tmpprodvat) {
1085 if ($price_base_type !=
'HT') {
1086 $pu_ht =
price2num($pu_ttc / (1 + ($tmpvat / 100)),
'MU');
1088 $pu_ttc =
price2num($pu_ht * (1 + ($tmpvat / 100)),
'MU');
1092 if (
GETPOST(
'propalid') > 0) {
1095 if (($result = $propal->defineBuyPrice($pu_ht,
price2num(
GETPOST(
'remise_percent'),
'', 2), $object->id)) < 0) {
1096 dol_syslog($langs->trans(
'FailedToGetCostPrice'));
1099 $buyprice = $result;
1102 $result = $propal->addline(
1127 header(
"Location: ".DOL_URL_ROOT.
"/comm/propal/card.php?id=".$propal->id);
1131 setEventMessages($langs->trans(
"ErrorUnknown").
": $result",
null,
'errors');
1132 } elseif (
GETPOST(
'commandeid') > 0) {
1135 if (($result = $commande->defineBuyPrice($pu_ht,
price2num(
GETPOST(
'remise_percent'),
'', 2), $object->id)) < 0) {
1136 dol_syslog($langs->trans(
'FailedToGetCostPrice'));
1139 $buyprice = $result;
1142 $result = $commande->addline(
1169 header(
"Location: ".DOL_URL_ROOT.
"/commande/card.php?id=".urlencode($commande->id));
1172 } elseif (
GETPOST(
'factureid') > 0) {
1175 if (($result = $facture->defineBuyPrice($pu_ht,
price2num(
GETPOST(
'remise_percent'),
'', 2), $object->id)) < 0) {
1176 dol_syslog($langs->trans(
'FailedToGetCostPrice'));
1179 $buyprice = $result;
1182 $result = $facture->addline(
1214 header(
"Location: ".DOL_URL_ROOT.
"/compta/facture/card.php?facid=".$facture->id);
1220 setEventMessages($langs->trans(
"WarningSelectOneDocument"),
null,
'warnings');
1240 $title = $langs->trans(
'ProductServiceCard');
1243 $shortlabel =
dol_trunc($object->label, 16);
1245 if ($action ==
'create') {
1246 $title = $langs->trans(
"NewProduct");
1248 $title = $langs->trans(
'Product').
" ".$shortlabel.
" - ".$langs->trans(
'Card');
1249 $help_url =
'EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos|DE:Modul_Produkte';
1253 if ($action ==
'create') {
1254 $title = $langs->trans(
"NewService");
1256 $title = $langs->trans(
'Service').
" ".$shortlabel.
" - ".$langs->trans(
'Card');
1257 $help_url =
'EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios|DE:Modul_Leistungen';
1265 if (
isModEnabled(
'barcode') && !empty($conf->global->BARCODE_PRODUCT_ADDON_NUM)) {
1266 $module = strtolower($conf->global->BARCODE_PRODUCT_ADDON_NUM);
1267 $dirbarcode = array_merge(array(
'/core/modules/barcode/'), $conf->modules_parts[
'barcode']);
1268 foreach ($dirbarcode as $dirroot) {
1275 $modBarCodeProduct =
new $module();
1279 if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
1283 if (empty($object->error) && $id) {
1284 $result = $object->fetch($id);
1289 $objcanvas->assign_values($action, $object->id, $object->ref);
1290 $objcanvas->display_canvas($action);
1295 if ($action ==
'create' && $usercancreate) {
1297 require_once DOL_DOCUMENT_ROOT.
'/core/class/doleditor.class.php';
1299 if (!empty($conf->use_javascript_ajax)) {
1300 print
'<script type="text/javascript">';
1301 print
'$(document).ready(function () {
1302 $("#selectcountry_id").change(function() {
1303 document.formprod.action.value="create";
1304 document.formprod.submit();
1307 print
'</script>'.
"\n";
1311 $module = (!empty($conf->global->PRODUCT_CODEPRODUCT_ADDON) ? $conf->global->PRODUCT_CODEPRODUCT_ADDON :
'mod_codeproduct_leopard');
1312 if (substr($module, 0, 16) ==
'mod_codeproduct_' && substr($module, -3) ==
'php') {
1313 $module = substr($module, 0,
dol_strlen($module) - 4);
1317 $modCodeProduct =
new $module();
1322 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'" method="POST" name="formprod">';
1323 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1324 print
'<input type="hidden" name="action" value="add">';
1325 print
'<input type="hidden" name="type" value="'.$type.
'">'.
"\n";
1326 if (!empty($modCodeProduct->code_auto)) {
1327 print
'<input type="hidden" name="code_auto" value="1">';
1329 if (!empty($modBarCodeProduct->code_auto)) {
1330 print
'<input type="hidden" name="barcode_auto" value="1">';
1332 print
'<input type="hidden" name="backtopage" value="'.$backtopage.
'">';
1336 $title = $langs->trans(
"NewService");
1339 $title = $langs->trans(
"NewProduct");
1346 if ($object->country_id > 0) {
1347 $tmparray =
getCountry($object->country_id,
'all');
1348 $object->country_code = $tmparray[
'code'];
1349 $object->country = $tmparray[
'label'];
1354 print
'<table class="border centpercent">';
1356 if (empty($conf->global->PRODUCT_GENERATE_REF_AFTER_FORM)) {
1359 if (!empty($modCodeProduct->code_auto)) {
1360 $tmpcode = $modCodeProduct->getNextValue($object, $type);
1362 print
'<td class="titlefieldcreate fieldrequired">'.$langs->trans(
"Ref").
'</td><td><input id="ref" name="ref" class="maxwidth200" maxlength="128" value="'.
dol_escape_htmltag(
GETPOSTISSET(
'ref') ?
GETPOST(
'ref',
'alphanohtml') : $tmpcode).
'">';
1363 if ($refalreadyexists) {
1364 print $langs->trans(
"RefAlreadyExists");
1370 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>';
1373 print
'<tr><td class="fieldrequired">'.$langs->trans(
"Status").
' ('.$langs->trans(
"Sell").
')</td><td>';
1374 $statutarray = array(
'1' => $langs->trans(
"OnSell"),
'0' => $langs->trans(
"NotOnSell"));
1375 print
$form->selectarray(
'statut', $statutarray,
GETPOST(
'statut'));
1379 print
'<tr><td class="fieldrequired">'.$langs->trans(
"Status").
' ('.$langs->trans(
"Buy").
')</td><td>';
1380 $statutarray = array(
'1' => $langs->trans(
"ProductStatusOnBuy"),
'0' => $langs->trans(
"ProductStatusNotOnBuy"));
1381 print
$form->selectarray(
'statut_buy', $statutarray,
GETPOST(
'statut_buy'));
1386 print
'<tr><td>'.$langs->trans(
"ManageLotSerial").
'</td><td>';
1387 $statutarray = array(
'0' => $langs->trans(
"ProductStatusNotOnBatch"),
'1' => $langs->trans(
"ProductStatusOnBatch"),
'2' => $langs->trans(
"ProductStatusOnSerial"));
1388 print
$form->selectarray(
'status_batch', $statutarray,
GETPOST(
'status_batch'));
1391 $status_batch =
GETPOST(
'status_batch');
1392 if ($status_batch !==
'0') {
1393 $langs->load(
"admin");
1394 $tooltip = $langs->trans(
"GenericMaskCodes", $langs->transnoentities(
"Batch"), $langs->transnoentities(
"Batch"));
1395 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes2");
1396 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes3");
1397 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes4a", $langs->transnoentities(
"Batch"), $langs->transnoentities(
"Batch"));
1398 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes5");
1399 if ((!empty($conf->global->PRODUCTBATCH_LOT_USE_PRODUCT_MASKS) && $conf->global->PRODUCTBATCH_LOT_ADDON ==
'mod_lot_advanced')
1400 || (!empty($conf->global->PRODUCTBATCH_SN_USE_PRODUCT_MASKS) && $conf->global->PRODUCTBATCH_SN_ADDON ==
'mod_sn_advanced')) {
1401 print
'<tr><td id="mask_option">'.$langs->trans(
"ManageLotMask").
'</td>';
1404 print
'<td id="field_mask">';
1405 print
$form->textwithpicto(
'<input type="text" class="flat minwidth175" name="batch_mask" id="batch_mask_input">', $tooltip, 1, 1);
1406 print
'<script type="text/javascript">
1407 $(document).ready(function() {
1408 $("#field_mask, #mask_option").addClass("hideobject");
1409 $("#status_batch").on("change", function () {
1410 console.log("We change batch status");
1411 var optionSelected = $("option:selected", this);
1412 var valueSelected = this.value;
1413 $("#field_mask, #mask_option").addClass("hideobject");
1417 if (this.value == 1) {
1418 $("#field_mask, #mask_option").toggleClass("hideobject");
1419 $("#batch_mask_input").val("'.$inherited_mask_lot.
'");
1423 if ($conf->global->PRODUCTBATCH_SN_USE_PRODUCT_MASKS && $conf->global->PRODUCTBATCH_SN_ADDON ==
'mod_sn_advanced') {
1425 if (this.value == 2) {
1426 $("#field_mask, #mask_option").toggleClass("hideobject");
1427 $("#batch_mask_input").val("'.$inherited_mask_sn.
'");
1440 $showbarcode = empty($conf->barcode->enabled) ? 0 : 1;
1441 if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->barcode->lire_advance)) {
1446 print
'<tr><td>'.$langs->trans(
'BarcodeType').
'</td><td>';
1448 $fk_barcode_type =
GETPOST(
'fk_barcode_type')?
GETPOST(
'fk_barcode_type'):0;
1450 if (empty($fk_barcode_type) && !empty($conf->global->PRODUIT_DEFAULT_BARCODE_TYPE)) {
1456 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formbarcode.class.php';
1458 print $formbarcode->selectBarcodeType($fk_barcode_type,
'fk_barcode_type', 1);
1461 print
'<td>'.$langs->trans(
"BarcodeValue").
'</td><td>';
1463 if (empty($tmpcode) && !empty($modBarCodeProduct->code_auto)) {
1464 $tmpcode = $modBarCodeProduct->getNextValue($object, $fk_barcode_type);
1466 print
'<input class="maxwidth100" type="text" name="barcode" value="'.dol_escape_htmltag($tmpcode).
'">';
1471 print
'<tr><td class="tdtop">'.$langs->trans(
"Description").
'</td><td>';
1472 $doleditor =
new DolEditor(
'desc',
GETPOST(
'desc',
'restricthtml'),
'', 160,
'dolibarr_details',
'',
false,
true,
getDolGlobalString(
'FCKEDITOR_ENABLE_DETAILS'), ROWS_4,
'90%');
1473 $doleditor->Create();
1476 if (empty($conf->global->PRODUCT_DISABLE_PUBLIC_URL)) {
1478 print
'<tr><td>'.$langs->trans(
"PublicUrl").
'</td><td>';
1479 print
img_picto(
'',
'globe',
'class="pictofixedwidth"');
1480 print
'<input type="text" name="url" class="quatrevingtpercent" value="'.GETPOST(
'url').
'">';
1486 print
'<tr><td>'.$langs->trans(
"DefaultWarehouse").
'</td><td>';
1487 print
img_picto($langs->trans(
"DefaultWarehouse"),
'stock',
'class="pictofixedwidth"');
1488 print $formproduct->selectWarehouses(
GETPOST(
'fk_default_warehouse',
'int'),
'fk_default_warehouse',
'warehouseopen', 1, 0, 0,
'', 0, 0, array(),
'minwidth300 widthcentpercentminusxx maxwidth500');
1489 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')).
'">';
1490 print
'<span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans(
"AddWarehouse").
'"></span>';
1495 if (empty($conf->global->PRODUCT_DISABLE_STOCK_LEVELS)) {
1497 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"StockLimit"), $langs->trans(
"StockLimitDesc"), 1).
'</td><td>';
1498 print
'<input name="seuil_stock_alerte" class="maxwidth50" value="'.GETPOST(
'seuil_stock_alerte').
'">';
1503 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"DesiredStock"), $langs->trans(
"DesiredStockDesc"), 1).
'</td><td>';
1504 print
'<input name="desiredstock" class="maxwidth50" value="'.GETPOST(
'desiredstock').
'">';
1508 if (empty($conf->global->PRODUCT_DISABLE_STOCK_LEVELS)) {
1509 print
'<input name="seuil_stock_alerte" type="hidden" value="0">';
1510 print
'<input name="desiredstock" type="hidden" value="0">';
1514 if ($type == 1 && $conf->workstation->enabled) {
1516 print
'<tr><td>'.$langs->trans(
"DefaultWorkstation").
'</td><td>';
1517 print
img_picto($langs->trans(
"DefaultWorkstation"),
'workstation',
'class="pictofixedwidth"');
1518 print $formproduct->selectWorkstations($object->fk_default_workstation,
'fk_default_workstation', 1);
1524 print
'<tr><td>'.$langs->trans(
"Duration").
'</td><td>';
1525 print
'<input name="duration_value" size="4" value="'.GETPOST(
'duration_value',
'int').
'">';
1526 print $formproduct->selectMeasuringUnits(
"duration_unit",
"time", (
GETPOSTISSET(
'duration_value') ?
GETPOST(
'duration_value',
'alpha') :
'h'), 0, 1);
1529 print
' ';
1530 print
'<input type="checkbox" id="mandatoryperiod" name="mandatoryperiod"'.($object->mandatory_period == 1 ?
' checked="checked"' :
'').
'>';
1531 print
'<label for="mandatoryperiod">';
1532 $htmltooltip = $langs->trans(
"mandatoryHelper");
1533 print
$form->textwithpicto($langs->trans(
"mandatoryperiod"), $htmltooltip, 1, 0);
1540 if (empty($conf->global->PRODUCT_DISABLE_NATURE)) {
1542 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"NatureOfProductShort"), $langs->trans(
"NatureOfProductDesc")).
'</td><td>';
1543 print $formproduct->selectProductNature(
'finished', $object->finished);
1549 if (empty($conf->global->PRODUCT_DISABLE_WEIGHT)) {
1551 print
'<tr><td>'.$langs->trans(
"Weight").
'</td><td>';
1552 print
'<input name="weight" size="4" value="'.GETPOST(
'weight').
'">';
1553 print $formproduct->selectMeasuringUnits(
"weight_units",
"weight",
GETPOSTISSET(
'weight_units') ?
GETPOST(
'weight_units',
'alpha') : (empty($conf->global->MAIN_WEIGHT_DEFAULT_UNIT) ? 0 : $conf->global->MAIN_WEIGHT_DEFAULT_UNIT), 0, 2);
1558 if (empty($conf->global->PRODUCT_DISABLE_SIZE)) {
1559 print
'<tr><td>'.$langs->trans(
"Length").
' x '.$langs->trans(
"Width").
' x '.$langs->trans(
"Height").
'</td><td>';
1560 print
'<input name="size" class="width50" value="'.GETPOST(
'size').
'"> x ';
1561 print
'<input name="sizewidth" class="width50" value="'.GETPOST(
'sizewidth').
'"> x ';
1562 print
'<input name="sizeheight" class="width50" value="'.GETPOST(
'sizeheight').
'">';
1563 print $formproduct->selectMeasuringUnits(
"size_units",
"size",
GETPOSTISSET(
'size_units') ?
GETPOST(
'size_units',
'alpha') :
'0', 0, 2);
1566 if (empty($conf->global->PRODUCT_DISABLE_SURFACE)) {
1568 print
'<tr><td>'.$langs->trans(
"Surface").
'</td><td>';
1569 print
'<input name="surface" size="4" value="'.GETPOST(
'surface').
'">';
1570 print $formproduct->selectMeasuringUnits(
"surface_units",
"surface",
GETPOSTISSET(
'surface_units') ?
GETPOST(
'surface_units',
'alpha') :
'0', 0, 2);
1573 if (empty($conf->global->PRODUCT_DISABLE_VOLUME)) {
1575 print
'<tr><td>'.$langs->trans(
"Volume").
'</td><td>';
1576 print
'<input name="volume" size="4" value="'.GETPOST(
'volume').
'">';
1577 print $formproduct->selectMeasuringUnits(
"volume_units",
"volume",
GETPOSTISSET(
'volume_units') ?
GETPOST(
'volume_units',
'alpha') :
'0', 0, 2);
1581 if (!empty($conf->global->PRODUCT_ADD_NET_MEASURE)) {
1583 print
'<tr><td>'.$langs->trans(
"NetMeasure").
'</td><td>';
1584 print
'<input name="net_measure" size="4" value="'.GETPOST(
'net_measure').
'">';
1585 print $formproduct->selectMeasuringUnits(
"net_measure_units",
'',
GETPOSTISSET(
'net_measure_units') ?
GETPOST(
'net_measure_units',
'alpha') : (empty($conf->global->MAIN_WEIGHT_DEFAULT_UNIT) ? 0 : $conf->global->MAIN_WEIGHT_DEFAULT_UNIT), 0, 0);
1591 if (!empty($conf->global->PRODUCT_USE_UNITS)) {
1592 print
'<tr><td>'.$langs->trans(
'DefaultUnitToShow').
'</td>';
1594 print
$form->selectUnits(empty($line->fk_unit) ? $conf->global->PRODUCT_USE_UNITS : $line->fk_unit,
'units');
1599 if (empty($conf->global->PRODUCT_DISABLE_CUSTOM_INFO) && empty($type)) {
1600 print
'<tr><td class="wordbreak">'.$langs->trans(
"CustomCode").
'</td><td><input name="customcode" class="maxwidth100onsmartphone" value="'.
GETPOST(
'customcode').
'"></td></tr>';
1603 print
'<tr><td>'.$langs->trans(
"CountryOrigin").
'</td>';
1605 print
img_picto(
'',
'globe-americas',
'class="paddingrightonly"');
1606 print
$form->select_country((
GETPOSTISSET(
'country_id') ?
GETPOST(
'country_id') : $object->country_id),
'country_id',
'', 0,
'minwidth300 widthcentpercentminusx maxwidth500');
1608 print
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1613 if (empty($conf->global->PRODUCT_DISABLE_STATE)) {
1615 if (!empty($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT) && ($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 1 || $conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 2)) {
1616 print
'<td>'.$form->editfieldkey(
'RegionStateOrigin',
'state_id',
'', $object, 0).
'</td><td>';
1618 print
'<td>'.$form->editfieldkey(
'StateOrigin',
'state_id',
'', $object, 0).
'</td><td>';
1621 print
img_picto(
'',
'state',
'class="pictofixedwidth"');
1622 print $formcompany->select_state($object->state_id, $object->country_code);
1628 if (!empty($conf->global->PRODUCT_LOT_ENABLE_QUALITY_CONTROL)) {
1629 print
'<tr><td>'.$langs->trans(
"LifeTime").
'</td><td><input name="lifetime" class="maxwidth50" value="'.
GETPOST(
'lifetime').
'"></td></tr>';
1630 print
'<tr><td>'.$langs->trans(
"QCFrequency").
'</td><td><input name="qc_frequency" class="maxwidth50" value="'.
GETPOST(
'qc_frequency').
'"></td></tr>';
1634 $parameters = array(
'colspan' =>
' colspan="2"',
'cols'=>2);
1635 $reshook = $hookmanager->executeHooks(
'formObjectOptions',
$parameters, $object, $action);
1636 print $hookmanager->resPrint;
1637 if (empty($reshook)) {
1638 print $object->showOptionals($extrafields,
'create',
$parameters);
1644 print
'<tr><td class="tdtop">'.$langs->trans(
"NoteNotVisibleOnBill").
'</td><td>';
1647 $doleditor =
new DolEditor(
'note_private',
GETPOST(
'note_private',
'restricthtml'),
'', 140,
'dolibarr_details',
'',
false,
true,
getDolGlobalString(
'FCKEDITOR_ENABLE_NOTE_PRIVATE'), ROWS_8,
'90%');
1648 $doleditor->Create();
1655 print
'<tr><td>'.$langs->trans(
"Categories").
'</td><td>';
1656 $cate_arbo =
$form->select_all_categories(Categorie::TYPE_PRODUCT,
'',
'parent', 64, 0, 1);
1657 print
img_picto(
'',
'category').$form->multiselectarray(
'categories', $cate_arbo,
GETPOST(
'categories',
'array'),
'', 0,
'quatrevingtpercent widthcentpercentminusx', 0, 0);
1665 if (empty($conf->global->PRODUCT_DISABLE_PRICES)) {
1666 if (!empty($conf->global->PRODUIT_MULTIPRICES)) {
1669 print
'<table class="border centpercent">';
1671 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"VATRate").
'</td><td>';
1673 print
$form->load_tva(
"tva_tx", $defaultva, $mysoc, $mysoc, 0, 0,
'',
false, 1);
1680 print
'<table class="border centpercent">';
1683 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"SellingPrice").
'</td>';
1684 print
'<td><input name="price" class="maxwidth50" value="'.$object->price.
'">';
1685 print
$form->selectPriceBaseType($conf->global->PRODUCT_PRICE_BASE_TYPE,
"price_base_type");
1689 print
'<tr><td>'.$langs->trans(
"MinPrice").
'</td>';
1690 print
'<td><input name="price_min" class="maxwidth50" value="'.$object->price_min.
'">';
1694 print
'<tr><td>'.$langs->trans(
"VATRate").
'</td><td>';
1696 print
$form->load_tva(
"tva_tx", $defaultva, $mysoc, $mysoc, 0, 0,
'',
false, 1);
1706 print
'<!-- accountancy codes -->'.
"\n";
1707 print
'<table class="border centpercent">';
1709 if (empty($conf->global->PRODUCT_DISABLE_ACCOUNTING)) {
1712 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellCode").
'</td>';
1719 print $formaccounting->select_account($accountancy_code_sell,
'accountancy_code_sell', 1,
null, 1, 1,
'minwidth150 maxwidth300', 1);
1723 if ($mysoc->isInEEC()) {
1724 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellIntraCode").
'</td>';
1727 $accountancy_code_sell_intra = (
GETPOSTISSET(
'accountancy_code_sell_intra') ?
GETPOST(
'accountancy_code_sell_intra',
'alpha') :
getDolGlobalString(
"ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT"));
1729 $accountancy_code_sell_intra = (
GETPOSTISSET(
'accountancy_code_sell_intra') ?
GETPOST(
'accountancy_code_sell_intra',
'alpha') :
getDolGlobalString(
"ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT"));
1731 print $formaccounting->select_account($accountancy_code_sell_intra,
'accountancy_code_sell_intra', 1,
null, 1, 1,
'minwidth150 maxwidth300', 1);
1736 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellExportCode").
'</td>';
1739 $accountancy_code_sell_export = (
GETPOST(
'accountancy_code_sell_export') ?
GETPOST(
'accountancy_code_sell_export',
'alpha') :
getDolGlobalString(
"ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT"));
1741 $accountancy_code_sell_export = (
GETPOST(
'accountancy_code_sell_export') ?
GETPOST(
'accountancy_code_sell_export',
'alpha') :
getDolGlobalString(
"ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT"));
1743 print $formaccounting->select_account($accountancy_code_sell_export,
'accountancy_code_sell_export', 1,
null, 1, 1,
'minwidth150 maxwidth300', 1);
1747 print
'<tr><td>'.$langs->trans(
"ProductAccountancyBuyCode").
'</td>';
1750 $accountancy_code_buy = (
GETPOST(
'accountancy_code_buy',
'alpha') ? (
GETPOST(
'accountancy_code_buy',
'alpha')) :
getDolGlobalString(
"ACCOUNTING_PRODUCT_BUY_ACCOUNT"));
1752 $accountancy_code_buy = (
GETPOST(
'accountancy_code_buy',
'alpha') ? (
GETPOST(
'accountancy_code_buy',
'alpha')) :
getDolGlobalString(
"ACCOUNTING_SERVICE_BUY_ACCOUNT"));
1754 print $formaccounting->select_account($accountancy_code_buy,
'accountancy_code_buy', 1,
null, 1, 1,
'minwidth150 maxwidth300', 1);
1758 if ($mysoc->isInEEC()) {
1759 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyIntraCode").
'</td>';
1762 $accountancy_code_buy_intra = (
GETPOSTISSET(
'accountancy_code_buy_intra') ?
GETPOST(
'accountancy_code_buy_intra',
'alpha') :
getDolGlobalString(
"ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT"));
1764 $accountancy_code_buy_intra = (
GETPOSTISSET(
'accountancy_code_buy_intra') ?
GETPOST(
'accountancy_code_buy_intra',
'alpha') :
getDolGlobalString(
"ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT"));
1766 print $formaccounting->select_account($accountancy_code_buy_intra,
'accountancy_code_buy_intra', 1,
null, 1, 1,
'minwidth150 maxwidth300', 1);
1771 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyExportCode").
'</td>';
1774 $accountancy_code_buy_export = (
GETPOST(
'accountancy_code_buy_export') ?
GETPOST(
'accountancy_code_buy_export',
'alpha') :
getDolGlobalString(
"ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT"));
1776 $accountancy_code_buy_export = (
GETPOST(
'accountancy_code_buy_export') ?
GETPOST(
'accountancy_code_buy_export',
'alpha') :
getDolGlobalString(
"ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT"));
1778 print $formaccounting->select_account($accountancy_code_buy_export,
'accountancy_code_buy_export', 1,
null, 1, 1,
'minwidth150 maxwidth300', 1);
1781 if (!empty($accountancy_code_sell)) {
1782 $object->accountancy_code_sell = $accountancy_code_sell;
1784 if (!empty($accountancy_code_sell_intra)) {
1785 $object->accountancy_code_sell_intra = $accountancy_code_sell_intra;
1787 if (!empty($accountancy_code_sell_export)) {
1788 $object->accountancy_code_sell_export = $accountancy_code_sell_export;
1790 if (!empty($accountancy_code_buy)) {
1791 $object->accountancy_code_buy = $accountancy_code_buy;
1793 if (!empty($accountancy_code_buy_intra)) {
1794 $object->accountancy_code_buy_intra = $accountancy_code_buy_intra;
1796 if (!empty($accountancy_code_buy_export)) {
1797 $object->accountancy_code_buy_export = $accountancy_code_buy_export;
1801 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellCode").
'</td>';
1802 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_sell" value="'.$object->accountancy_code_sell.
'">';
1806 if ($mysoc->isInEEC()) {
1807 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellIntraCode").
'</td>';
1808 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_sell_intra" value="'.$object->accountancy_code_sell_intra.
'">';
1813 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellExportCode").
'</td>';
1814 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_sell_export" value="'.$object->accountancy_code_sell_export.
'">';
1818 print
'<tr><td>'.$langs->trans(
"ProductAccountancyBuyCode").
'</td>';
1819 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_buy" value="'.$object->accountancy_code_buy.
'">';
1823 if ($mysoc->isInEEC()) {
1824 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyIntraCode").
'</td>';
1825 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_buy_intra" value="'.$object->accountancy_code_buy_intra.
'">';
1830 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyExportCode").
'</td>';
1831 print
'<td class="maxwidthonsmartphone"><input class="minwidth150" name="accountancy_code_buy_export" value="'.$object->accountancy_code_buy_export.
'">';
1839 print
$form->buttonsSaveCancel(
"Create");
1842 } elseif ($object->id > 0) {
1848 if ($action ==
'edit' && $usercancreate) {
1850 require_once DOL_DOCUMENT_ROOT.
'/core/class/doleditor.class.php';
1852 if (!empty($conf->use_javascript_ajax)) {
1853 print
'<script type="text/javascript">';
1854 print
'$(document).ready(function () {
1855 $("#selectcountry_id").change(function () {
1856 document.formprod.action.value="edit";
1857 document.formprod.submit();
1860 print
'</script>'.
"\n";
1864 $object->country_id =
GETPOST(
'country_id') ?
GETPOST(
'country_id') : $object->country_id;
1865 if ($object->country_id) {
1866 $tmparray =
getCountry($object->country_id,
'all');
1867 $object->country_code = $tmparray[
'code'];
1868 $object->country = $tmparray[
'label'];
1871 $type = $langs->trans(
'Product');
1872 if ($object->isService()) {
1873 $type = $langs->trans(
'Service');
1878 print
'<form action="'.$_SERVER[
'PHP_SELF'].
'?id='.$object->id.
'" method="POST" name="formprod">'.
"\n";
1879 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1880 print
'<input type="hidden" name="action" value="update">';
1881 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
1882 print
'<input type="hidden" name="canvas" value="'.$object->canvas.
'">';
1885 $titre = $langs->trans(
"CardProduct".$object->type);
1890 print
'<table class="border allwidth">';
1893 if (empty($conf->global->MAIN_PRODUCT_REF_NOT_EDITABLE)) {
1894 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>';
1896 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>';
1900 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>';
1903 print
'<tr><td class="fieldrequired">'.$langs->trans(
"Status").
' ('.$langs->trans(
"Sell").
')</td><td colspan="3">';
1904 print
'<select class="flat" name="statut">';
1906 print
'<option value="1" selected>'.$langs->trans(
"OnSell").
'</option>';
1907 print
'<option value="0">'.$langs->trans(
"NotOnSell").
'</option>';
1909 print
'<option value="1">'.$langs->trans(
"OnSell").
'</option>';
1910 print
'<option value="0" selected>'.$langs->trans(
"NotOnSell").
'</option>';
1916 print
'<tr><td class="fieldrequired">'.$langs->trans(
"Status").
' ('.$langs->trans(
"Buy").
')</td><td colspan="3">';
1917 print
'<select class="flat" name="statut_buy">';
1919 print
'<option value="1" selected>'.$langs->trans(
"ProductStatusOnBuy").
'</option>';
1920 print
'<option value="0">'.$langs->trans(
"ProductStatusNotOnBuy").
'</option>';
1922 print
'<option value="1">'.$langs->trans(
"ProductStatusOnBuy").
'</option>';
1923 print
'<option value="0" selected>'.$langs->trans(
"ProductStatusNotOnBuy").
'</option>';
1930 if ($object->isProduct() || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
1931 print
'<tr><td>'.$langs->trans(
"ManageLotSerial").
'</td><td>';
1932 $statutarray = array(
'0' => $langs->trans(
"ProductStatusNotOnBatch"),
'1' => $langs->trans(
"ProductStatusOnBatch"),
'2' => $langs->trans(
"ProductStatusOnSerial"));
1933 print
$form->selectarray(
'status_batch', $statutarray, (
GETPOSTISSET(
'status_batch') ?
GETPOST(
'status_batch') : $object->status_batch));
1935 if (!empty($object->status_batch) || !empty($conf->use_javascript_ajax)) {
1936 $langs->load(
"admin");
1937 $tooltip = $langs->trans(
"GenericMaskCodes", $langs->transnoentities(
"Batch"), $langs->transnoentities(
"Batch"));
1938 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes2");
1939 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes3");
1940 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes4a", $langs->transnoentities(
"Batch"), $langs->transnoentities(
"Batch"));
1941 $tooltip .=
'<br>'.$langs->trans(
"GenericMaskCodes5");
1942 print
'<tr><td id="mask_option">'.$langs->trans(
"ManageLotMask").
'</td>';
1944 $mask = !empty($object->batch_mask) ? $object->batch_mask :
getDolGlobalString(
'LOT_ADVANCED_MASK');
1947 $mask = !empty($object->batch_mask) ? $object->batch_mask :
getDolGlobalString(
'SN_ADVANCED_MASK');
1951 print
'<td id="field_mask">';
1952 print
$form->textwithpicto(
'<input type="text" class="flat minwidth175" name="batch_mask" id="batch_mask_input" value="'.$mask.
'">', $tooltip, 1, 1);
1954 if (!empty($conf->use_javascript_ajax)) {
1955 print
'<script type="text/javascript">
1956 $(document).ready(function() {
1957 $("#field_mask").parent().addClass("hideobject");
1958 var preselect = document.getElementById("status_batch");';
1960 print
'if (preselect.value == "2") {
1961 $("#field_mask").parent().removeClass("hideobject");
1965 print
'if (preselect.value == "1") {
1966 $("#field_mask").parent().removeClass("hideobject");
1969 print
'$("#status_batch").on("change", function () {
1970 var optionSelected = $("option:selected", this);
1971 var valueSelected = this.value;
1972 $("#field_mask").parent().addClass("hideobject");
1976 if (this.value == 1) {
1977 $("#field_mask").parent().removeClass("hideobject");
1978 $("#batch_mask_input").val("'.$inherited_mask_lot.
'");
1984 if (this.value == 2) {
1985 $("#field_mask").parent().removeClass("hideobject");
1986 $("#batch_mask_input").val("'.$inherited_mask_sn.
'");
2001 $showbarcode = empty($conf->barcode->enabled) ? 0 : 1;
2002 if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->barcode->lire_advance)) {
2007 print
'<tr><td>'.$langs->trans(
'BarcodeType').
'</td><td>';
2009 $fk_barcode_type =
GETPOST(
'fk_barcode_type');
2011 $fk_barcode_type = $object->barcode_type;
2012 if (empty($fk_barcode_type) && !empty($conf->global->PRODUIT_DEFAULT_BARCODE_TYPE)) {
2013 $fk_barcode_type = $conf->global->PRODUIT_DEFAULT_BARCODE_TYPE;
2016 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formbarcode.class.php';
2018 print $formbarcode->selectBarcodeType($fk_barcode_type,
'fk_barcode_type', 1);
2020 print
'<tr><td>'.$langs->trans(
"BarcodeValue").
'</td><td>';
2022 if (empty($tmpcode) && !empty($modBarCodeProduct->code_auto)) {
2023 $tmpcode = $modBarCodeProduct->getNextValue($object, $fk_barcode_type);
2025 print
'<input class="maxwidth150 maxwidthonsmartphone" type="text" name="barcode" value="'.dol_escape_htmltag($tmpcode).
'">';
2030 print
'<tr><td class="tdtop">'.$langs->trans(
"Description").
'</td><td>';
2033 $doleditor =
new DolEditor(
'desc',
GETPOSTISSET(
'desc') ?
GETPOST(
'desc',
'restricthtml') : $object->description,
'', 160,
'dolibarr_details',
'',
false,
true,
getDolGlobalInt(
'FCKEDITOR_ENABLE_DETAILS'), ROWS_4,
'90%');
2034 $doleditor->Create();
2040 if (empty($conf->global->PRODUCT_DISABLE_PUBLIC_URL)) {
2041 print
'<tr><td>'.$langs->trans(
"PublicUrl").
'</td><td>';
2042 print
img_picto(
'',
'globe',
'class="pictofixedwidth"');
2043 print
'<input type="text" name="url" class="quatrevingtpercent" value="'.(GETPOSTISSET(
'url') ?
GETPOST(
'url') : $object->url).
'">';
2050 print
'<tr><td>'.$langs->trans(
"DefaultWarehouse").
'</td><td>';
2051 print
img_picto($langs->trans(
"DefaultWarehouse"),
'stock',
'class="pictofixedwidth"');
2052 print $formproduct->selectWarehouses((
GETPOSTISSET(
'fk_default_warehouse') ?
GETPOST(
'fk_default_warehouse') : $object->fk_default_warehouse),
'fk_default_warehouse',
'warehouseopen', 1);
2053 print
' <a href="'.DOL_URL_ROOT.
'/product/stock/card.php?action=create&backtopage='.urlencode($_SERVER[
'PHP_SELF'].
'?action=edit&id='.((
int) $object->id)).
'">';
2054 print
'<span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans(
"AddWarehouse").
'"></span></a>';
2067 if ($object->isService() && $conf->workstation->enabled) {
2069 print
'<tr><td>'.$langs->trans(
"DefaultWorkstation").
'</td><td>';
2070 print
img_picto($langs->trans(
"DefaultWorkstation"),
'workstation',
'class="pictofixedwidth"');
2071 print $formproduct->selectWorkstations($object->fk_default_workstation,
'fk_default_workstation', 1);
2082 if ($object->isService()) {
2084 print
'<tr><td>'.$langs->trans(
"Duration").
'</td><td>';
2085 print
'<input name="duration_value" size="5" value="'.$object->duration_value.
'"> ';
2086 print $formproduct->selectMeasuringUnits(
"duration_unit",
"time", $object->duration_unit, 0, 1);
2089 print
' ';
2090 print
'<input type="checkbox" id="mandatoryperiod" name="mandatoryperiod"'.($object->mandatory_period == 1 ?
' checked="checked"' :
'').
'>';
2091 print
'<label for="mandatoryperiod">';
2092 $htmltooltip = $langs->trans(
"mandatoryHelper");
2093 print
$form->textwithpicto($langs->trans(
"mandatoryperiod"), $htmltooltip, 1, 0);
2098 if (empty($conf->global->PRODUCT_DISABLE_NATURE)) {
2100 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"NatureOfProductShort"), $langs->trans(
"NatureOfProductDesc")).
'</td><td>';
2101 print $formproduct->selectProductNature(
'finished', (
GETPOSTISSET(
'finished') ?
GETPOST(
'finished') : $object->finished));
2107 print
'<tr><td>'.$form->textwithpicto($langs->trans(
"DefaultBOM"), $langs->trans(
"DefaultBOMDesc", $langs->transnoentitiesnoconv(
"Finished"))).
'</td><td>';
2108 $bomkey =
"Bom:bom/class/bom.class.php:0:(t.status:=:1) AND (t.fk_product:=:".((int) $object->id).
')';
2109 print
$form->selectForForms($bomkey,
'fk_default_bom', (
GETPOSTISSET(
'fk_default_bom') ?
GETPOST(
'fk_default_bom') : $object->fk_default_bom), 1);
2113 if (!$object->isService()) {
2114 if (empty($conf->global->PRODUCT_DISABLE_WEIGHT)) {
2116 print
'<tr><td>'.$langs->trans(
"Weight").
'</td><td>';
2117 print
'<input name="weight" size="5" value="'.(GETPOSTISSET(
'weight') ?
GETPOST(
'weight') : $object->weight).
'"> ';
2118 print $formproduct->selectMeasuringUnits(
"weight_units",
"weight",
GETPOSTISSET(
'weight_units') ?
GETPOST(
'weight_units') : $object->weight_units, 0, 2);
2122 if (empty($conf->global->PRODUCT_DISABLE_SIZE)) {
2124 print
'<tr><td>'.$langs->trans(
"Length").
' x '.$langs->trans(
"Width").
' x '.$langs->trans(
"Height").
'</td><td>';
2125 print
'<input name="size" size="5" value="'.(GETPOSTISSET(
'size') ?
GETPOST(
'size') : $object->length).
'">x';
2126 print
'<input name="sizewidth" size="5" value="'.(GETPOSTISSET(
'sizewidth') ?
GETPOST(
'sizewidth') : $object->width).
'">x';
2127 print
'<input name="sizeheight" size="5" value="'.(GETPOSTISSET(
'sizeheight') ?
GETPOST(
'sizeheight') : $object->height).
'"> ';
2128 print $formproduct->selectMeasuringUnits(
"size_units",
"size",
GETPOSTISSET(
'size_units') ?
GETPOST(
'size_units') : $object->length_units, 0, 2);
2131 if (empty($conf->global->PRODUCT_DISABLE_SURFACE)) {
2133 print
'<tr><td>'.$langs->trans(
"Surface").
'</td><td>';
2134 print
'<input name="surface" size="5" value="'.(GETPOSTISSET(
'surface') ?
GETPOST(
'surface') : $object->surface).
'"> ';
2135 print $formproduct->selectMeasuringUnits(
"surface_units",
"surface",
GETPOSTISSET(
'surface_units') ?
GETPOST(
'surface_units') : $object->surface_units, 0, 2);
2138 if (empty($conf->global->PRODUCT_DISABLE_VOLUME)) {
2140 print
'<tr><td>'.$langs->trans(
"Volume").
'</td><td>';
2141 print
'<input name="volume" size="5" value="'.(GETPOSTISSET(
'volume') ?
GETPOST(
'volume') : $object->volume).
'"> ';
2142 print $formproduct->selectMeasuringUnits(
"volume_units",
"volume",
GETPOSTISSET(
'volume_units') ?
GETPOST(
'volume_units') : $object->volume_units, 0, 2);
2146 if (!empty($conf->global->PRODUCT_ADD_NET_MEASURE)) {
2148 print
'<tr><td>'.$langs->trans(
"NetMeasure").
'</td><td>';
2149 print
'<input name="net_measure" size="5" value="'.(GETPOSTISSET(
'net_measure') ?
GETPOST(
'net_measure') : $object->net_measure).
'"> ';
2150 print $formproduct->selectMeasuringUnits(
"net_measure_units",
"",
GETPOSTISSET(
'net_measure_units') ?
GETPOST(
'net_measure_units') : $object->net_measure_units, 0, 0);
2155 if (!empty($conf->global->PRODUCT_USE_UNITS)) {
2156 print
'<tr><td>'.$langs->trans(
'DefaultUnitToShow').
'</td>';
2158 print
$form->selectUnits($object->fk_unit,
'units');
2163 if (!$object->isService() && empty($conf->global->PRODUCT_DISABLE_CUSTOM_INFO)) {
2164 print
'<tr><td class="wordbreak">'.$langs->trans(
"CustomCode").
'</td><td><input name="customcode" class="maxwidth100onsmartphone" value="'.(
GETPOSTISSET(
'customcode') ?
GETPOST(
'customcode') : $object->customcode).
'"></td></tr>';
2166 print
'<tr><td>'.$langs->trans(
"CountryOrigin").
'</td>';
2168 print
img_picto(
'',
'globe-americas',
'class="paddingrightonly"');
2169 print
$form->select_country(
GETPOSTISSET(
'country_id') ?
GETPOST(
'country_id',
'int') : $object->country_id,
'country_id',
'', 0,
'minwidth100 maxwidthonsmartphone');
2171 print
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
2176 if (empty($conf->global->PRODUCT_DISABLE_STATE)) {
2178 if (!empty($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT) && ($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 1 || $conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 2)) {
2179 print
'<td>'.$form->editfieldkey(
'RegionStateOrigin',
'state_id',
'', $object, 0).
'</td><td>';
2181 print
'<td>'.$form->editfieldkey(
'StateOrigin',
'state_id',
'', $object, 0).
'</td><td>';
2184 print
img_picto(
'',
'state',
'class="pictofixedwidth"');
2185 print $formcompany->select_state(
GETPOSTISSET(
'state_id') ?
GETPOST(
'state_id',
'int') : $object->state_id, $object->country_code);
2192 if (!empty($conf->global->PRODUCT_LOT_ENABLE_QUALITY_CONTROL)) {
2193 print
'<tr><td>'.$langs->trans(
"LifeTime").
'</td><td><input name="lifetime" class="maxwidth100onsmartphone" value="'.$object->lifetime.
'"></td></tr>';
2194 print
'<tr><td>'.$langs->trans(
"QCFrequency").
'</td><td><input name="qc_frequency" class="maxwidth100onsmartphone" value="'.$object->qc_frequency.
'"></td></tr>';
2198 $parameters = array(
'colspan' =>
' colspan="2"',
'cols' => 2);
2199 $reshook = $hookmanager->executeHooks(
'formObjectOptions',
$parameters, $object, $action);
2200 print $hookmanager->resPrint;
2201 if (empty($reshook)) {
2202 print $object->showOptionals($extrafields,
'edit',
$parameters);
2207 print
'<tr><td>'.$langs->trans(
"Categories").
'</td><td>';
2208 $cate_arbo =
$form->select_all_categories(Categorie::TYPE_PRODUCT,
'',
'parent', 64, 0, 1);
2210 $cats = $c->containing($object->id, Categorie::TYPE_PRODUCT);
2211 $arrayselected = array();
2212 if (is_array($cats)) {
2213 foreach ($cats as $cat) {
2214 $arrayselected[] = $cat->id;
2218 foreach (
GETPOST(
'categories',
'array') as $cat) {
2219 $arrayselected[] = $cat;
2222 print
img_picto(
'',
'category').$form->multiselectarray(
'categories', $cate_arbo, $arrayselected,
'', 0,
'quatrevingtpercent widthcentpercentminusx', 0, 0);
2227 if (!empty($conf->global->MAIN_DISABLE_NOTES_TAB)) {
2228 print
'<tr><td class="tdtop">'.$langs->trans(
"NoteNotVisibleOnBill").
'</td><td>';
2230 $doleditor =
new DolEditor(
'note_private', $object->note_private,
'', 140,
'dolibarr_notes',
'',
false,
true,
getDolGlobalInt(
'FCKEDITOR_ENABLE_NOTE_PRIVATE'), ROWS_4,
'90%');
2231 $doleditor->Create();
2240 print
'<table class="border centpercent">';
2242 if (empty($conf->global->PRODUCT_DISABLE_ACCOUNTING)) {
2245 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellCode").
'</td>';
2247 print $formaccounting->select_account((
GETPOSTISSET(
'accountancy_code_sell') ?
GETPOST(
'accountancy_code_sell') : $object->accountancy_code_sell),
'accountancy_code_sell', 1,
'', 1, 1,
'minwidth150 maxwidth300');
2251 if ($mysoc->isInEEC()) {
2252 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellIntraCode").
'</td>';
2254 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');
2259 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellExportCode").
'</td>';
2261 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');
2265 print
'<tr><td>'.$langs->trans(
"ProductAccountancyBuyCode").
'</td>';
2267 print $formaccounting->select_account((
GETPOSTISSET(
'accountancy_code_buy') ?
GETPOST(
'accountancy_code_buy') : $object->accountancy_code_buy),
'accountancy_code_buy', 1,
'', 1, 1,
'minwidth150 maxwidth300');
2271 if ($mysoc->isInEEC()) {
2272 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyIntraCode").
'</td>';
2274 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');
2279 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyExportCode").
'</td>';
2281 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');
2286 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellCode").
'</td>';
2287 print
'<td><input name="accountancy_code_sell" class="maxwidth200" value="'.(GETPOSTISSET(
'accountancy_code_sell') ?
GETPOST(
'accountancy_code_sell') : $object->accountancy_code_sell).
'">';
2291 if ($mysoc->isInEEC()) {
2292 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellIntraCode").
'</td>';
2293 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).
'">';
2298 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancySellExportCode").
'</td>';
2299 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).
'">';
2303 print
'<tr><td>'.$langs->trans(
"ProductAccountancyBuyCode").
'</td>';
2304 print
'<td><input name="accountancy_code_buy" class="maxwidth200" value="'.(GETPOSTISSET(
'accountancy_code_buy') ?
GETPOST(
'accountancy_code_buy') : $object->accountancy_code_buy).
'">';
2308 if ($mysoc->isInEEC()) {
2309 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyIntraCode").
'</td>';
2310 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).
'">';
2315 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"ProductAccountancyBuyExportCode").
'</td>';
2316 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).
'">';
2324 print
$form->buttonsSaveCancel();
2330 $showbarcode = empty($conf->barcode->enabled) ? 0 : 1;
2331 if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->barcode->lire_advance)) {
2336 $titre = $langs->trans(
"CardProduct".$object->type);
2341 $linkback =
'<a href="'.DOL_URL_ROOT.
'/product/list.php?restore_lastsearch_values=1&type='.$object->type.
'">'.$langs->trans(
"BackToList").
'</a>';
2342 $object->next_prev_filter =
" fk_product_type = ".$object->type;
2345 if ($user->socid && !in_array(
'product', explode(
',', $conf->global->MAIN_MODULES_FOR_EXTERNAL))) {
2352 print
'<div class="fichecenter">';
2353 print
'<div class="fichehalfleft">';
2355 print
'<div class="underbanner clearboth"></div>';
2356 print
'<table class="border tableforfield centpercent">';
2360 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
2361 print
'<tr><td class="titlefield">';
2362 print (empty($conf->global->PRODUCT_DENY_CHANGE_PRODUCT_TYPE)) ?
$form->editfieldkey(
"Type",
'fk_product_type', $object->type, $object, $usercancreate, $typeformat) : $langs->trans(
'Type');
2364 print
$form->editfieldval(
"Type",
'fk_product_type', $object->type, $object, $usercancreate, $typeformat);
2370 print
'<tr><td class="nowrap">';
2371 print
'<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
2372 print $langs->trans(
"BarcodeType");
2374 if (($action !=
'editbarcodetype') && $usercancreate && $createbarcode) {
2375 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>';
2377 print
'</tr></table>';
2379 if ($action ==
'editbarcodetype' || $action ==
'editbarcode') {
2380 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formbarcode.class.php';
2384 $fk_barcode_type =
'';
2385 if ($action ==
'editbarcodetype') {
2386 print $formbarcode->formBarcodeType($_SERVER[
'PHP_SELF'].
'?id='.$object->id, $object->barcode_type,
'fk_barcode_type');
2387 $fk_barcode_type = $object->barcode_type;
2389 $object->fetch_barcode();
2390 $fk_barcode_type = $object->barcode_type;
2391 print $object->barcode_type_label ? $object->barcode_type_label : ($object->barcode ?
'<div class="warning">'.$langs->trans(
"SetDefaultBarcodeType").
'<div>' :
'');
2393 print
'</td></tr>'.
"\n";
2396 print
'<tr><td class="nowrap">';
2397 print
'<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
2398 print $langs->trans(
"BarcodeValue");
2400 if (($action !=
'editbarcode') && $usercancreate && $createbarcode) {
2401 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>';
2403 print
'</tr></table>';
2405 if ($action ==
'editbarcode') {
2407 if (empty($tmpcode) && !empty($modBarCodeProduct->code_auto)) {
2408 $tmpcode = $modBarCodeProduct->getNextValue($object, $fk_barcode_type);
2411 print
'<form method="post" action="'.$_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'">';
2412 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2413 print
'<input type="hidden" name="action" value="setbarcode">';
2414 print
'<input type="hidden" name="barcode_type_code" value="'.$object->barcode_type_code.
'">';
2415 print
'<input size="40" class="maxwidthonsmartphone" type="text" name="barcode" value="'.$tmpcode.
'">';
2416 print
' <input type="submit" class="button smallpaddingimp" value="'.$langs->trans(
"Modify").
'">';
2421 print
'</td></tr>'.
"\n";
2426 if ($object->isProduct() || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
2427 print
'<tr><td>'.$langs->trans(
"ManageLotSerial").
'</td><td>';
2428 print $object->getLibStatut(0, 2);
2430 if ((($object->status_batch ==
'1' && !empty($conf->global->PRODUCTBATCH_LOT_USE_PRODUCT_MASKS) && $conf->global->PRODUCTBATCH_LOT_ADDON ==
'mod_lot_advanced')
2431 || ($object->status_batch ==
'2' && $conf->global->PRODUCTBATCH_SN_ADDON ==
'mod_sn_advanced' && !empty($conf->global->PRODUCTBATCH_SN_USE_PRODUCT_MASKS)))) {
2432 print
'<tr><td>'.$langs->trans(
"ManageLotMask").
'</td><td>';
2433 print $object->batch_mask;
2439 if (empty($conf->global->PRODUCT_DISABLE_ACCOUNTING)) {
2441 print
'<tr><td class="nowrap">';
2442 print $langs->trans(
"ProductAccountancySellCode");
2445 if (!empty($object->accountancy_code_sell)) {
2447 $accountingaccount->fetch(
'', $object->accountancy_code_sell, 1);
2449 print $accountingaccount->getNomUrl(0, 1, 1,
'', 1);
2452 print $object->accountancy_code_sell;
2457 if ($mysoc->isInEEC()) {
2458 print
'<tr><td class="nowrap">';
2459 print $langs->trans(
"ProductAccountancySellIntraCode");
2462 if (!empty($object->accountancy_code_sell_intra)) {
2464 $accountingaccount2->fetch(
'', $object->accountancy_code_sell_intra, 1);
2466 print $accountingaccount2->getNomUrl(0, 1, 1,
'', 1);
2469 print $object->accountancy_code_sell_intra;
2475 print
'<tr><td class="nowrap">';
2476 print $langs->trans(
"ProductAccountancySellExportCode");
2479 if (!empty($object->accountancy_code_sell_export)) {
2481 $accountingaccount3->fetch(
'', $object->accountancy_code_sell_export, 1);
2483 print $accountingaccount3->getNomUrl(0, 1, 1,
'', 1);
2486 print $object->accountancy_code_sell_export;
2491 print
'<tr><td class="nowrap">';
2492 print $langs->trans(
"ProductAccountancyBuyCode");
2495 if (!empty($object->accountancy_code_buy)) {
2497 $accountingaccount4->fetch(
'', $object->accountancy_code_buy, 1);
2499 print $accountingaccount4->getNomUrl(0, 1, 1,
'', 1);
2502 print $object->accountancy_code_buy;
2507 if ($mysoc->isInEEC()) {
2508 print
'<tr><td class="nowrap">';
2509 print $langs->trans(
"ProductAccountancyBuyIntraCode");
2512 if (!empty($object->accountancy_code_buy_intra)) {
2514 $accountingaccount5->fetch(
'', $object->accountancy_code_buy_intra, 1);
2516 print $accountingaccount5->getNomUrl(0, 1, 1,
'', 1);
2519 print $object->accountancy_code_buy_intra;
2525 print
'<tr><td class="nowrap">';
2526 print $langs->trans(
"ProductAccountancyBuyExportCode");
2529 if (!empty($object->accountancy_code_buy_export)) {
2531 $accountingaccount6->fetch(
'', $object->accountancy_code_buy_export, 1);
2533 print $accountingaccount6->getNomUrl(0, 1, 1,
'', 1);
2536 print $object->accountancy_code_buy_export;
2542 print
'<tr><td class="tdtop">'.$langs->trans(
"Description").
'</td><td>'.(
dol_textishtml($object->description) ? $object->description :
dol_nl2br($object->description, 1,
true)).
'</td></tr>';
2545 if (empty($conf->global->PRODUCT_DISABLE_PUBLIC_URL)) {
2546 print
'<tr><td>'.$langs->trans(
"PublicUrl").
'</td><td>';
2554 $warehouse->fetch($object->fk_default_warehouse);
2556 print
'<tr><td>'.$langs->trans(
"DefaultWarehouse").
'</td><td>';
2557 print (!empty($warehouse->id) ? $warehouse->getNomUrl(1) :
'');
2561 if ($object->isService() &&
isModEnabled(
'workstation')) {
2563 $res = $workstation->fetch($object->fk_default_workstation);
2565 print
'<tr><td>'.$langs->trans(
"DefaultWorkstation").
'</td><td>';
2566 print (!empty($workstation->id) ? $workstation->getNomUrl(1) :
'');
2571 if (
isModEnabled(
'variants') && ($object->isProduct() || $object->isService())) {
2574 if ($combination->fetchByFkProductChild($object->id) > 0) {
2575 $prodstatic =
new Product($db);
2576 $prodstatic->fetch($combination->fk_product_parent);
2579 print
'<tr><td>'.$langs->trans(
"ParentProduct").
'</td><td>';
2580 print $prodstatic->getNomUrl(1);
2587 print
'<div class="fichehalfright">';
2589 print
'<div class="underbanner clearboth"></div>';
2590 print
'<table class="border tableforfield centpercent">';
2592 if ($object->isService()) {
2594 print
'<tr><td class="titlefield">'.$langs->trans(
"Duration").
'</td><td>';
2595 print $object->duration_value;
2596 if ($object->duration_value > 1) {
2597 $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"));
2598 } elseif ($object->duration_value > 0) {
2599 $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"));
2601 print (!empty($object->duration_unit) && isset($dur[$object->duration_unit]) ?
" ".$langs->trans($dur[$object->duration_unit]).
" " :
'');
2604 if ($object->duration_value > 0) {
2605 print
' ';
2607 $htmltooltip = $langs->trans(
"mandatoryHelper");
2608 print
'<input type="checkbox" class="" name="mandatoryperiod"'.($object->mandatory_period == 1 ?
' checked="checked"' :
'').
' disabled>';
2609 print
$form->textwithpicto($langs->trans(
"mandatoryperiod"), $htmltooltip, 1, 0);
2613 if (empty($conf->global->PRODUCT_DISABLE_NATURE)) {
2615 print
'<tr><td class="titlefield">'.$form->textwithpicto($langs->trans(
"NatureOfProductShort"), $langs->trans(
"NatureOfProductDesc")).
'</td><td>';
2616 print $object->getLibFinished();
2621 if (!$object->isService() &&
isModEnabled(
'bom') && $object->finished) {
2622 print
'<tr><td class="titlefield">'.$form->textwithpicto($langs->trans(
"DefaultBOM"), $langs->trans(
"DefaultBOMDesc", $langs->transnoentitiesnoconv(
"Finished"))).
'</td><td>';
2623 if ($object->fk_default_bom) {
2624 $bom_static =
new BOM($db);
2625 $bom_static->fetch($object->fk_default_bom);
2626 print $bom_static->getNomUrl(1);
2631 if (!$object->isService()) {
2633 if (empty($conf->global->PRODUCT_DISABLE_WEIGHT)) {
2634 print
'<tr><td class="titlefield">'.$langs->trans(
"Weight").
'</td><td>';
2635 if ($object->weight !=
'') {
2640 print
"</td></tr>\n";
2643 if (empty($conf->global->PRODUCT_DISABLE_SIZE)) {
2645 print
'<tr><td>'.$langs->trans(
"Length").
' x '.$langs->trans(
"Width").
' x '.$langs->trans(
"Height").
'</td><td>';
2646 if ($object->length !=
'' || $object->width !=
'' || $object->height !=
'') {
2647 print $object->length;
2648 if ($object->width) {
2649 print
" x ".$object->width;
2651 if ($object->height) {
2652 print
" x ".$object->height;
2654 print
' '.measuringUnitString(0,
"size", $object->length_units);
2658 print
"</td></tr>\n";
2660 if (empty($conf->global->PRODUCT_DISABLE_SURFACE)) {
2662 print
'<tr><td>'.$langs->trans(
"Surface").
'</td><td>';
2663 if ($object->surface !=
'') {
2668 print
"</td></tr>\n";
2670 if (empty($conf->global->PRODUCT_DISABLE_VOLUME)) {
2672 print
'<tr><td>'.$langs->trans(
"Volume").
'</td><td>';
2673 if ($object->volume !=
'') {
2678 print
"</td></tr>\n";
2681 if (!empty($conf->global->PRODUCT_ADD_NET_MEASURE)) {
2683 print
'<tr><td class="titlefield">'.$langs->trans(
"NetMeasure").
'</td><td>';
2684 if ($object->net_measure !=
'') {
2694 if (!empty($conf->global->PRODUCT_USE_UNITS)) {
2695 $unit = $object->getLabelOfUnit();
2697 print
'<tr><td>'.$langs->trans(
'DefaultUnitToShow').
'</td><td>';
2699 print $langs->trans($unit);
2705 if (!$object->isService() && empty($conf->global->PRODUCT_DISABLE_CUSTOM_INFO)) {
2706 print
'<tr><td>'.$langs->trans(
"CustomCode").
'</td><td>'.$object->customcode.
'</td></tr>';
2709 print
'<tr><td>'.$langs->trans(
"Origin").
'</td><td>'.
getCountry($object->country_id, 0, $db);
2710 if (!empty($object->state_id)) {
2711 print
' - '.getState($object->state_id, 0, $db);
2717 if (!empty($conf->global->PRODUCT_LOT_ENABLE_QUALITY_CONTROL)) {
2718 print
'<tr><td>'.$langs->trans(
"LifeTime").
'</td><td>'.$object->lifetime.
'</td></tr>';
2719 print
'<tr><td>'.$langs->trans(
"QCFrequency").
'</td><td>'.$object->qc_frequency.
'</td></tr>';
2724 include DOL_DOCUMENT_ROOT.
'/core/tpl/extrafields_view.tpl.php';
2728 print
'<tr><td class="valignmiddle">'.$langs->trans(
"Categories").
'</td><td>';
2729 print
$form->showCategories($object->id, Categorie::TYPE_PRODUCT, 1);
2734 if (!empty($conf->global->MAIN_DISABLE_NOTES_TAB)) {
2735 print
'<!-- show Note --> '.
"\n";
2736 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";
2737 print
'<!-- End show Note --> '.
"\n";
2744 print
'<div style="clear:both"></div>';
2748 } elseif ($action !=
'create') {
2754 if (!empty($modCodeProduct->code_auto)) {
2755 $tmpcode = $modCodeProduct->getNextValue($object, $object->type);
2761 if (($action ==
'delete' && (empty($conf->use_javascript_ajax) || !empty($conf->dol_use_jmobile)))
2762 || (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile))) {
2763 $formconfirm =
$form->formconfirm(
"card.php?id=".$object->id, $langs->trans(
"DeleteProduct"), $langs->trans(
"ConfirmDeleteProduct"),
"confirm_delete",
'', 0,
"action-delete");
2765 if ($action ==
'merge') {
2766 $formquestion = array(
2768 'name' =>
'product_origin',
2769 'label' => $langs->trans(
'MergeOriginProduct'),
2771 'value' =>
$form->select_produits(
'',
'product_origin',
'', 0, 0, 1, 2,
'', 1, array(), 0, 1, 0,
'minwidth200', 0,
'',
null, 1),
2774 $formconfirm =
$form->formconfirm($_SERVER[
"PHP_SELF"].
"?id=".$object->id, $langs->trans(
"MergeProducts"), $langs->trans(
"ConfirmMergeProducts"),
"confirm_merge", $formquestion,
'no', 1, 250);
2778 if (($action ==
'clone' && (empty($conf->use_javascript_ajax) || !empty($conf->dol_use_jmobile)))
2779 || (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile))) {
2781 $formquestionclone = array(
2782 'text' => $langs->trans(
"ConfirmClone"),
2783 array(
'type' =>
'text',
'name' =>
'clone_ref',
'label' => $langs->trans(
"NewRefForClone"),
'value' => empty($tmpcode) ? $langs->trans(
"CopyOf").
' '.$object->ref : $tmpcode,
'morecss'=>
'width150'),
2784 array(
'type' =>
'checkbox',
'name' =>
'clone_content',
'label' => $langs->trans(
"CloneContentProduct"),
'value' => 1),
2785 array(
'type' =>
'checkbox',
'name' =>
'clone_categories',
'label' => $langs->trans(
"CloneCategoriesProduct"),
'value' => 1),
2787 if (!empty($conf->global->PRODUIT_MULTIPRICES)) {
2788 $formquestionclone[] = array(
'type' =>
'checkbox',
'name' =>
'clone_prices',
'label' => $langs->trans(
"ClonePricesProduct").
' ('.$langs->trans(
"CustomerPrices").
')',
'value' => 0);
2790 if (!empty($conf->global->PRODUIT_SOUSPRODUITS)) {
2791 $formquestionclone[] = array(
'type' =>
'checkbox',
'name' =>
'clone_composition',
'label' => $langs->trans(
'CloneCompositionProduct'),
'value' => 1);
2794 $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);
2799 $reshook = $hookmanager->executeHooks(
'formConfirm',
$parameters, $object, $action);
2800 if (empty($reshook)) {
2802 } elseif ($reshook > 0) {
2812 if ($action !=
'create' && $action !=
'edit') {
2813 $cloneProductUrl = $_SERVER[
"PHP_SELF"].
'?action=clone&token='.
newToken();
2814 $cloneButtonId =
'action-clone-no-ajax';
2816 print
"\n".
'<div class="tabsAction">'.
"\n";
2819 $reshook = $hookmanager->executeHooks(
'addMoreActionsButtons',
$parameters, $object, $action);
2820 if (empty($reshook)) {
2821 if ($usercancreate) {
2822 if (!isset($object->no_button_edit) || $object->no_button_edit <> 1) {
2823 print
dolGetButtonAction(
'', $langs->trans(
'Modify'),
'default', $_SERVER[
"PHP_SELF"].
'?action=edit&token='.
newToken().
'&id='.$object->id,
'', $usercancreate);
2826 if (!isset($object->no_button_copy) || $object->no_button_copy <> 1) {
2827 if (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile)) {
2828 $cloneProductUrl =
'';
2829 $cloneButtonId =
'action-clone';
2831 print
dolGetButtonAction($langs->trans(
'ToClone'),
'',
'default', $cloneProductUrl, $cloneButtonId, $usercancreate);
2834 $object_is_used = $object->isObjectUsed($object->id);
2836 if ($usercandelete) {
2837 if (empty($object_is_used) && (!isset($object->no_button_delete) || $object->no_button_delete <> 1)) {
2838 if (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile)) {
2839 print
dolGetButtonAction($langs->trans(
'Delete'),
'',
'delete',
'#',
'action-delete',
true);
2841 print
dolGetButtonAction(
'', $langs->trans(
'Delete'),
'delete', $_SERVER[
"PHP_SELF"].
'?action=delete&token='.
newToken().
'&id='.$object->id,
'');
2844 print
dolGetButtonAction($langs->trans(
"ProductIsUsed"), $langs->trans(
'Delete'),
'delete',
'#',
'',
false);
2847 print
'<a class="butActionDelete" href="card.php?action=merge&id='.$object->id.
'" title="'.
dol_escape_htmltag($langs->trans(
"MergeProducts")).
'">'.$langs->trans(
'Merge').
'</a>'.
"\n";
2850 print
dolGetButtonAction($langs->trans(
"NotEnoughPermissions"), $langs->trans(
'Delete'),
'delete',
'#',
'',
false);
2862 if (!empty($conf->global->PRODUCT_ADD_FORM_ADD_TO) && $object->id && ($action ==
'' || $action ==
'view') && $object->status) {
2868 if (
isModEnabled(
"propal") && $user->rights->propal->creer) {
2869 $propal =
new Propal($db);
2871 $langs->load(
"propal");
2873 $otherprop = $propal->liste_array(2, 1, 0);
2875 if (is_array($otherprop) && count($otherprop)) {
2876 $html .=
'<tr><td style="width: 200px;">';
2877 $html .= $langs->trans(
"AddToDraftProposals").
'</td><td>';
2878 $html .=
$form->selectarray(
"propalid", $otherprop, 0, 1);
2879 $html .=
'</td></tr>';
2881 $html .=
'<tr><td style="width: 200px;">';
2882 $html .= $langs->trans(
"AddToDraftProposals").
'</td><td>';
2883 $html .= $langs->trans(
"NoDraftProposals");
2884 $html .=
'</td></tr>';
2889 if (
isModEnabled(
'commande') && $user->rights->commande->creer) {
2892 $langs->load(
"orders");
2894 $othercom = $commande->liste_array(2, 1,
null);
2895 if (is_array($othercom) && count($othercom)) {
2896 $html .=
'<tr><td style="width: 200px;">';
2897 $html .= $langs->trans(
"AddToDraftOrders").
'</td><td>';
2898 $html .=
$form->selectarray(
"commandeid", $othercom, 0, 1);
2899 $html .=
'</td></tr>';
2901 $html .=
'<tr><td style="width: 200px;">';
2902 $html .= $langs->trans(
"AddToDraftOrders").
'</td><td>';
2903 $html .= $langs->trans(
"NoDraftOrders");
2904 $html .=
'</td></tr>';
2909 if (
isModEnabled(
'facture') && $user->rights->facture->creer) {
2912 $langs->load(
"bills");
2914 $otherinvoice = $invoice->liste_array(2, 1,
null);
2915 if (is_array($otherinvoice) && count($otherinvoice)) {
2916 $html .=
'<tr><td style="width: 200px;">';
2917 $html .= $langs->trans(
"AddToDraftInvoices").
'</td><td>';
2918 $html .=
$form->selectarray(
"factureid", $otherinvoice, 0, 1);
2919 $html .=
'</td></tr>';
2921 $html .=
'<tr><td style="width: 200px;">';
2922 $html .= $langs->trans(
"AddToDraftInvoices").
'</td><td>';
2923 $html .= $langs->trans(
"NoDraftInvoices");
2924 $html .=
'</td></tr>';
2929 if (!empty($html)) {
2930 print
'<form method="POST" action="'.$_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'">';
2931 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2932 print
'<input type="hidden" name="action" value="addin">';
2938 $html .=
'<tr><td class="nowrap">'.$langs->trans(
"Quantity").
' ';
2939 $html .=
'<input type="text" class="flat" name="qty" size="1" value="1"></td>';
2940 $html .=
'<td class="nowrap">'.$langs->trans(
"ReductionShort").
'(%) ';
2941 $html .=
'<input type="text" class="flat" name="remise_percent" size="1" value="0">';
2942 $html .=
'</td></tr>';
2944 print
'<table width="100%" class="border">';
2948 print
'<div class="center">';
2949 print
'<input type="submit" class="button button-add" value="'.$langs->trans(
"Add").
'">';
2963 if ($action !=
'create' && $action !=
'edit' && $action !=
'delete') {
2964 print
'<div class="fichecenter"><div class="fichehalfleft">';
2965 print
'<a name="builddoc"></a>';
2969 if (!empty($conf->product->multidir_output[$object->entity])) {
2970 $filedir = $conf->product->multidir_output[$object->entity].
'/'.$objectref;
2972 $filedir = $conf->product->dir_output.
'/'.$objectref;
2974 $urlsource = $_SERVER[
"PHP_SELF"].
"?id=".$object->id;
2975 $genallowed = $usercanread;
2976 $delallowed = $usercancreate;
2978 print $formfile->showdocuments($modulepart, $object->ref, $filedir, $urlsource, $genallowed, $delallowed,
'', 0, 0, 0, 28, 0,
'', 0,
'', $langs->getDefaultLang(),
'', $object);
2979 $somethingshown = $formfile->numoffiles;
2981 print
'</div><div class="fichehalfright">';
2985 $morehtmlcenter =
dolGetButtonTitle($langs->trans(
'SeeAll'),
'',
'fa fa-bars imgforviewmode', DOL_URL_ROOT.
'/product/agenda.php?id='.$object->id);
2988 include_once DOL_DOCUMENT_ROOT.
'/core/class/html.formactions.class.php';
2990 $somethingshown =
$formactions->showactions($object,
'product', 0, 1,
'', $MAXEVENT,
'', $morehtmlcenter);
2992 print
'</div></div>';
if(GETPOST('button_removefilter_x', 'alpha')||GETPOST('button_removefilter.x', 'alpha')||GETPOST('button_removefilter', 'alpha')) if(GETPOST('button_search_x', 'alpha')||GETPOST('button_search.x', 'alpha')||GETPOST('button_search', 'alpha')) if($action=="save" &&empty($cancel)) $help_url
View.
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.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
File of class to manage predefined price products or services by customer.
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.
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
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.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='')
Show tabs of a record.
showValueWithClipboardCPButton($valuetocopy, $showonlyonhover=1, $texttoshow='')
Create a button to copy $valuetocopy in the clipboard (for copy and paste feature).
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
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.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
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.
if(!function_exists('dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
getDolGlobalInt($key, $default=0)
Return 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)
dol_set_focus($selector)
Set focus onto field with selector (similar behaviour of 'autofocus' HTML5 tag)
dol_print_url($url, $target='_blank', $max=32, $withpicto=0)
Show Url link.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
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)
Fonction qui renvoie si tva doit etre tva percue recuperable.
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.
get_localtax($vatrate, $local, $thirdparty_buyer="", $thirdparty_seller="", $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate,...
if(!function_exists('utf8_encode')) if(!function_exists('utf8_decode')) getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
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.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
isModEnabled($module)
Is Dolibarr module enabled.
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.
$formconfirm
if ($action == 'delbookkeepingyear') {
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.