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