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