dolibarr 21.0.3
price.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2015 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005 Eric Seigne <eric.seigne@ryxeo.com>
5 * Copyright (C) 2005-2013 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
7 * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
8 * Copyright (C) 2023 Alexandre Spangaro <aspangaro@open-dsi.fr>
9 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
10 * Copyright (C) 2024 Mélina Joum <melina.joum@altairis.fr>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 */
25
33// Load Dolibarr environment
34require '../main.inc.php';
35require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
36require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
37require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
38require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
39
50if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) {
51 require_once DOL_DOCUMENT_ROOT.'/product/class/productcustomerprice.class.php';
52 $prodcustprice = new ProductCustomerPrice($db);
53}
54
55
56// Load translation files required by the page
57$langs->loadLangs(array("products", "companies", "bills"));
58
59
60// Get parameters
61$action = GETPOST('action', 'aZ09');
62$search_prod = GETPOST('search_prod', 'alpha');
63$cancel = GETPOST('cancel', 'alpha');
64$search_label = GETPOST('search_label', 'alpha');
65$search_price = GETPOST('search_price');
66$search_price_ttc = GETPOST('search_price_ttc');
67
68// Security check
69$socid = GETPOSTINT('socid') ? GETPOSTINT('socid') : GETPOSTINT('id');
70if ($user->socid) {
71 $socid = $user->socid;
72}
73
74// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
75$hookmanager->initHooks(array('thirdpartycustomerprice', 'globalcard'));
76
77$result = restrictedArea($user, 'societe', $socid, '&societe');
78
79// Initialize objects
80$object = new Societe($db);
81
82$error = 0;
83
84
85/*
86 * Actions
87 */
88
89$parameters = array('id' => $socid);
90$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
91if ($reshook < 0) {
92 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
93}
94
95if (empty($reshook)) {
96 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // Both test are required to be compatible with all browsers
97 $search_prod = $search_label = $search_price = $search_price_ttc = '';
98 }
99
100 if ($action == 'add_customer_price_confirm' && !$cancel && ($user->hasRight('produit', 'creer') || $user->hasRight('service', 'creer'))) {
101 if (!(GETPOSTINT('prodid') > 0)) {
102 $error++;
103 setEventMessages($langs->trans("ErrorFieldRequired", $langs->trans("Product")), null, 'errors');
104 $action = 'add_customer_price';
105 }
106
107 if (!$error) {
108 $update_child_soc = GETPOST('updatechildprice');
109
110 // add price by customer
111 $prodcustprice->fk_soc = $socid;
112 $prodcustprice->ref_customer = GETPOST('ref_customer', 'alpha');
113 $prodcustprice->fk_product = GETPOSTINT('prodid');
114 $prodcustprice->price = price2num(GETPOST("price"), 'MU');
115 $prodcustprice->price_min = price2num(GETPOST("price_min"), 'MU');
116 $prodcustprice->price_base_type = GETPOST("price_base_type", 'alpha');
117
118 $tva_tx_txt = GETPOST('tva_tx', 'alpha'); // tva_tx can be '8.5' or '8.5*' or '8.5 (XXX)' or '8.5* (XXX)'
119
120 // We must define tva_tx, npr and local taxes
121 $vatratecode = '';
122 $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot
123 $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0;
124 $localtax1 = 0;
125 $localtax2 = 0;
126 $localtax1_type = '0';
127 $localtax2_type = '0';
128 // If value contains the unique code of vat line (new recommended method), we use it to find npr and local taxes
129 if (preg_match('/\‍((.*)\‍)/', $tva_tx_txt, $reg)) {
130 // We look into database using code (we can't use get_localtax() because it depends on buyer that is not known). Same in update price.
131 $vatratecode = $reg[1];
132 // Get record from code
133 $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
134 $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c";
135 $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($mysoc->country_code)."'";
136 $sql .= " AND t.taux = ".((float) $tva_tx)." AND t.active = 1";
137 $sql .= " AND t.code = '".$db->escape($vatratecode)."'";
138 $sql .= " AND t.entity IN (".getEntity('c_tva').")";
139 $resql = $db->query($sql);
140 if ($resql) {
141 $obj = $db->fetch_object($resql);
142 $npr = $obj->recuperableonly;
143 $localtax1 = $obj->localtax1;
144 $localtax2 = $obj->localtax2;
145 $localtax1_type = $obj->localtax1_type;
146 $localtax2_type = $obj->localtax2_type;
147 }
148 }
149
150 $prodcustprice->default_vat_code = $vatratecode;
151 $prodcustprice->tva_tx = $tva_tx;
152 $prodcustprice->recuperableonly = $npr;
153 $prodcustprice->localtax1_tx = $localtax1;
154 $prodcustprice->localtax2_tx = $localtax2;
155 $prodcustprice->localtax1_type = $localtax1_type;
156 $prodcustprice->localtax2_type = $localtax2_type;
157
158 $result = $prodcustprice->create($user, 0, $update_child_soc);
159 if ($result > 0) {
160 $extrafields->fetch_name_optionals_label("product_customer_price");
161 $extralabels = !empty($extrafields->attributes["product_customer_price"]['label']) ? $extrafields->attributes["product_customer_price"]['label'] : '';
162 $extrafield_values = $extrafields->getOptionalsFromPost("product_customer_price");
163 if (!empty($extralabels) && is_array($extralabels)) {
164 $productcustomerprice = new ProductCustomerPrice($db);
165 $res = $productcustomerprice->fetch($prodcustprice->id);
166 if ($res > 0) {
167 foreach ($extrafield_values as $key => $value) {
168 $productcustomerprice->array_options[$key] = $value;
169 }
170 $result2 = $productcustomerprice->insertExtraFields();
171 if ($result2 < 0) {
172 $prodcustprice->error = $productcustomerprice->error;
173 $prodcustprice->errors = $productcustomerprice->errors;
174 $error++;
175 }
176 }
177 }
178 }
179
180 if ($result < 0) {
181 setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors');
182 } else {
183 setEventMessages($langs->trans("Save"), null, 'mesgs');
184 }
185
186 $action = '';
187 }
188 }
189
190 if ($action == 'delete_customer_price' && ($user->hasRight('produit', 'creer') || $user->hasRight('service', 'creer'))) {
191 // Delete price by customer
192 $prodcustprice->id = GETPOSTINT('lineid');
193 $result = $prodcustprice->delete($user);
194
195 if ($result < 0) {
196 setEventMessages($prodcustprice->error, $prodcustprice->errors, 'mesgs');
197 } else {
198 setEventMessages($langs->trans('RecordDeleted'), null, 'errors');
199 }
200 $action = '';
201 }
202
203 if ($action == 'update_customer_price_confirm' && !$cancel && ($user->hasRight('produit', 'creer') || $user->hasRight('service', 'creer'))) {
204 $prodcustprice->fetch(GETPOSTINT('lineid'));
205
206 $update_child_soc = GETPOST('updatechildprice');
207
208 // update price by customer
209 $prodcustprice->ref_customer = GETPOST('ref_customer', 'alpha');
210 $prodcustprice->price = price2num(GETPOST("price"), 'MU');
211 $prodcustprice->price_min = price2num(GETPOST("price_min"), 'MU');
212 $prodcustprice->price_base_type = GETPOST("price_base_type", 'alpha');
213 $prodcustprice->tva_tx = str_replace('*', '', GETPOST("tva_tx"));
214 $prodcustprice->recuperableonly = (preg_match('/\*/', GETPOST("tva_tx")) ? 1 : 0);
215
216 $result = $prodcustprice->update($user, 0, $update_child_soc);
217 if ($result > 0) {
218 $extrafields->fetch_name_optionals_label("product_customer_price");
219 $extralabels = !empty($extrafields->attributes["product_customer_price"]['label']) ? $extrafields->attributes["product_customer_price"]['label'] : '';
220 $extrafield_values = $extrafields->getOptionalsFromPost("product_customer_price");
221 if (!empty($extralabels) && is_array($extralabels)) {
222 $productcustomerprice = new ProductCustomerPrice($db);
223 $res = $productcustomerprice->fetch($prodcustprice->id);
224 if ($res > 0) {
225 foreach ($extrafield_values as $key => $value) {
226 $productcustomerprice->array_options[$key] = $value;
227 }
228 $result2 = $productcustomerprice->insertExtraFields();
229 if ($result2 < 0) {
230 $prodcustprice->error = $productcustomerprice->error;
231 $prodcustprice->errors = $productcustomerprice->errors;
232 $error++;
233 }
234 }
235 }
236 }
237 if ($result < 0) {
238 setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors');
239 } else {
240 setEventMessages($langs->trans("Save"), null, 'mesgs');
241 }
242
243 $action = '';
244 }
245}
246
247
248/*
249 * View
250 */
251
252$form = new Form($db);
253
254$object = new Societe($db);
255
256$result = $object->fetch($socid);
257llxHeader("", $langs->trans("ThirdParty").'-'.$langs->trans('PriceByCustomer'));
258
259$head = societe_prepare_head($object);
260
261print dol_get_fiche_head($head, 'price', $langs->trans("ThirdParty"), -1, 'company');
262
263$linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
264
265dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom');
266
267print '<div class="fichecenter">';
268
269print '<div class="underbanner clearboth"></div>';
270print '<table class="border centpercent tableforfield">';
271
272// Type Prospect/Customer/Supplier
273print '<tr><td class="titlefield">'.$langs->trans('NatureOfThirdParty').'</td><td>';
274print $object->getTypeUrl(1);
275print '</td></tr>';
276
277if (getDolGlobalString('SOCIETE_USEPREFIX')) { // Old not used prefix field
278 print '<tr><td class="titlefield">'.$langs->trans('Prefix').'</td><td colspan="3">'.$object->prefix_comm.'</td></tr>';
279}
280
281if ($object->client) {
282 print '<tr><td class="titlefield">';
283 print $langs->trans('CustomerCode').'</td><td colspan="3">';
284 print $object->code_client;
285 $tmpcheck = $object->check_codeclient();
286 if ($tmpcheck != 0 && $tmpcheck != -5) {
287 print ' <span class="error">('.$langs->trans("WrongCustomerCode").')</span>';
288 }
289 print '</td></tr>';
290}
291
292if ($object->fournisseur) {
293 print '<tr><td class="titlefield">';
294 print $langs->trans('SupplierCode').'</td><td colspan="3">';
295 print $object->code_fournisseur;
296 $tmpcheck = $object->check_codefournisseur();
297 if ($tmpcheck != 0 && $tmpcheck != -5) {
298 print ' <span class="error">('.$langs->trans("WrongSupplierCode").')</span>';
299 }
300 print '</td></tr>';
301}
302
303print '</table>';
304
305print '</div>';
306
307print dol_get_fiche_end();
308
309
310
311if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) {
312 $prodcustprice = new ProductCustomerPrice($db);
313
314 $sortfield = GETPOST('sortfield', 'aZ09comma');
315 $sortorder = GETPOST('sortorder', 'aZ09comma');
316 $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
317 $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
318 if (empty($page) || $page == -1) {
319 $page = 0;
320 } // If $page is not defined, or '' or -1
321 $offset = $limit * $page;
322 $pageprev = $page - 1;
323 $pagenext = $page + 1;
324 if (!$sortorder) {
325 $sortorder = "ASC";
326 }
327 if (!$sortfield) {
328 $sortfield = "soc.nom";
329 }
330
331 // Build filter to display only concerned lines
332 $filter = array(
333 't.fk_soc' => $object->id
334 );
335
336 if (!empty($search_prod)) {
337 $filter ['prod.ref'] = $search_prod;
338 }
339
340 if (!empty($search_label)) {
341 $filter ['prod.label'] = $search_label;
342 }
343
344 if (!empty($search_price)) {
345 $filter ['t.price'] = $search_price;
346 }
347
348 if (!empty($search_price_ttc)) {
349 $filter ['t.price_ttc'] = $search_price_ttc;
350 }
351
352 if ($action == 'add_customer_price') {
353 // Create mode
354
355 print '<br>';
356 print '<!-- Price by customer -->'."\n";
357
358 print load_fiche_titre($langs->trans('PriceByCustomer'));
359
360 print '<form action="'.$_SERVER["PHP_SELF"].'?socid='.$object->id.'" method="POST">';
361 print '<input type="hidden" name="token" value="'.newToken().'">';
362 print '<input type="hidden" name="action" value="add_customer_price_confirm">';
363 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
364 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
365 print '<input type="hidden" name="socid" value="'.$object->id.'">';
366 print '<table class="border centpercent">';
367 print '<tr>';
368 print '<td>'.$langs->trans('Product').'</td>';
369 print '<td>';
370 $form->select_produits('', 'prodid', '', 0);
371 print '</td>';
372 print '</tr>';
373
374 // Ref. Customer
375 print '<tr><td>'.$langs->trans('RefCustomer').'</td>';
376 print '<td><input name="ref_customer" size="12"></td></tr>';
377
378 // VAT
379 print '<tr><td>'.$langs->trans("VATRate").'</td><td>';
380 print $form->load_tva("tva_tx", GETPOST("tva_tx", "alpha"), $mysoc, '', $object->id, 0, '', false, 1);
381 print '</td></tr>';
382
383 // Price base
384 print '<tr><td width="15%">';
385 print $langs->trans('PriceBase');
386 print '</td>';
387 print '<td>';
388 print $form->selectPriceBaseType(GETPOST("price_base_type", "aZ09"), "price_base_type");
389 print '</td>';
390 print '</tr>';
391
392 // Price
393 print '<tr><td width="20%">';
394 $text = $langs->trans('SellingPrice');
395 print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", getDolGlobalString('MAIN_MAX_DECIMALS_UNIT')), 1, 1);
396 print '</td><td>';
397 print '<input name="price" size="10" value="'.GETPOSTINT('price').'">';
398 print '</td></tr>';
399
400 // Price minimum
401 print '<tr><td>';
402 $text = $langs->trans('MinPrice');
403 print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", getDolGlobalString('MAIN_MAX_DECIMALS_UNIT')), 1, 1);
404 print '<td><input name="price_min" size="10" value="'.GETPOSTINT('price_min').'">';
405 print '</td></tr>';
406
407 // Update all child soc
408 print '<tr><td width="15%">';
409 print $langs->trans('ForceUpdateChildPriceSoc');
410 print '</td>';
411 print '<td>';
412 print '<input type="checkbox" name="updatechildprice" value="1"/>';
413 print '</td>';
414 print '</tr>';
415
416 // Extrafields
417 $extrafields->fetch_name_optionals_label("product_customer_price");
418 $extralabels = !empty($extrafields->attributes["product_customer_price"]['label']) ? $extrafields->attributes["product_customer_price"]['label'] : '';
419 $extrafield_values = $extrafields->getOptionalsFromPost("product_customer_price");
420 if (!empty($extralabels)) {
421 if (empty($prodcustprice->id)) {
422 foreach ($extralabels as $key => $value) {
423 if (!empty($extrafields->attributes["product_customer_price"]['list'][$key]) && ($extrafields->attributes["product_customer_price"]['list'][$key] == 1 || $extrafields->attributes["product_customer_price"]['list'][$key] == 3 || ($action == "add_customer_price" && $extrafields->attributes["product_customer_price"]['list'][$key] == 4))) {
424 if (!empty($extrafields->attributes["product_customer_price"]['langfile'][$key])) {
425 $langs->load($extrafields->attributes["product_customer_price"]['langfile'][$key]);
426 }
427
428 print '<tr><td'.($extrafields->attributes["product_customer_price"]['required'][$key] ? ' class="fieldrequired"' : '').'>';
429 if (!empty($extrafields->attributes["product_customer_price"]['help'][$key])) {
430 print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes["product_customer_price"]['help'][$key]));
431 } else {
432 print $langs->trans($value);
433 }
434 print '</td><td>'.$extrafields->showInputField($key, GETPOSTISSET('options_'.$key) ? $extrafield_values['options_'.$key] : '', '', '', '', '', 0, 'product_customer_price').'</td></tr>';
435 }
436 }
437 }
438 }
439
440 print '</table>';
441
442 print $form->buttonsSaveCancel();
443
444 print '</form>';
445 } elseif ($action == 'edit_customer_price') {
446 // Edit mode
447
448 print load_fiche_titre($langs->trans('PriceByCustomer'));
449
450 $result = $prodcustprice->fetch(GETPOSTINT('lineid'));
451
452 if ($result <= 0) {
453 setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors');
454 } else {
455 print '<form action="'.$_SERVER["PHP_SELF"].'?socid='.$object->id.'" method="POST">';
456 print '<input type="hidden" name="token" value="'.newToken().'">';
457 print '<input type="hidden" name="action" value="update_customer_price_confirm">';
458 print '<input type="hidden" name="lineid" value="'.$prodcustprice->id.'">';
459 print '<table class="border centpercent">';
460 print '<tr>';
461 print '<td>'.$langs->trans('Product').'</td>';
462 $staticprod = new Product($db);
463 $staticprod->fetch($prodcustprice->fk_product);
464 print "<td>".$staticprod->getNomUrl(1)."</td>";
465 print '</tr>';
466
467 // Ref. Customer
468 print '<tr><td>'.$langs->trans('RefCustomer').'</td>';
469 print '<td><input name="ref_customer" size="12" value="'.dol_escape_htmltag($prodcustprice->ref_customer).'"></td></tr>';
470
471 // VAT
472 print '<tr><td>'.$langs->trans("VATRate").'</td><td>';
473 print $form->load_tva("tva_tx", $prodcustprice->tva_tx, $mysoc, '', $staticprod->id, $prodcustprice->recuperableonly);
474 print '</td></tr>';
475
476 // Price base
477 print '<tr><td width="15%">';
478 print $langs->trans('PriceBase');
479 print '</td>';
480 print '<td>';
481 print $form->selectPriceBaseType($prodcustprice->price_base_type, "price_base_type");
482 print '</td>';
483 print '</tr>';
484
485 // Price
486 print '<tr><td>';
487 $text = $langs->trans('SellingPrice');
488 print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", getDolGlobalString('MAIN_MAX_DECIMALS_UNIT')), 1, 1);
489 print '</td><td>';
490 if ($prodcustprice->price_base_type == 'TTC') {
491 print '<input name="price" size="10" value="'.price($prodcustprice->price_ttc).'">';
492 } else {
493 print '<input name="price" size="10" value="'.price($prodcustprice->price).'">';
494 }
495 print '</td></tr>';
496
497 // Price minimum
498 print '<tr><td>';
499 $text = $langs->trans('MinPrice');
500 print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", getDolGlobalString('MAIN_MAX_DECIMALS_UNIT')), 1, 1);
501 print '</td><td>';
502 if ($prodcustprice->price_base_type == 'TTC') {
503 print '<input name="price_min" size="10" value="'.price($prodcustprice->price_min_ttc).'">';
504 } else {
505 print '<input name="price_min" size="10" value="'.price($prodcustprice->price_min).'">';
506 }
507 print '</td></tr>';
508
509 // Extrafields
510 $extrafields->fetch_name_optionals_label("product_customer_price");
511 $extralabels = !empty($extrafields->attributes["product_customer_price"]['label']) ? $extrafields->attributes["product_customer_price"]['label'] : '';
512 $extrafield_values = $extrafields->getOptionalsFromPost("product_customer_price");
513 if (!empty($extralabels)) {
514 if (empty($object->id)) {
515 foreach ($extralabels as $key => $value) {
516 if (!empty($extrafields->attributes["product_customer_price"]['list'][$key]) && ($extrafields->attributes["product_customer_price"]['list'][$key] == 1 || $extrafields->attributes["product_customer_price"]['list'][$key] == 3 || ($action == "edit_price" && $extrafields->attributes["product_customer_price"]['list'][$key] == 4))) {
517 if (!empty($extrafields->attributes["product_customer_price"]['langfile'][$key])) {
518 $langs->load($extrafields->attributes["product_customer_price"]['langfile'][$key]);
519 }
520
521 print '<tr><td'.($extrafields->attributes["product_customer_price"]['required'][$key] ? ' class="fieldrequired"' : '').'>';
522 if (!empty($extrafields->attributes["product_customer_price"]['help'][$key])) {
523 print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes["product_customer_price"]['help'][$key]));
524 } else {
525 print $langs->trans($value);
526 }
527 print '</td><td>'.$extrafields->showInputField($key, GETPOSTISSET('options_'.$key) ? $extrafield_values['options_'.$key] : '', '', '', '', '', 0, 'product_customer_price').'</td></tr>';
528 }
529 }
530 } else {
531 $sql = "SELECT";
532 $sql .= " fk_object";
533 foreach ($extralabels as $key => $value) {
534 $sql .= ", ".$key;
535 }
536 $sql .= " FROM ".MAIN_DB_PREFIX."product_customer_price_extrafields";
537 $sql .= " WHERE fk_object = ".((int) $prodcustprice->id);
538 $resql = $db->query($sql);
539 if ($resql) {
540 $obj = $db->fetch_object($resql);
541 foreach ($extralabels as $key => $value) {
542 if (!empty($extrafields->attributes["product_customer_price"]['list'][$key]) && ($extrafields->attributes["product_customer_price"]['list'][$key] == 1 || $extrafields->attributes["product_customer_price"]['list'][$key] == 3 || ($action == "edit_price" && $extrafields->attributes["product_customer_price"]['list'][$key] == 4))) {
543 if (!empty($extrafields->attributes["product_customer_price"]['langfile'][$key])) {
544 $langs->load($extrafields->attributes["product_customer_price"]['langfile'][$key]);
545 }
546
547 print '<tr><td'.($extrafields->attributes["product_customer_price"]['required'][$key] ? ' class="fieldrequired"' : '').'>';
548 if (!empty($extrafields->attributes["product_customer_price"]['help'][$key])) {
549 print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes["product_customer_price"]['help'][$key]));
550 } else {
551 print $langs->trans($value);
552 }
553 print '</td><td>'.$extrafields->showInputField($key, GETPOSTISSET('options_'.$key) ? $extrafield_values['options_'.$key] : $obj->{$key}, '', '', '', '', 0, 'product_customer_price');
554
555 print '</td></tr>';
556 }
557 }
558 $db->free($resql);
559 }
560 }
561 }
562
563 print '</table>';
564
565 // Update all child soc
566 print '<center>';
567 print '<input type="checkbox" name="updatechildprice" id="updatechildprice" value="1"> ';
568 print '<label for="updatechildprice">'.$langs->trans('ForceUpdateChildPriceSoc').'</label>';
569 print '</center>';
570
571 print $form->buttonsSaveCancel();
572
573 print '</form>';
574 }
575 } elseif ($action == 'showlog_customer_price') {
576 print '<br>';
577 print '<!-- showlog_customer_price -->'."\n";
578
579 $filter = array(
580 't.fk_product' => GETPOSTINT('prodid'),
581 't.fk_soc' => $socid
582 );
583
584 // Count total nb of records
585 $nbtotalofrecords = '';
586 $result = $prodcustprice->fetchAllLog($sortorder, $sortfield, $conf->liste_limit, $offset, $filter);
587 if ($result < 0) {
588 setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors');
589 } else {
590 if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
591 $nbtotalofrecords = $result;
592 }
593 }
594
595 $option = '&socid='.GETPOSTINT('socid').'&prodid='.GETPOSTINT('prodid');
596
597 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
598 print_barre_liste($langs->trans('PriceByCustomerLog'), $page, $_SERVER ['PHP_SELF'], $option, $sortfield, $sortorder, '', count($prodcustprice->lines), $nbtotalofrecords);
599
600 if (count($prodcustprice->lines) > 0) {
601 print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="POST">';
602 print '<input type="hidden" name="token" value="'.newToken().'">';
603 print '<input type="hidden" name="id" value="'.$object->id.'">';
604
605 print '<table class="noborder centpercent">';
606
607 print '<tr class="liste_titre">';
608 print '<td>'.$langs->trans("Product").'</td>';
609 print '<td>'.$langs->trans('RefCustomer').'</td>';
610 print '<td>'.$langs->trans("AppliedPricesFrom").'</td>';
611 print '<td class="center">'.$langs->trans("PriceBase").'</td>';
612 print '<td class="right">'.$langs->trans("VAT").'</td>';
613 print '<td class="right">'.$langs->trans("HT").'</td>';
614 print '<td class="right">'.$langs->trans("TTC").'</td>';
615 print '<td class="right">'.$langs->trans("MinPrice").' '.$langs->trans("HT").'</td>';
616 print '<td class="right">'.$langs->trans("MinPrice").' '.$langs->trans("TTC").'</td>';
617 print '<td class="right">'.$langs->trans("ChangedBy").'</td>';
618 print '<td></td>';
619 print '</tr>';
620
621 foreach ($prodcustprice->lines as $line) {
622 $staticprod = new Product($db);
623 $staticprod->fetch($line->fk_product);
624
625 $userstatic = new User($db);
626 $userstatic->fetch($line->fk_user);
627
628 print '<tr class="oddeven">';
629
630 print "<td>".$staticprod->getNomUrl(1)."</td>";
631 print '<td>'.$line->ref_customer.'</td>';
632 print "<td>".dol_print_date($line->datec, "dayhour")."</td>";
633
634 print '<td class="center">'.$langs->trans($line->price_base_type)."</td>";
635 print '<td class="right">'.vatrate($line->tva_tx, true, $line->recuperableonly)."</td>";
636 print '<td class="right">'.price($line->price)."</td>";
637 print '<td class="right">'.price($line->price_ttc)."</td>";
638 print '<td class="right">'.price($line->price_min).'</td>';
639 print '<td class="right">'.price($line->price_min_ttc).'</td>';
640
641 // User
642 print '<td class="right">';
643 print $userstatic->getNomUrl(-1);
644 print '</td>';
645 print '<td></td>';
646 }
647 print "</table>";
648 } else {
649 print $langs->trans('None');
650 }
651
652 print "\n".'<div class="tabsAction">'."\n";
653 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?socid='.$object->id.'">'.$langs->trans("Ok").'</a></div>';
654 print "\n</div><br>\n";
655 } else {
656 // View mode
657
658 /*
659 * Action bar
660 */
661 print "\n".'<div class="tabsAction">'."\n";
662
663 if ($user->hasRight('produit', 'creer') || $user->hasRight('service', 'creer')) {
664 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=add_customer_price&token='.newToken().'&socid='.$object->id.'">'.$langs->trans("AddCustomerPrice").'</a></div>';
665 }
666 print "\n</div>\n";
667
668
669 $arrayfields = array();
670 foreach ($prodcustprice->fields as $key => $val) {
671 // If $val['visible']==0, then we never show the field
672 if (!empty($val['visible'])) {
673 $visible = (int) dol_eval((string) $val['visible'], 1, 1, '1');
674 $arrayfields['t.'.$key] = array(
675 'label' => $val['label'],
676 'checked' => (($visible < 0) ? 0 : 1),
677 'enabled' => (abs($visible) != 3 && (bool) dol_eval($val['enabled'], 1)),
678 'position' => $val['position'],
679 'help' => isset($val['help']) ? $val['help'] : ''
680 );
681 }
682 }
683 // fetch optionals attributes and labels
684 $extrafields->fetch_name_optionals_label("product_customer_price");
685 if ($extrafields->attributes["product_customer_price"] && array_key_exists('label', $extrafields->attributes["product_customer_price"])) {
686 $extralabels = $extrafields->attributes["product_customer_price"]['label'];
687
688 if (!empty($extralabels)) {
689 foreach ($extralabels as $key => $value) {
690 // Show field if not hidden
691 if (!empty($extrafields->attributes["product_customer_price"]['list'][$key]) && $extrafields->attributes["product_customer_price"]['list'][$key] != 3) {
692 $extratitle = $langs->trans($value);
693 if (!empty($val['visible'])) {
694 $visible = (int) dol_eval((string) $val['visible'], 1, 1, '1');
695 $arrayfields['ef.' . $key] = array(
696 'label' => $extratitle,
697 'checked' => (($visible < 0) ? 0 : 1),
698 'position' => (int) $extrafields->attributes['product_customer_price']['pos'][$key],
699 'langfile' => $extrafields->attributes["product_customer_price"]['langfile'][$key],
700 'help' => $extrafields->attributes["product_customer_price"]['help'][$key]
701 );
702 }
703 }
704 }
705 }
706 }
707
708 $arrayfields = dol_sort_array($arrayfields, 'position');
709
710 // Count total nb of records
711 $nbtotalofrecords = '';
712 if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
713 $nbtotalofrecords = $prodcustprice->fetchAll('', '', 0, 0, $filter);
714 }
715
716 $result = $prodcustprice->fetchAll($sortorder, $sortfield, $conf->liste_limit, $offset, $filter);
717 if ($result < 0) {
718 setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors');
719 }
720
721 $option = '&search_prod='.$search_prod.'&id='.$object->id.'&label='.$search_label.'&price='.$search_price.'&price_ttc='.$search_price_ttc;
722
723 print '<!-- view specific price for each product -->'."\n";
724
725 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
726 print_barre_liste($langs->trans('PriceForEachProduct'), $page, $_SERVER['PHP_SELF'], $option, $sortfield, $sortorder, '', count($prodcustprice->lines), $nbtotalofrecords, '');
727
728 print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="POST">';
729 print '<input type="hidden" name="token" value="'.newToken().'">';
730 print '<input type="hidden" name="id" value="'.$object->id.'">';
731 if (!empty($sortfield)) {
732 print '<input type="hidden" name="sortfield" value="'.$sortfield.'"/>';
733 }
734 if (!empty($sortorder)) {
735 print '<input type="hidden" name="sortorder" value="'.$sortorder.'"/>';
736 }
737 print '<div class="div-table-responsive-no-min">';
738 print '<table class="noborder centpercent liste">';
739
740 $param = 'socid='.$object->id.'&';
741 if ($search_prod) {
742 $param .= '&search_prod='.urlencode($search_prod);
743 }
744 if ($search_label) {
745 $param .= '&search_label='.urlencode($search_label);
746 }
747 if ($search_price) {
748 $param .= '&search_price='.urlencode($search_price);
749 }
750 if ($search_price) {
751 $param .= '&search_price='.urlencode($search_price);
752 }
753 if ($search_price_ttc) {
754 $param .= '&search_price_ttc='.urlencode($search_price_ttc);
755 }
756
757 print '<tr class="liste_titre">';
758
759 $colspan = 0;
760
761 foreach ($prodcustprice->fields as $key => $val) {
762 if (!empty($arrayfields['t.'.$key]['checked'])) {
763 print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], $key, '', $param, '', $sortfield, $sortorder)."\n";
764 $colspan++;
765 }
766 }
767 if (!empty($extralabels) && is_array($extralabels)) {
768 foreach ($extralabels as $key => $val) {
769 if (!empty($arrayfields['ef.'.$key]['checked'])) {
770 print getTitleFieldOfList($arrayfields['ef.'.$key]['label'], 0, $_SERVER['PHP_SELF'], $key, '', $param, '', $sortfield, $sortorder)."\n";
771 $colspan++;
772 }
773 }
774 }
775 print '<td></td>';
776 $colspan++;
777
778 print '</tr>';
779
780 if (count($prodcustprice->lines) > 0 || $search_prod) {
781 print '<tr class="liste_titre">';
782 print '<td class="liste_titre"><input type="text" class="flat width75" name="search_prod" value="'.$search_prod.'"></td>';
783 print '<td class="liste_titre" ><input type="text" class="flat width75" name="search_label" value="'.$search_label.'"></td>';
784 print '<td class="liste_titre"></td>';
785 print '<td class="liste_titre"></td>';
786 print '<td class="liste_titre"></td>';
787 print '<td class="liste_titre"></td>';
788 print '<td class="liste_titre left"><input type="text" class="flat width75" name="search_price" value="'.$search_price.'"></td>';
789 print '<td class="liste_titre left"><input type="text" class="flat width75" name="search_price_ttc" value="'.$search_price_ttc.'"></td>';
790 print '<td class="liste_titre"></td>';
791 print '<td class="liste_titre"></td>';
792 print '<td class="liste_titre"></td>';
793 print '<td class="liste_titre"></td>';
794 if (!empty($extralabels)) {
795 foreach ($extralabels as $key) {
796 print '<td class="right"></td>';
797 }
798 }
799 // Print the search button
800 print '<td class="liste_titre maxwidthsearch">';
801 $searchpicto = $form->showFilterAndCheckAddButtons(0);
802 print $searchpicto;
803 print '</td>';
804 print '</tr>';
805 }
806
807 if (count($prodcustprice->lines) > 0) {
808 foreach ($prodcustprice->lines as $line) {
809 $staticprod = new Product($db);
810 $staticprod->fetch($line->fk_product);
811
812 $userstatic = new User($db);
813 $userstatic->fetch($line->fk_user);
814
815 print '<tr class="oddeven">';
816
817 print '<td class="left">'.$staticprod->getNomUrl(1)."</td>";
818 print '<td class="left">'.$staticprod->label."</td>";
819 print '<td class="left">'.$line->ref_customer.'</td>';
820 print '<td class="left">'.dol_print_date($line->datec, "dayhour")."</td>";
821 print '<td class="left">'.$langs->trans($line->price_base_type)."</td>";
822 print '<td class="left">'.vatrate($line->tva_tx.($line->default_vat_code ? ' ('.$line->default_vat_code.')' : ''), true, $line->recuperableonly)."</td>";
823 print '<td class="left">'.price($line->price)."</td>";
824 print '<td class="left">'.price($line->price_ttc)."</td>";
825 print '<td class="left">'.price($line->price_min).'</td>';
826 print '<td class="left">'.price($line->price_min_ttc).'</td>';
827 print '<td class="left">'.$line->price_label.'</td>';
828 // User
829 print '<td class="left">';
830 print $userstatic->getNomUrl(-1);
831 print '</td>';
832
833 // Extrafields
834 $extrafields->fetch_name_optionals_label("product_customer_price");
835 $extralabels = $extrafields->attributes["product_customer_price"]['label'];
836 if (!empty($extralabels)) {
837 $sql = "SELECT";
838 $sql .= " fk_object";
839 foreach ($extralabels as $key => $value) {
840 $sql .= ", ".$key;
841 }
842 $sql .= " FROM ".MAIN_DB_PREFIX."product_customer_price_extrafields";
843 $sql .= " WHERE fk_object = ".((int) $line->id);
844 $resql = $db->query($sql);
845 if ($resql) {
846 if ($db->num_rows($resql) != 1) {
847 foreach ($extralabels as $key => $value) {
848 if (!empty($extrafields->attributes["product_customer_price"]['list'][$key]) && $extrafields->attributes["product_customer_price"]['list'][$key] != 3) {
849 print "<td></td>";
850 }
851 }
852 } else {
853 $obj = $db->fetch_object($resql);
854 foreach ($extralabels as $key => $value) {
855 if (!empty($extrafields->attributes["product_customer_price"]['list'][$key]) && $extrafields->attributes["product_customer_price"]['list'][$key] != 3) {
856 print '<td align="right">'.$extrafields->showOutputField($key, $obj->{$key}, '', 'product_customer_price')."</td>";
857 }
858 }
859 }
860 $db->free($resql);
861 }
862 }
863 // Action
864 if ($user->hasRight('produit', 'creer') || $user->hasRight('service', 'creer')) {
865 print '<td class="right nowraponall">';
866 print '<a class="paddingleftonly paddingrightonly" href="'.$_SERVER["PHP_SELF"].'?action=showlog_customer_price&token='.newToken().'&socid='.$object->id.'&prodid='.$line->fk_product.'">';
867 print img_info();
868 print '</a>';
869 print ' ';
870 print '<a class="editfielda paddingleftonly paddingrightonly" href="'.$_SERVER["PHP_SELF"].'?action=edit_customer_price&token='.newToken().'&socid='.$object->id.'&lineid='.$line->id.'">';
871 print img_edit('default', 0, 'style="vertical-align: middle;"');
872 print '</a>';
873 print ' ';
874 print '<a class="paddingleftonly paddingrightonly" href="'.$_SERVER["PHP_SELF"].'?action=delete_customer_price&token='.newToken().'&socid='.$object->id.'&lineid='.$line->id.'">';
875 print img_delete('default', 'style="vertical-align: middle;"');
876 print '</a>';
877 print '</td>';
878 }
879
880 print "</tr>\n";
881 }
882 } else {
883 if ($user->hasRight('produit', 'supprimer') || $user->hasRight('service', 'supprimer')) {
884 $colspan += 1;
885 }
886 print '<tr class="oddeven"><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans('None').'</span></td></tr>';
887 }
888
889 print "</table>";
890 print '</div>';
891
892 print "</form>";
893 }
894}
895
896// End of page
897llxFooter();
898$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:87
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:71
Class to manage generation of HTML components Only common components must be here.
File of class to manage predefined price products or services by customer.
Class to manage products or services.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
societe_prepare_head(Societe $object)
Return array of tabs to used on pages for third parties cards.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by the value of a given key, which produces ascending (default) or descending out...
newToken()
Return the value of token currently saved into session with name 'newtoken'.
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get title line of an array.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
img_info($titlealt='default')
Show info logo.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
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.