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