dolibarr  18.0.6
fournisseurs.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2021 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
5  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
6  * Copyright (C) 2010-2012 Juanjo Menent <jmenent@2byte.es>
7  * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
8  * Copyright (C) 2014 Ion Agorria <ion@agorria.com>
9  * Copyright (C) 2015 Alexandre Spangaro <aspangaro@open-dsi.fr>
10  * Copyright (C) 2016 Ferran Marcet <fmarcet@2byte.es>
11  * Copyright (C) 2019 Frédéric France <frederic.france@netlogic.fr>
12  * Copyright (C) 2019 Tim Otte <otte@meuser.it>
13  * Copyright (C) 2020 Pierre Ardoin <mapiolca@me.com>
14  * Copyright (C) 2023 Joachim Kueter <git-jk@bloxera.com>
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 3 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program. If not, see <https://www.gnu.org/licenses/>.
28  */
29 
36 // Load Dolibarr environment
37 require '../main.inc.php';
38 require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
39 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
40 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
41 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
42 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
43 require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_expression.class.php';
44 require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php';
45 if (isModEnabled('barcode')) {
46  dol_include_once('/core/class/html.formbarcode.class.php');
47 }
48 // Load translation files required by the page
49 $langs->loadLangs(array('products', 'suppliers', 'bills', 'margins', 'stocks'));
50 
51 $id = GETPOST('id', 'int');
52 $ref = GETPOST('ref', 'alpha');
53 $rowid = GETPOST('rowid', 'int');
54 $action = GETPOST('action', 'aZ09');
55 $cancel = GETPOST('cancel', 'alpha');
56 $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'pricesuppliercard';
57 
58 $socid = GETPOST('socid', 'int');
59 $cost_price = price2num(GETPOST('cost_price', 'alpha'), '', 2);
60 $pmp = price2num(GETPOST('pmp', 'alpha'), '', 2);
61 
62 $backtopage = GETPOST('backtopage', 'alpha');
63 $error = 0;
64 
65 $extrafields = new ExtraFields($db);
66 
67 // If socid provided by ajax company selector
68 if (GETPOST('search_fourn_id', 'int')) {
69  $_GET['id_fourn'] = GETPOST('search_fourn_id', 'int');
70  $_POST['id_fourn'] = GETPOST('search_fourn_id', 'int');
71 }
72 
73 // Security check
74 $fieldvalue = (!empty($id) ? $id : (!empty($ref) ? $ref : ''));
75 $fieldtype = (!empty($ref) ? 'ref' : 'rowid');
76 if ($user->socid) {
77  $socid = $user->socid;
78 }
79 
80 if (empty($user->rights->fournisseur->lire) && (!isModEnabled('margin') && !$user->hasRight("margin", "liretous"))) {
82 }
83 
84 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
85 $sortfield = GETPOST('sortfield', 'aZ09comma');
86 $sortorder = GETPOST('sortorder', 'aZ09comma');
87 $page = (GETPOST("page", 'int') ?GETPOST("page", 'int') : 0);
88 if (empty($page) || $page == -1) {
89  $page = 0;
90 } // If $page is not defined, or '' or -1
91 $offset = $limit * $page;
92 $pageprev = $page - 1;
93 $pagenext = $page + 1;
94 if (!$sortfield) {
95  $sortfield = "s.nom";
96 }
97 if (!$sortorder) {
98  $sortorder = "ASC";
99 }
100 
101 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
102 $hookmanager->initHooks(array('pricesuppliercard', 'globalcard'));
103 
104 $object = new ProductFournisseur($db);
105 $prod = new Product($db);
106 if ($id > 0 || $ref) {
107  $object->fetch($id, $ref);
108  $prod->fetch($id, $ref);
109 }
110 
111 $usercanread = (($object->type == Product::TYPE_PRODUCT && $user->rights->produit->lire) || ($object->type == Product::TYPE_SERVICE && $user->hasRight('service', 'lire')));
112 $usercancreate = (($object->type == Product::TYPE_PRODUCT && $user->rights->produit->creer) || ($object->type == Product::TYPE_SERVICE && $user->hasRight('service', 'creer')));
113 
114 if ($object->id > 0) {
115  if ($object->type == $object::TYPE_PRODUCT) {
116  restrictedArea($user, 'produit', $object->id, 'product&product', '', '');
117  }
118  if ($object->type == $object::TYPE_SERVICE) {
119  restrictedArea($user, 'service', $object->id, 'product&product', '', '');
120  }
121 } else {
122  restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype);
123 }
124 
125 
126 /*
127  * Actions
128  */
129 
130 if ($cancel) {
131  $action = '';
132 }
133 
134 $parameters = array('socid'=>$socid, 'id_prod'=>$id);
135 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
136 if ($reshook < 0) {
137  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
138 }
139 
140 if (empty($reshook)) {
141  if ($action == 'setcost_price') {
142  if ($id) {
143  $result = $object->fetch($id);
144  $object->oldcopy = dol_clone($object);
145  $object->cost_price = price2num($cost_price);
146  $result = $object->update($object->id, $user);
147  if ($result > 0) {
148  setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
149  $action = '';
150  } else {
151  $error++;
152  setEventMessages($object->error, $object->errors, 'errors');
153  }
154  }
155  }
156  if ($action == 'setpmp') {
157  if ($id) {
158  $result = $object->fetch($id);
159  $object->pmp = price2num($pmp);
160  $sql = "UPDATE ".MAIN_DB_PREFIX."product SET pmp = ".((float) $object->pmp)." WHERE rowid = ".((int) $id);
161  $resql = $db->query($sql);
162  //$result = $object->update($object->id, $user);
163  if ($resql) {
164  setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
165  $action = '';
166  } else {
167  $error++;
168  setEventMessages($object->error, $object->errors, 'errors');
169  }
170  }
171  }
172 
173  if ($action == 'confirm_remove_pf') {
174  if ($rowid) { // id of product supplier price to remove
175  $action = '';
176  $result = $object->remove_product_fournisseur_price($rowid);
177  if ($result > 0) {
178  $db->query("DELETE FROM ".MAIN_DB_PREFIX."product_fournisseur_price_extrafields WHERE fk_object = ".((int) $rowid));
179  setEventMessages($langs->trans("PriceRemoved"), null, 'mesgs');
180  } else {
181  $error++;
182  setEventMessages($object->error, $object->errors, 'errors');
183  }
184  }
185  }
186 
187  if ($action == 'save_price') {
188  $ref_fourn_price_id = GETPOSTINT('ref_fourn_price_id');
189  $id_fourn = GETPOST("id_fourn");
190  if (empty($id_fourn)) {
191  $id_fourn = GETPOST("search_id_fourn");
192  }
193  $ref_fourn = GETPOST("ref_fourn");
194  if (empty($ref_fourn)) {
195  $ref_fourn = GETPOST("search_ref_fourn");
196  }
197  $ref_fourn_old = GETPOST("ref_fourn_old");
198  if (empty($ref_fourn_old)) {
199  $ref_fourn_old = $ref_fourn;
200  }
201  $quantity = price2num(GETPOST("qty", 'alphanohtml'), 'MS');
202  $remise_percent = price2num(GETPOST('remise_percent', 'alpha'));
203 
204  $npr = preg_match('/\*/', GETPOST('tva_tx', 'alpha')) ? 1 : 0;
205  $tva_tx = str_replace('*', '', GETPOST('tva_tx', 'alpha'));
206  if (!preg_match('/\‍((.*)\‍)/', $tva_tx)) {
207  $tva_tx = price2num($tva_tx);
208  }
209 
210  $price_expression = GETPOST('eid', 'int') ? GETPOST('eid', 'int') : ''; // Discard expression if not in expression mode
211  $delivery_time_days = GETPOST('delivery_time_days', 'int') ? GETPOST('delivery_time_days', 'int') : '';
212  $supplier_reputation = GETPOST('supplier_reputation');
213  $supplier_description = GETPOST('supplier_description', 'restricthtml');
214  $barcode = GETPOST('barcode', 'alpha');
215  $fk_barcode_type = GETPOST('fk_barcode_type', 'int');
216  $packaging = price2num(GETPOST("packaging", 'alphanohtml'), 'MS');
217 
218  if ($tva_tx == '') {
219  $error++;
220  $langs->load("errors");
221  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("VATRateForSupplierProduct")), null, 'errors');
222  }
223  if (!is_numeric($tva_tx)) {
224  $error++;
225  $langs->load("errors");
226  setEventMessages($langs->trans("ErrorFieldMustBeANumeric", $langs->transnoentities("VATRateForSupplierProduct")), null, 'errors');
227  }
228  if (empty($quantity)) {
229  $error++;
230  $langs->load("errors");
231  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Qty")), null, 'errors');
232  }
233  if (empty($ref_fourn)) {
234  $error++;
235  $langs->load("errors");
236  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("RefSupplier")), null, 'errors');
237  }
238  if ($id_fourn <= 0) {
239  $error++;
240  $langs->load("errors");
241  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Supplier")), null, 'errors');
242  }
243  if (price2num(GETPOST("price")) < 0 || GETPOST("price") == '') {
244  if ($price_expression === '') { // Return error of missing price only if price_expression not set
245  $error++;
246  $langs->load("errors");
247  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Price")), null, 'errors');
248  } else {
249  $_POST["price"] = 0;
250  }
251  }
252  if (isModEnabled("multicurrency")) {
253  if (!GETPOST("multicurrency_code")) {
254  $error++;
255  $langs->load("errors");
256  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Currency")), null, 'errors');
257  }
258  if (price2num(GETPOST("multicurrency_tx")) <= 0 || GETPOST("multicurrency_tx") == '') {
259  $error++;
260  $langs->load("errors");
261  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("CurrencyRate")), null, 'errors');
262  }
263  if (price2num(GETPOST("multicurrency_price")) < 0 || GETPOST("multicurrency_price") == '') {
264  $error++;
265  $langs->load("errors");
266  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("PriceCurrency")), null, 'errors');
267  }
268  }
269 
270  if (!$error) {
271  $db->begin();
272 
273  if (empty($ref_fourn_price_id)) {
274  $ret = $object->add_fournisseur($user, $id_fourn, $ref_fourn_old, $quantity); // This insert record with no value for price. Values are update later with update_buyprice
275  if ($ret == -3) {
276  $error++;
277 
278  $tmpobject = new Product($db);
279  $tmpobject->fetch($object->product_id_already_linked);
280  $productLink = $tmpobject->getNomUrl(1, 'supplier');
281 
282  $texttoshow = $langs->trans("ReferenceSupplierIsAlreadyAssociatedWithAProduct", '{s1}');
283  $texttoshow = str_replace('{s1}', $productLink, $texttoshow);
284  setEventMessages($texttoshow, null, 'errors');
285  } elseif ($ret < 0) {
286  $error++;
287  setEventMessages($object->error, $object->errors, 'errors');
288  }
289  }
290 
291  if (!$error) {
292  $supplier = new Fournisseur($db);
293  $result = $supplier->fetch($id_fourn);
294  if ($ref_fourn_price_id > 0) {
295  $object->fetch_product_fournisseur_price($ref_fourn_price_id);
296  }
297  $extralabels = $extrafields->fetch_name_optionals_label("product_fournisseur_price");
298  $extrafield_values = $extrafields->getOptionalsFromPost("product_fournisseur_price");
299 
300  $newprice = price2num(GETPOST("price", "alpha"));
301 
302  if (empty($packaging)) {
303  $packaging = 1;
304  }
305  /* We can have a puchase ref that need to buy 100 min for a given price and with a packaging of 50.
306  if ($packaging < $quantity) {
307  $packaging = $quantity;
308  }*/
309  $object->packaging = $packaging;
310 
311  if (isModEnabled("multicurrency")) {
312  $multicurrency_tx = price2num(GETPOST("multicurrency_tx", 'alpha'));
313  $multicurrency_price = price2num(GETPOST("multicurrency_price", 'alpha'));
314  $multicurrency_code = GETPOST("multicurrency_code", 'alpha');
315 
316  $ret = $object->update_buyprice($quantity, $newprice, $user, GETPOST("price_base_type"), $supplier, GETPOST("oselDispo"), $ref_fourn, $tva_tx, GETPOST("charges"), $remise_percent, 0, $npr, $delivery_time_days, $supplier_reputation, array(), '', $multicurrency_price, GETPOST("multicurrency_price_base_type"), $multicurrency_tx, $multicurrency_code, $supplier_description, $barcode, $fk_barcode_type, $extrafield_values);
317  } else {
318  $ret = $object->update_buyprice($quantity, $newprice, $user, GETPOST("price_base_type"), $supplier, GETPOST("oselDispo"), $ref_fourn, $tva_tx, GETPOST("charges"), $remise_percent, 0, $npr, $delivery_time_days, $supplier_reputation, array(), '', 0, 'HT', 1, '', $supplier_description, $barcode, $fk_barcode_type, $extrafield_values);
319  }
320  if ($ret < 0) {
321  $error++;
322  setEventMessages($object->error, $object->errors, 'errors');
323  } else {
324  if (isModEnabled('dynamicprices') && $price_expression !== '') {
325  //Check the expression validity by parsing it
326  require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php';
327  $priceparser = new PriceParser($db);
328  $object->fk_supplier_price_expression = $price_expression;
329  $price_result = $priceparser->parseProductSupplier($object);
330  if ($price_result < 0) { //Expression is not valid
331  $error++;
332  setEventMessages($priceparser->translatedError(), null, 'errors');
333  }
334  }
335  if (!$error && isModEnabled('dynamicprices')) {
336  //Set the price expression for this supplier price
337  $ret = $object->setSupplierPriceExpression($price_expression);
338  if ($ret < 0) {
339  $error++;
340  setEventMessages($object->error, $object->errors, 'errors');
341  }
342  }
343  }
344  }
345 
346  if (!$error) {
347  $db->commit();
348  $action = '';
349  } else {
350  $db->rollback();
351  }
352  } else {
353  $action = 'create_price';
354  }
355  }
356 }
357 
358 
359 /*
360  * view
361  */
362 
363 $form = new Form($db);
364 
365 $title = $langs->trans('ProductServiceCard');
366 $helpurl = '';
367 $shortlabel = dol_trunc($object->label, 16);
368 if (GETPOST("type") == '0' || ($object->type == Product::TYPE_PRODUCT)) {
369  $title = $langs->trans('Product')." ".$shortlabel." - ".$langs->trans('BuyingPrices');
370  $helpurl = 'EN:Module_Products|FR:Module_Produits|ES:M&oacute;dulo_Productos|DE:Modul_Produkte';
371 }
372 if (GETPOST("type") == '1' || ($object->type == Product::TYPE_SERVICE)) {
373  $title = $langs->trans('Service')." ".$shortlabel." - ".$langs->trans('BuyingPrices');
374  $helpurl = 'EN:Module_Services_En|FR:Module_Services|ES:M&oacute;dulo_Servicios|DE:Modul_Lesitungen';
375 }
376 
377 llxHeader('', $title, $helpurl, '', 0, 0, '', '', '', 'classforhorizontalscrolloftabs');
378 
379 if ($id > 0 || $ref) {
380  if ($result) {
381  if ($action == 'ask_remove_pf') {
382  $form = new Form($db);
383  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$id.'&rowid='.$rowid, $langs->trans('DeleteProductBuyPrice'), $langs->trans('ConfirmDeleteProductBuyPrice'), 'confirm_remove_pf', '', 0, 1);
384  echo $formconfirm;
385  }
386 
387  if ($action != 'edit' && $action != 're-edit') {
388  $head = product_prepare_head($object);
389  $titre = $langs->trans("CardProduct".$object->type);
390  $picto = ($object->type == Product::TYPE_SERVICE ? 'service' : 'product');
391 
392  print dol_get_fiche_head($head, 'suppliers', $titre, -1, $picto);
393 
394  $linkback = '<a href="'.DOL_URL_ROOT.'/product/list.php?restore_lastsearch_values=1&type='.$object->type.'">'.$langs->trans("BackToList").'</a>';
395  $object->next_prev_filter = "fk_product_type = ".((int) $object->type);
396 
397  $shownav = 1;
398  if ($user->socid && !in_array('product', explode(',', $conf->global->MAIN_MODULES_FOR_EXTERNAL))) {
399  $shownav = 0;
400  }
401 
402  dol_banner_tab($prod, 'ref', $linkback, $shownav, 'ref');
403 
404  print '<div class="fichecenter">';
405 
406  print '<div class="underbanner clearboth"></div>';
407  print '<table class="border tableforfield centpercent">';
408 
409  // Type
410  if (isModEnabled("product") && isModEnabled("service")) {
411  $typeformat = 'select;0:'.$langs->trans("Product").',1:'.$langs->trans("Service");
412  print '<tr><td class="">';
413  print (empty($conf->global->PRODUCT_DENY_CHANGE_PRODUCT_TYPE)) ? $form->editfieldkey("Type", 'fk_product_type', $object->type, $object, 0, $typeformat) : $langs->trans('Type');
414  print '</td><td>';
415  print $form->editfieldval("Type", 'fk_product_type', $object->type, $object, 0, $typeformat);
416  print '</td></tr>';
417  }
418 
419  // Cost price. Can be used for margin module for option "calculate margin on explicit cost price
420  print '<tr><td>';
421  $textdesc = $langs->trans("CostPriceDescription");
422  $textdesc .= "<br>".$langs->trans("CostPriceUsage");
423  $text = $form->textwithpicto($langs->trans("CostPrice"), $textdesc, 1, 'help', '');
424  print $form->editfieldkey($text, 'cost_price', $object->cost_price, $object, $usercancreate, 'amount:6');
425  print '</td><td>';
426  print $form->editfieldval($text, 'cost_price', $object->cost_price, $object, $usercancreate, 'amount:6');
427  print '</td></tr>';
428 
429  // PMP
430  $usercaneditpmp = 0;
431  if (!empty($conf->global->PRODUCT_CAN_EDIT_WAP)) {
432  $usercaneditpmp = $usercancreate;
433  }
434  print '<tr><td class="titlefieldcreate">';
435  $textdesc = $langs->trans("AverageUnitPricePMPDesc");
436  $text = $form->textwithpicto($langs->trans("AverageUnitPricePMPShort"), $textdesc, 1, 'help', '');
437  print $form->editfieldkey($text, 'pmp', $object->pmp, $object, $usercaneditpmp, 'amount:6');
438  print '</td><td>';
439  print $form->editfieldval($text, 'pmp', ($object->pmp > 0 ? $object->pmp : ''), $object, $usercaneditpmp, 'amount:6');
440  if ($object->pmp > 0) {
441  print ' '.$langs->trans("HT");
442  }
443  /*
444  .$form->textwithpicto($langs->trans("AverageUnitPricePMPShort"), $langs->trans("AverageUnitPricePMPDesc")).'</td>';
445  print '<td>';
446  if ($object->pmp > 0) {
447  print price($object->pmp).' '.$langs->trans("HT");
448  }*/
449  print '</td>';
450  print '</tr>';
451 
452  // Best buying Price
453  print '<tr><td class="titlefieldcreate">'.$langs->trans("BuyingPriceMin").'</td>';
454  print '<td>';
455  $product_fourn = new ProductFournisseur($db);
456  if ($product_fourn->find_min_price_product_fournisseur($object->id) > 0) {
457  if ($product_fourn->product_fourn_price_id > 0) {
458  print $product_fourn->display_price_product_fournisseur();
459  } else {
460  print $langs->trans("NotDefined");
461  }
462  }
463  print '</td></tr>';
464 
465  print '</table>';
466 
467  print '</div>';
468  print '<div class="clearboth"></div>';
469 
470  print dol_get_fiche_end();
471 
472 
473  // Form to add or update a price
474  if (($action == 'create_price' || $action == 'update_price') && $usercancreate) {
475  $langs->load("suppliers");
476 
477  print "<!-- form to add a supplier price -->\n";
478  print '<br>';
479 
480  if ($rowid) {
481  $object->fetch_product_fournisseur_price($rowid, 1); //Ignore the math expression when getting the price
482  print load_fiche_titre($langs->trans("ChangeSupplierPrice"));
483  } else {
484  print load_fiche_titre($langs->trans("AddSupplierPrice"));
485  }
486 
487  print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'" method="POST">';
488  print '<input type="hidden" name="token" value="'.newToken().'">';
489  print '<input type="hidden" name="action" value="save_price">';
490 
491  print dol_get_fiche_head();
492 
493  print '<table class="border centpercent">';
494 
495  // Supplier
496  print '<tr><td class="titlefield fieldrequired">'.$langs->trans("Supplier").'</td><td>';
497  if ($rowid) {
498  $supplier = new Fournisseur($db);
499  $supplier->fetch($socid);
500  print $supplier->getNomUrl(1);
501  print '<input type="hidden" name="id_fourn" value="'.$socid.'">';
502  print '<input type="hidden" name="ref_fourn_price_id" value="'.$rowid.'">';
503  print '<input type="hidden" name="rowid" value="'.$rowid.'">';
504  print '<input type="hidden" name="socid" value="'.$socid.'">';
505  } else {
506  $events = array();
507  $events[] = array('method' => 'getVatRates', 'url' => dol_buildpath('/core/ajax/vatrates.php', 1), 'htmlname' => 'tva_tx', 'params' => array());
508  $filter = '(fournisseur:=:1)';
509  print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company(GETPOST("id_fourn", 'alpha'), 'id_fourn', $filter, 'SelectThirdParty', 0, 0, $events);
510 
511  $parameters = array('filtre'=>"fournisseur=1", 'html_name'=>'id_fourn', 'selected'=>GETPOST("id_fourn"), 'showempty'=>1, 'prod_id'=>$object->id);
512  $reshook = $hookmanager->executeHooks('formCreateThirdpartyOptions', $parameters, $object, $action);
513  if (empty($reshook)) {
514  if (empty($form->result)) {
515  print '<a href="'.DOL_URL_ROOT.'/societe/card.php?action=create&type=f&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.((int) $object->id).'&action='.urlencode($action).($action == 'create_price' ? '&token='.newToken() : '')).'">';
516  print img_picto($langs->trans("CreateDolibarrThirdPartySupplier"), 'add', 'class="marginleftonly"');
517  print '</a>';
518  }
519  }
520  print '<script type="text/javascript">
521  $(document).ready(function () {
522  $("#search_id_fourn").change(load_vat)
523  console.log("Requesting default VAT rate for the supplier...")
524  });
525  function load_vat() {
526  // get soc id
527  let socid = $("#id_fourn")[0].value
528 
529  // load available VAT rates
530  let vat_url = "'.dol_buildpath('/core/ajax/vatrates.php', 1).'"
531  //Make GET request with params
532  let options = "";
533  options += "id=" + socid
534  options += "&htmlname=tva_tx"
535  options += "&action=default" // not defined in vatrates.php, default behavior.
536 
537  var get = $.getJSON(
538  vat_url,
539  options,
540  (data) => {
541  rate_options = $.parseHTML(data.value)
542  rate_options.forEach(opt => {
543  if (opt.selected) {
544  replaceVATWithSupplierValue(opt.value);
545  return;
546  }
547  })
548  }
549  );
550 
551  }
552  function replaceVATWithSupplierValue(vat_rate) {
553  console.log("Default VAT rate for the supplier: " + vat_rate + "%")
554  $("[name=\'tva_tx\']")[0].value = vat_rate;
555  }
556  </script>';
557  }
558  print '</td></tr>';
559 
560  // Ref supplier
561  print '<tr><td class="fieldrequired">'.$langs->trans("SupplierRef").'</td><td>';
562  if ($rowid) {
563  print '<input type="hidden" name="ref_fourn_old" value="'.$object->ref_supplier.'">';
564  print '<input class="flat width150" maxlength="128" name="ref_fourn" value="'.$object->ref_supplier.'">';
565  } else {
566  print '<input class="flat width150" maxlength="128" name="ref_fourn" value="'.(GETPOST("ref_fourn") ? GETPOST("ref_fourn") : '').'">';
567  }
568  print '</td>';
569  print '</tr>';
570 
571  // Availability
572  if (getDolGlobalInt('FOURN_PRODUCT_AVAILABILITY')) {
573  $langs->load("propal");
574  print '<tr><td>'.$langs->trans("Availability").'</td><td>';
575  $form->selectAvailabilityDelay($object->fk_availability, "oselDispo", 1);
576  print '</td></tr>'."\n";
577  }
578 
579  // Qty min
580  print '<tr>';
581  print '<td class="fieldrequired">'.$langs->trans("QtyMin").'</td>';
582  print '<td>';
583  $quantity = GETPOSTISSET('qty') ? price2num(GETPOST('qty', 'alphanohtml'), 'MS') : "1";
584  if ($rowid) {
585  print '<input type="hidden" name="qty" value="'.$object->fourn_qty.'">';
586  print $object->fourn_qty;
587  } else {
588  print '<input class="flat" name="qty" size="5" value="'.$quantity.'">';
589  }
590  // Units
591  if (!empty($conf->global->PRODUCT_USE_UNITS)) {
592  $unit = $object->getLabelOfUnit();
593  if ($unit !== '') {
594  print '&nbsp;&nbsp;'.$langs->trans($unit);
595  }
596  }
597  print '</td></tr>';
598 
599  if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) {
600  // Packaging/Conditionnement
601  print '<tr>';
602 
603  print '<td class="fieldrequired">'.$form->textwithpicto($langs->trans("PackagingForThisProduct"), $langs->trans("PackagingForThisProductDesc")).'</td>';
604  print '<td>';
605  $packaging = GETPOSTISSET('packaging') ? price2num(GETPOST('packaging', 'alphanohtml'), 'MS') : ((empty($rowid)) ? "1" : price2num($object->packaging, 'MS'));
606  print '<input class="flat" name="packaging" size="5" value="'.$packaging.'">';
607 
608  // Units
609  if (!empty($conf->global->PRODUCT_USE_UNITS)) {
610  $unit = $object->getLabelOfUnit();
611  if ($unit !== '') {
612  print '&nbsp;&nbsp;'.$langs->trans($unit);
613  }
614  }
615  }
616  // Vat rate
617  $default_vat = '';
618 
619  // We don't have supplier, so we try to guess.
620  // For this we build a fictive supplier with same properties than user but using vat)
621  $mysoc2 = clone $mysoc;
622  $mysoc2->name = 'Fictive seller with same country';
623  $mysoc2->tva_assuj = 1;
624  $default_vat = get_default_tva($mysoc2, $mysoc, $object->id, 0);
625  $default_npr = get_default_npr($mysoc2, $mysoc, $object->id, 0);
626  if (empty($default_vat)) {
627  $default_npr = $default_vat;
628  }
629 
630  print '<tr><td class="fieldrequired">'.$langs->trans("VATRateForSupplierProduct").'</td>';
631  print '<td>';
632  //print $form->load_tva('tva_tx',$object->tva_tx,$supplier,$mysoc); // Do not use list here as it may be any vat rates for any country
633  if (!empty($rowid)) { // If we have a supplier, it is an update, we must show the vat of current supplier price
634  $tmpproductsupplier = new ProductFournisseur($db);
635  $tmpproductsupplier->fetch_product_fournisseur_price($rowid, 1);
636  $default_vat = $tmpproductsupplier->fourn_tva_tx;
637  $default_npr = $tmpproductsupplier->fourn_tva_npr;
638  } else {
639  if (empty($default_vat)) {
640  $default_vat = $object->tva_tx;
641  }
642  }
643  $vattosuggest = (GETPOSTISSET("tva_tx") ? vatrate(GETPOST("tva_tx")) : ($default_vat != '' ?vatrate($default_vat) : ''));
644  $vattosuggest = preg_replace('/\s*\‍(.*\‍)$/', '', $vattosuggest);
645  print '<input type="text" class="flat" size="5" name="tva_tx" value="'.$vattosuggest.'">';
646  print '</td></tr>';
647 
648  if (isModEnabled('dynamicprices')) { //Only show price mode and expression selector if module is enabled
649  // Price mode selector
650  print '<tr><td class="fieldrequired">'.$langs->trans("PriceMode").'</td><td>';
651  $price_expression = new PriceExpression($db);
652  $price_expression_list = array(0 => $langs->trans("PriceNumeric")); //Put the numeric mode as first option
653  foreach ($price_expression->list_price_expression() as $entry) {
654  $price_expression_list[$entry->id] = $entry->title;
655  }
656  $price_expression_preselection = GETPOST('eid') ? GETPOST('eid') : ($object->fk_supplier_price_expression ? $object->fk_supplier_price_expression : '0');
657  print $form->selectarray('eid', $price_expression_list, $price_expression_preselection);
658  print '&nbsp; <div id="expression_editor" class="button smallpaddingimp">'.$langs->trans("PriceExpressionEditor").'</div>';
659  print '</td></tr>';
660  // This code hides the numeric price input if is not selected, loads the editor page if editor button is pressed
661  print '<script type="text/javascript">
662  jQuery(document).ready(run);
663  function run() {
664  jQuery("#expression_editor").click(on_click);
665  jQuery("#eid").change(on_change);
666  on_change();
667  }
668  function on_click() {
669  window.location = "'.DOL_URL_ROOT.'/product/dynamic_price/editor.php?id='.$id.'&tab=fournisseurs&eid=" + $("#eid").val();
670  }
671  function on_change() {
672  if ($("#eid").val() == 0) {
673  jQuery("#price_numeric").show();
674  } else {
675  jQuery("#price_numeric").hide();
676  }
677  }
678  </script>';
679  }
680 
681  if (isModEnabled("multicurrency")) {
682  // Currency
683  print '<tr><td class="fieldrequired">'.$langs->trans("Currency").'</td>';
684  print '<td>';
685  $currencycodetouse = GETPOST('multicurrency_code') ? GETPOST('multicurrency_code') : (isset($object->fourn_multicurrency_code) ? $object->fourn_multicurrency_code : '');
686  if (empty($currencycodetouse) && $object->fourn_multicurrency_tx == 1) {
687  $currencycodetouse = $conf->currency;
688  }
689  print $form->selectMultiCurrency($currencycodetouse, "multicurrency_code", 1);
690  print ' &nbsp; &nbsp; '.$langs->trans("CurrencyRate").' ';
691  print '<input class="flat" name="multicurrency_tx" size="4" value="'.vatrate(GETPOST('multicurrency_tx') ? GETPOST('multicurrency_tx') : (isset($object->fourn_multicurrency_tx) ? $object->fourn_multicurrency_tx : '')).'">';
692  print '</td>';
693  print '</tr>';
694 
695  // Currency price qty min
696  print '<tr><td class="fieldrequired">'.$form->textwithpicto($langs->trans("PriceQtyMinCurrency"), $langs->transnoentitiesnoconv("WithoutDiscount")).'</td>';
697  $pricesupplierincurrencytouse = (GETPOST('multicurrency_price') ? GETPOST('multicurrency_price') : (isset($object->fourn_multicurrency_price) ? $object->fourn_multicurrency_price : ''));
698  print '<td><input class="flat" name="multicurrency_price" size="8" value="'.price($pricesupplierincurrencytouse).'">';
699  print '&nbsp;';
700  print $form->selectPriceBaseType((GETPOST('multicurrency_price_base_type') ?GETPOST('multicurrency_price_base_type') : 'HT'), "multicurrency_price_base_type"); // We keep 'HT' here, multicurrency_price_base_type is not yet supported for supplier prices
701  print '</td></tr>';
702 
703  // Price qty min
704  print '<tr><td class="fieldrequired">'.$form->textwithpicto($langs->trans("PriceQtyMin"), $langs->transnoentitiesnoconv("WithoutDiscount")).'</td>';
705  print '<td><input class="flat" name="disabled_price" size="8" value="">';
706  print '<input type="hidden" name="price" value="">';
707  print '<input type="hidden" name="price_base_type" value="">';
708  print '&nbsp;';
709  print $form->selectPriceBaseType('', "disabled_price_base_type");
710  print '</td></tr>';
711 
712  $currencies = array();
713  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."multicurrency WHERE entity = ".((int) $conf->entity);
714  $resql = $db->query($sql);
715  if ($resql) {
716  $currency = new MultiCurrency($db);
717  while ($obj = $db->fetch_object($resql)) {
718  $currency->fetch($obj->rowid);
719  $currencies[$currency->code] = ((float) $currency->rate->rate);
720  }
721  }
722  $currencies = json_encode($currencies);
723 
724  print <<<END
725  <!-- javascript to autocalculate the minimum price -->
726  <script type="text/javascript">
727  function update_price_from_multicurrency() {
728  console.log("update_price_from_multicurrency");
729  var multicurrency_price = price2numjs($('input[name="multicurrency_price"]').val());
730  var multicurrency_tx = price2numjs($('input[name="multicurrency_tx"]').val());
731  if (multicurrency_tx != 0) {
732  $('input[name="price"]').val(multicurrency_price / multicurrency_tx);
733  $('input[name="disabled_price"]').val(multicurrency_price / multicurrency_tx);
734  } else {
735  $('input[name="price"]').val('');
736  $('input[name="disabled_price"]').val('');
737  }
738  }
739 
740  jQuery(document).ready(function () {
741  $('input[name="disabled_price"]').prop('disabled', true);
742  $('select[name="disabled_price_base_type"]').prop('disabled', true);
743  update_price_from_multicurrency();
744 
745  $('input[name="multicurrency_price"], input[name="multicurrency_tx"]').keyup(function () {
746  update_price_from_multicurrency();
747  });
748  $('input[name="multicurrency_price"], input[name="multicurrency_tx"]').change(function () {
749  update_price_from_multicurrency();
750  });
751  $('input[name="multicurrency_price"], input[name="multicurrency_tx"]').on('paste', function () {
752  update_price_from_multicurrency();
753  });
754 
755  $('select[name="multicurrency_price_base_type"]').change(function () {
756  $('input[name="price_base_type"]').val($(this).val());
757  $('select[name="disabled_price_base_type"]').val($(this).val());
758  });
759 
760  var currencies_array = $currencies;
761  $('select[name="multicurrency_code"]').change(function () {
762  console.log("We change the currency");
763  $('input[name="multicurrency_tx"]').val(currencies_array[$(this).val()]);
764  update_price_from_multicurrency();
765  });
766  });
767  </script>
768 END;
769  } else {
770  // Price qty min
771  print '<tr><td class="fieldrequired">'.$langs->trans("PriceQtyMin").'</td>';
772  print '<td><input class="flat" name="price" size="8" value="'.(GETPOST('price') ? price(GETPOST('price')) : (isset($object->fourn_price) ? price($object->fourn_price) : '')).'">';
773  print '&nbsp;';
774  print $form->selectPriceBaseType((GETPOSTISSET('price_base_type') ? GETPOST('price_base_type') : 'HT'), "price_base_type"); // We keep 'HT' here, price_base_type is not yet supported for supplier prices
775  print '</td></tr>';
776  }
777 
778  // Option to define a transport cost on supplier price
779  if (getDolGlobalString('PRODUCT_CHARGES')) {
780  print '<tr>';
781  print '<td>'.$langs->trans("Charges").'</td>';
782  print '<td><input class="flat" name="charges" size="8" value="'.(GETPOST('charges') ? price(GETPOST('charges')) : (isset($object->fourn_charges) ? price($object->fourn_charges) : '')).'">';
783  print '</td>';
784  print '</tr>';
785  }
786 
787  // Discount qty min
788  print '<tr><td>'.$langs->trans("DiscountQtyMin").'</td>';
789  print '<td><input class="flat" name="remise_percent" size="4" value="'.(GETPOSTISSET('remise_percent') ? vatrate(price2num(GETPOST('remise_percent'), '', 2)) : (isset($object->fourn_remise_percent) ?vatrate($object->fourn_remise_percent) : '')).'"> %';
790  print '</td>';
791  print '</tr>';
792 
793  // Delivery delay in days
794  print '<tr>';
795  print '<td>'.$langs->trans('NbDaysToDelivery').'</td>';
796  print '<td><input class="flat" name="delivery_time_days" size="4" value="'.($rowid ? $object->delivery_time_days : '').'">&nbsp;'.$langs->trans('days').'</td>';
797  print '</tr>';
798 
799  // Reputation
800  print '<tr><td>'.$langs->trans("ReferenceReputation").'</td><td>';
801  echo $form->selectarray('supplier_reputation', $object->reputations, !empty($supplier_reputation) ? $supplier_reputation : $object->supplier_reputation);
802  print '</td></tr>';
803 
804  // Barcode
805  if (isModEnabled('barcode')) {
806  $formbarcode = new FormBarCode($db);
807 
808  // Barcode type
809  print '<tr>';
810  print '<td>'.$langs->trans('GencodBuyPrice').'</td>';
811  print '<td>';
812  print img_picto('', 'barcode', 'class="pictofixedwidth"');
813  print $formbarcode->selectBarcodeType((GETPOSTISSET('fk_barcode_type') ? GETPOST('fk_barcode_type', 'int') : ($rowid ? $object->supplier_fk_barcode_type : getDolGlobalint("PRODUIT_DEFAULT_BARCODE_TYPE"))), 'fk_barcode_type', 1);
814  print ' <input class="flat" name="barcode" value="'.(GETPOSTISSET('barcode') ? GETPOST('barcode') : ($rowid ? $object->supplier_barcode : '')).'"></td>';
815  print '</tr>';
816  }
817 
818  // Product description of the supplier
819  if (!empty($conf->global->PRODUIT_FOURN_TEXTS)) {
820  //WYSIWYG Editor
821  require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
822 
823  print '<tr>';
824  print '<td>'.$langs->trans('ProductSupplierDescription').'</td>';
825  print '<td>';
826 
827  $doleditor = new DolEditor('supplier_description', $object->desc_supplier, '', 160, 'dolibarr_details', '', false, true, getDolGlobalInt('FCKEDITOR_ENABLE_DETAILS'), ROWS_4, '90%');
828  $doleditor->Create();
829 
830  print '</td>';
831  print '</tr>';
832  }
833 
834  // Extrafields
835  $extrafields->fetch_name_optionals_label("product_fournisseur_price");
836  $extralabels = !empty($extrafields->attributes["product_fournisseur_price"]['label']) ? $extrafields->attributes["product_fournisseur_price"]['label'] : '';
837  $extrafield_values = $extrafields->getOptionalsFromPost("product_fournisseur_price");
838  if (!empty($extralabels)) {
839  if (empty($rowid)) {
840  foreach ($extralabels as $key => $value) {
841  if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && ($extrafields->attributes["product_fournisseur_price"]['list'][$key] == 1 || $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 3 || ($action == "update_price" && $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 4))) {
842  if (!empty($extrafields->attributes["product_fournisseur_price"]['langfile'][$key])) {
843  $langs->load($extrafields->attributes["product_fournisseur_price"]['langfile'][$key]);
844  }
845 
846  print '<tr><td'.($extrafields->attributes["product_fournisseur_price"]['required'][$key] ? ' class="fieldrequired"' : '').'>';
847  if (!empty($extrafields->attributes["product_fournisseur_price"]['help'][$key])) {
848  print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes["product_fournisseur_price"]['help'][$key]));
849  } else {
850  print $langs->trans($value);
851  }
852  print '</td><td>'.$extrafields->showInputField($key, GETPOSTISSET('options_'.$key) ? $extrafield_values['options_'.$key] : '', '', '', '', '', 0, 'product_fournisseur_price').'</td></tr>';
853  }
854  }
855  } else {
856  $sql = "SELECT";
857  $sql .= " fk_object";
858  foreach ($extralabels as $key => $value) {
859  $sql .= ", ".$key;
860  }
861  $sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price_extrafields";
862  $sql .= " WHERE fk_object = ".((int) $rowid);
863  $resql = $db->query($sql);
864  if ($resql) {
865  $obj = $db->fetch_object($resql);
866  foreach ($extralabels as $key => $value) {
867  if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && ($extrafields->attributes["product_fournisseur_price"]['list'][$key] == 1 || $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 3 || ($action == "update_price" && $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 4))) {
868  if (!empty($extrafields->attributes["product_fournisseur_price"]['langfile'][$key])) {
869  $langs->load($extrafields->attributes["product_fournisseur_price"]['langfile'][$key]);
870  }
871 
872  print '<tr><td'.($extrafields->attributes["product_fournisseur_price"]['required'][$key] ? ' class="fieldrequired"' : '').'>';
873  if (!empty($extrafields->attributes["product_fournisseur_price"]['help'][$key])) {
874  print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes["product_fournisseur_price"]['help'][$key]));
875  } else {
876  print $langs->trans($value);
877  }
878  print '</td><td>'.$extrafields->showInputField($key, GETPOSTISSET('options_'.$key) ? $extrafield_values['options_'.$key] : $obj->{$key}, '', '', '', '', 0, 'product_fournisseur_price');
879 
880  print '</td></tr>';
881  }
882  }
883  $db->free($resql);
884  }
885  }
886  }
887 
888  if (is_object($hookmanager)) {
889  $parameters = array('id_fourn'=>!empty($id_fourn) ? $id_fourn : 0, 'prod_id'=>$object->id);
890  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action);
891  print $hookmanager->resPrint;
892  }
893 
894  print '</table>';
895 
896  print dol_get_fiche_end();
897 
898  print '<div class="center">';
899  print '<input class="button button-save" type="submit" value="'.$langs->trans("Save").'">';
900  print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
901  print '<input class="button button-cancel" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
902  print '</div>';
903 
904  print '</form>'."\n";
905  }
906 
907 
908  // Actions buttons
909 
910  print '<div class="tabsAction">'."\n";
911 
912  if ($action != 'create_price' && $action != 'update_price') {
913  $parameters = array();
914  $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
915  if (empty($reshook)) {
916  if ($usercancreate) {
917  print '<a class="butAction" href="'.DOL_URL_ROOT.'/product/fournisseurs.php?id='.((int) $object->id).'&action=create_price&token='.newToken().'">';
918  print $langs->trans("AddSupplierPrice").'</a>';
919  }
920  }
921  }
922 
923  print "</div>\n";
924 
925  if ($user->hasRight("fournisseur", "read")) { // Duplicate ? this check is already in the head of this file
926  $param = '';
927  if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
928  $param .= '&contextpage='.urlencode($contextpage);
929  }
930  if ($limit > 0 && $limit != $conf->liste_limit) {
931  $param .= '&limit='.((int) $limit);
932  }
933  $param .= '&ref='.urlencode($object->ref);
934 
935  $product_fourn = new ProductFournisseur($db);
936  $product_fourn_list = $product_fourn->list_product_fournisseur_price($object->id, $sortfield, $sortorder, $limit, $offset);
937  $product_fourn_list_all = $product_fourn->list_product_fournisseur_price($object->id, $sortfield, $sortorder, 0, 0);
938  $nbtotalofrecords = count($product_fourn_list_all);
939  $num = count($product_fourn_list);
940  if (($num + ($offset * $limit)) < $nbtotalofrecords) {
941  $num++;
942  }
943 
944  print_barre_liste($langs->trans('SupplierPrices'), $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_accountancy.png', 0, '', '', $limit, 1);
945 
946  // Definition of fields for lists
947  // Some fields are missing because they are not included in the database query
948  $arrayfields = array(
949  'pfp.datec'=>array('label'=>$langs->trans("AppliedPricesFrom"), 'checked'=>1, 'position'=>1),
950  's.nom'=>array('label'=>$langs->trans("Suppliers"), 'checked'=>1, 'position'=>2),
951  'pfp.fk_availability'=>array('label'=>$langs->trans("Availability"), 'enabled' => getDolGlobalInt('FOURN_PRODUCT_AVAILABILITY'), 'checked'=>0, 'position'=>4),
952  'pfp.quantity'=>array('label'=>$langs->trans("QtyMin"), 'checked'=>1, 'position'=>5),
953  'pfp.unitprice'=>array('label'=>$langs->trans("UnitPriceHT"), 'checked'=>1, 'position'=>9),
954  'pfp.multicurrency_unitprice'=>array('label'=>$langs->trans("UnitPriceHTCurrency"), 'enabled' => isModEnabled('multicurrency'), 'checked'=>0, 'position'=>10),
955  'pfp.charges'=>array('label'=>$langs->trans("Charges"), 'enabled' => !empty($conf->global->PRODUCT_CHARGES), 'checked'=>0, 'position'=>11),
956  'pfp.delivery_time_days'=>array('label'=>$langs->trans("NbDaysToDelivery"), 'checked'=>-1, 'position'=>13),
957  'pfp.supplier_reputation'=>array('label'=>$langs->trans("ReputationForThisProduct"), 'checked'=>-1, 'position'=>14),
958  'pfp.fk_barcode_type'=>array('label'=>$langs->trans("BarcodeType"), 'enabled' => isModEnabled('barcode'), 'checked'=>0, 'position'=>15),
959  'pfp.barcode'=>array('label'=>$langs->trans("BarcodeValue"), 'enabled' => isModEnabled('barcode'), 'checked'=>0, 'position'=>16),
960  'pfp.packaging'=>array('label'=>$langs->trans("PackagingForThisProduct"), 'enabled' => getDolGlobalInt('PRODUCT_USE_SUPPLIER_PACKAGING'), 'checked'=>0, 'position'=>17),
961  'pfp.status'=>array('label'=>$langs->trans("Status"), 'enabled' => 1, 'checked'=>0, 'position'=>40),
962  'pfp.tms'=>array('label'=>$langs->trans("DateModification"), 'enabled' => isModEnabled('barcode'), 'checked'=>1, 'position'=>50),
963  );
964 
965  // fetch optionals attributes and labels
966  $extrafields->fetch_name_optionals_label("product_fournisseur_price");
967  if ($extrafields->attributes["product_fournisseur_price"] && array_key_exists('label', $extrafields->attributes["product_fournisseur_price"])) {
968  $extralabels = $extrafields->attributes["product_fournisseur_price"]['label'];
969 
970  if (!empty($extralabels)) {
971  foreach ($extralabels as $key => $value) {
972  // Show field if not hidden
973  if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && $extrafields->attributes["product_fournisseur_price"]['list'][$key] != 3) {
974  $extratitle = $langs->trans($value);
975  $arrayfields['ef.' . $key] = array('label' => $extratitle, 'checked' => 0,
976  'position' => (end($arrayfields)['position'] + 1),
977  'langfile' => $extrafields->attributes["product_fournisseur_price"]['langfile'][$key],
978  'help' => $extrafields->attributes["product_fournisseur_price"]['help'][$key]);
979  }
980  }
981  }
982  }
983 
984  // Selection of new fields
985  include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
986 
987  $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
988  $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
989 
990  print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post" name="formulaire">';
991  print '<input type="hidden" name="token" value="'.newToken().'">';
992  print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
993  print '<input type="hidden" name="action" value="list">';
994  print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
995  print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
996 
997  // Suppliers list title
998  print '<div class="div-table-responsive">';
999  print '<table class="liste centpercent">';
1000 
1001  $param = "&id=".$object->id;
1002 
1003  $nbfields = 0;
1004 
1005  print '<tr class="liste_titre">';
1006  if (!empty($arrayfields['pfp.datec']['checked'])) {
1007  print_liste_field_titre("AppliedPricesFrom", $_SERVER["PHP_SELF"], "pfp.datec", "", $param, "", $sortfield, $sortorder, '', '', 1);
1008  $nbfields++;
1009  }
1010  if (!empty($arrayfields['s.nom']['checked'])) {
1011  print_liste_field_titre("Suppliers", $_SERVER["PHP_SELF"], "s.nom", "", $param, "", $sortfield, $sortorder, '', '', 1);
1012  $nbfields++;
1013  }
1014  print_liste_field_titre("SupplierRef", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder, '', '', 1);
1015  $nbfields++;
1016  if (!empty($arrayfields['pfp.fk_availability']['checked'])) {
1017  print_liste_field_titre("Availability", $_SERVER["PHP_SELF"], "pfp.fk_availability", "", $param, "", $sortfield, $sortorder);
1018  $nbfields++;
1019  }
1020  if (!empty($arrayfields['pfp.quantity']['checked'])) {
1021  print_liste_field_titre("QtyMin", $_SERVER["PHP_SELF"], "pfp.quantity", "", $param, '', $sortfield, $sortorder, 'right ');
1022  $nbfields++;
1023  }
1024  print_liste_field_titre("VATRate", $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'right ');
1025  $nbfields++;
1026  print_liste_field_titre("PriceQtyMinHT", $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'right ');
1027  $nbfields++;
1028  if (isModEnabled("multicurrency")) {
1029  print_liste_field_titre("PriceQtyMinHTCurrency", $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'right ');
1030  $nbfields++;
1031  }
1032  if (!empty($arrayfields['pfp.unitprice']['checked'])) {
1033  print_liste_field_titre("UnitPriceHT", $_SERVER["PHP_SELF"], "pfp.unitprice", "", $param, '', $sortfield, $sortorder, 'right ');
1034  $nbfields++;
1035  }
1036  if (!empty($arrayfields['pfp.multicurrency_unitprice']['checked'])) {
1037  print_liste_field_titre("UnitPriceHTCurrency", $_SERVER["PHP_SELF"], "pfp.multicurrency_unitprice", "", $param, '', $sortfield, $sortorder, 'right ');
1038  $nbfields++;
1039  }
1040  if (isModEnabled("multicurrency")) {
1041  print_liste_field_titre("Currency", $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ');
1042  $nbfields++;
1043  }
1044  if (!empty($arrayfields['pfp.charges']['checked'])) { // possible only when $conf->global->PRODUCT_CHARGES is set
1045  print_liste_field_titre("Charges", $_SERVER["PHP_SELF"], "pfp.charges", "", $param, '', $sortfield, $sortorder, 'right ');
1046  $nbfields++;
1047  }
1048  print_liste_field_titre("DiscountQtyMin", $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'right ');
1049  $nbfields++;
1050  if (!empty($arrayfields['pfp.delivery_time_days']['checked'])) {
1051  print_liste_field_titre("NbDaysToDelivery", $_SERVER["PHP_SELF"], "pfp.delivery_time_days", "", $param, '', $sortfield, $sortorder, 'right ');
1052  $nbfields++;
1053  }
1054  if (!empty($arrayfields['pfp.supplier_reputation']['checked'])) {
1055  print_liste_field_titre("ReputationForThisProduct", $_SERVER["PHP_SELF"], "pfp.supplier_reputation", "", $param, '', $sortfield, $sortorder, 'center ');
1056  $nbfields++;
1057  }
1058  if (!empty($arrayfields['pfp.fk_barcode_type']['checked'])) {
1059  print_liste_field_titre("BarcodeType", $_SERVER["PHP_SELF"], "pfp.fk_barcode_type", "", $param, '', $sortfield, $sortorder, 'center ');
1060  $nbfields++;
1061  }
1062  if (!empty($arrayfields['pfp.barcode']['checked'])) {
1063  print_liste_field_titre("BarcodeValue", $_SERVER["PHP_SELF"], "pfp.barcode", "", $param, '', $sortfield, $sortorder, 'center ');
1064  $nbfields++;
1065  }
1066  if (!empty($arrayfields['pfp.packaging']['checked'])) {
1067  print_liste_field_titre("PackagingForThisProduct", $_SERVER["PHP_SELF"], "pfp.packaging", "", $param, '', $sortfield, $sortorder, 'center ');
1068  $nbfields++;
1069  }
1070  if (!empty($arrayfields['pfp.status']['checked'])) {
1071  print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "pfp.status", "", $param, '', $sortfield, $sortorder, 'center ', '', 1);
1072  $nbfields++;
1073  }
1074  if (!empty($arrayfields['pfp.tms']['checked'])) {
1075  print_liste_field_titre("DateModification", $_SERVER["PHP_SELF"], "pfp.tms", "", $param, '', $sortfield, $sortorder, 'right ', '', 1);
1076  $nbfields++;
1077  }
1078 
1079  // fetch optionals attributes and labels
1080  $extrafields->fetch_name_optionals_label("product_fournisseur_price");
1081  if ($extrafields->attributes["product_fournisseur_price"] && array_key_exists('label', $extrafields->attributes["product_fournisseur_price"])) {
1082  $extralabels = $extrafields->attributes["product_fournisseur_price"]['label'];
1083 
1084  if (!empty($extralabels)) {
1085  foreach ($extralabels as $key => $value) {
1086  // Show field if not hidden
1087  if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && $extrafields->attributes["product_fournisseur_price"]['list'][$key] != 3) {
1088  if (!empty($extrafields->attributes["product_fournisseur_price"]['langfile'][$key])) {
1089  $langs->load($extrafields->attributes["product_fournisseur_price"]['langfile'][$key]);
1090  }
1091  if (!empty($extrafields->attributes["product_fournisseur_price"]['help'][$key])) {
1092  $extratitle = $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes["product_fournisseur_price"]['help'][$key]));
1093  } else {
1094  $extratitle = $langs->trans($value);
1095  }
1096  if (!empty($arrayfields['ef.' . $key]['checked'])) {
1097  print_liste_field_titre($extratitle, $_SERVER["PHP_SELF"], 'ef.' . $key, '', $param, '', $sortfield, $sortorder, 'right ');
1098  $nbfields++;
1099  }
1100  }
1101  }
1102  }
1103  }
1104 
1105  if (is_object($hookmanager)) {
1106  $parameters = array('id_fourn'=>(!empty($id_fourn)?$id_fourn:''), 'prod_id'=>$object->id, 'nbfields'=>$nbfields);
1107  $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action);
1108  }
1109  print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
1110  $nbfields++;
1111  print "</tr>\n";
1112 
1113  if (is_array($product_fourn_list)) {
1114  foreach ($product_fourn_list as $productfourn) {
1115  print '<tr class="oddeven">';
1116 
1117  // Date from
1118  if (!empty($arrayfields['pfp.datec']['checked'])) {
1119  print '<td>'.dol_print_date(($productfourn->fourn_date_creation ? $productfourn->fourn_date_creation : $productfourn->date_creation), 'dayhour', 'tzuserrel').'</td>';
1120  }
1121 
1122  // Supplier
1123  if (!empty($arrayfields['s.nom']['checked'])) {
1124  print '<td class="tdoverflowmax150">'.$productfourn->getSocNomUrl(1, 'supplier').'</td>';
1125  }
1126 
1127  // Supplier ref
1128  if ($usercancreate) { // change required right here
1129  print '<td class="tdoverflowmax150">'.$productfourn->getNomUrl().'</td>';
1130  } else {
1131  print '<td class="tdoverflowmax150">'.dol_escape_htmltag($productfourn->fourn_ref).'</td>';
1132  }
1133 
1134  // Availability
1135  if (!empty($arrayfields['pfp.fk_availability']['checked'])) {
1136  $form->load_cache_availability();
1137  $availability = $form->cache_availability[$productfourn->fk_availability]['label'];
1138  print '<td class="left">'.$availability.'</td>';
1139  }
1140 
1141  // Quantity
1142  if (!empty($arrayfields['pfp.quantity']['checked'])) {
1143  print '<td class="right">';
1144  print $productfourn->fourn_qty;
1145  // Units
1146  if (!empty($conf->global->PRODUCT_USE_UNITS)) {
1147  $unit = $object->getLabelOfUnit();
1148  if ($unit !== '') {
1149  print '&nbsp;&nbsp;'.$langs->trans($unit);
1150  }
1151  }
1152  print '</td>';
1153  }
1154 
1155  // VAT rate
1156  print '<td class="right">';
1157  print vatrate($productfourn->fourn_tva_tx, true);
1158  print '</td>';
1159 
1160  // Price for the quantity
1161  print '<td class="right">';
1162  print $productfourn->fourn_price ? '<span class="amount">'.price($productfourn->fourn_price).'</span>' : "";
1163  print '</td>';
1164 
1165  if (isModEnabled("multicurrency")) {
1166  // Price for the quantity in currency
1167  print '<td class="right">';
1168  print $productfourn->fourn_multicurrency_price ? '<span class="amount">'.price($productfourn->fourn_multicurrency_price).'</span>' : "";
1169  print '</td>';
1170  }
1171 
1172  // Unit price
1173  if (!empty($arrayfields['pfp.unitprice']['checked'])) {
1174  print '<td class="right">';
1175  print price($productfourn->fourn_unitprice);
1176  //print $objp->unitprice? price($objp->unitprice) : ($objp->quantity?price($objp->price/$objp->quantity):"&nbsp;");
1177  print '</td>';
1178  }
1179 
1180  // Unit price in currency
1181  if (!empty($arrayfields['pfp.multicurrency_unitprice']['checked'])) {
1182  print '<td class="right">';
1183  print price($productfourn->fourn_multicurrency_unitprice);
1184  print '</td>';
1185  }
1186 
1187  // Currency
1188  if (isModEnabled("multicurrency")) {
1189  print '<td class="right nowraponall">';
1190  print $productfourn->fourn_multicurrency_code ? currency_name($productfourn->fourn_multicurrency_code) : '';
1191  print '</td>';
1192  }
1193 
1194  // Charges
1195  if (!empty($arrayfields['pfp.charges']['checked'])) { // Possible only when getDolGlobalString('PRODUCT_CHARGES') is set
1196  print '<td class="right">';
1197  print price($productfourn->fourn_charges);
1198  print '</td>';
1199  }
1200 
1201  // Discount
1202  print '<td class="right">';
1203  print price2num($productfourn->fourn_remise_percent).'%';
1204  print '</td>';
1205 
1206  // Delivery delay
1207  if (!empty($arrayfields['pfp.delivery_time_days']['checked'])) {
1208  print '<td class="right">';
1209  print $productfourn->delivery_time_days;
1210  print '</td>';
1211  }
1212 
1213  // Reputation
1214  if (!empty($arrayfields['pfp.supplier_reputation']['checked'])) {
1215  print '<td class="center">';
1216  if (!empty($productfourn->supplier_reputation) && !empty($object->reputations[$productfourn->supplier_reputation])) {
1217  print $object->reputations[$productfourn->supplier_reputation];
1218  }
1219  print'</td>';
1220  }
1221 
1222  // Barcode type
1223  if (!empty($arrayfields['pfp.fk_barcode_type']['checked'])) {
1224  print '<td class="center">';
1225  $productfourn->barcode_type = !empty($productfourn->supplier_fk_barcode_type) ? $productfourn->supplier_fk_barcode_type : 0;
1226  $productfourn->fetch_barcode();
1227  print $productfourn->barcode_type_label ? $productfourn->barcode_type_label : ($productfourn->supplier_barcode ? '<div class="warning">'.$langs->trans("SetDefaultBarcodeType").'<div>' : '');
1228  print '</td>';
1229  }
1230 
1231  // Barcode
1232  if (!empty($arrayfields['pfp.barcode']['checked'])) {
1233  print '<td class="right">';
1234  print $productfourn->supplier_barcode;
1235  print '</td>';
1236  }
1237 
1238  // Packaging
1239  if (!empty($arrayfields['pfp.packaging']['checked'])) {
1240  print '<td class="center">';
1241  print price2num($productfourn->packaging);
1242  print '</td>';
1243  }
1244 
1245  // Status
1246  if (!empty($arrayfields['pfp.status']['checked'])) {
1247  print '<td class="center">';
1248  print $productfourn->getLibStatut(3);
1249  print '</td>';
1250  }
1251 
1252  // Date modification
1253  if (!empty($arrayfields['pfp.tms']['checked'])) {
1254  print '<td class="right nowraponall">';
1255  print dol_print_date(($productfourn->fourn_date_modification ? $productfourn->fourn_date_modification : $productfourn->date_modification), "dayhour");
1256  print '</td>';
1257  }
1258 
1259  // Extrafields
1260  if (!empty($extralabels)) {
1261  $sql = "SELECT";
1262  $sql .= " fk_object";
1263  foreach ($extralabels as $key => $value) {
1264  $sql .= ", ".$key;
1265  }
1266  $sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price_extrafields";
1267  $sql .= " WHERE fk_object = ".((int) $productfourn->product_fourn_price_id);
1268  $resql = $db->query($sql);
1269  if ($resql) {
1270  if ($db->num_rows($resql) != 1) {
1271  foreach ($extralabels as $key => $value) {
1272  if (!empty($arrayfields['ef.'.$key]['checked']) && !empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && $extrafields->attributes["product_fournisseur_price"]['list'][$key] != 3) {
1273  print "<td></td>";
1274  }
1275  }
1276  } else {
1277  $obj = $db->fetch_object($resql);
1278  foreach ($extralabels as $key => $value) {
1279  if (!empty($arrayfields['ef.'.$key]['checked']) && !empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && $extrafields->attributes["product_fournisseur_price"]['list'][$key] != 3) {
1280  print '<td align="right">'.$extrafields->showOutputField($key, $obj->{$key}, '', 'product_fournisseur_price')."</td>";
1281  }
1282  }
1283  }
1284  $db->free($resql);
1285  }
1286  }
1287 
1288  if (is_object($hookmanager)) {
1289  $parameters = array('id_pfp'=>$productfourn->product_fourn_price_id, 'id_fourn'=>(!empty($id_fourn)?$id_fourn:''), 'prod_id'=>$object->id);
1290  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action);
1291  }
1292 
1293  // Modify-Remove
1294  print '<td class="center nowraponall">';
1295 
1296  if ($usercancreate) {
1297  print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?id='.((int) $object->id).'&socid='.((int) $productfourn->fourn_id).'&action=update_price&token='.newToken().'&rowid='.((int) $productfourn->product_fourn_price_id).'">'.img_edit()."</a>";
1298  print ' &nbsp; ';
1299  print '<a href="'.$_SERVER['PHP_SELF'].'?id='.((int) $object->id).'&socid='.((int) $productfourn->fourn_id).'&action=ask_remove_pf&token='.newToken().'&rowid='.((int) $productfourn->product_fourn_price_id).'">'.img_picto($langs->trans("Remove"), 'delete').'</a>';
1300  }
1301 
1302  print '</td>';
1303 
1304  print '</tr>';
1305  }
1306 
1307  if (empty($product_fourn_list)) {
1308  print '<tr><td colspan="'.$nbfields.'"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
1309  }
1310  } else {
1311  dol_print_error($db);
1312  }
1313 
1314  print '</table>';
1315  print '</div>';
1316  print '</form>';
1317  }
1318  }
1319  }
1320 } else {
1321  print $langs->trans("ErrorUnknown");
1322 }
1323 
1324 // End of page
1325 llxFooter();
1326 $db->close();
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:56
llxFooter()
Empty footer.
Definition: wrapper.php:70
Class to manage a WYSIWYG editor.
Class to manage standard extra fields.
Class to manage barcode HTML.
Class to manage generation of HTML components Only common components must be here.
Class to manage suppliers.
Class Currency.
Class for accesing price expression table.
Class to parse product price expressions.
Class to manage predefined suppliers products.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
currency_name($code_iso, $withcode='', $outputlangs=null)
Return label of currency or code+label.
if(isModEnabled('facture') && $user->hasRight('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') && $user->hasRight('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)) $sql
Social contributions to pay.
Definition: index.php:746
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
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.
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formated for view output Used into pdf and HTML pages.
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
GETPOSTINT($paramname, $method=0)
Return value of a param into GET or POST supervariable.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_get_fiche_end($notab=0)
Return tab footer of a card.
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.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
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)
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 =...
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
get_default_npr(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that returns whether VAT must be recoverable collected VAT (e.g.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
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...
price2numjs(amount)
Function similar to PHP price2num()
$formconfirm
if ($action == 'delbookkeepingyear') {
div float
Buy price without taxes.
Definition: style.css.php:926
product_prepare_head($object)
Prepare array with list of tabs.
Definition: product.lib.php:36
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:120
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.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.