40require
'../main.inc.php';
41require_once DOL_DOCUMENT_ROOT.
'/core/lib/product.lib.php';
42require_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
43require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
44require_once DOL_DOCUMENT_ROOT.
'/product/dynamic_price/class/price_expression.class.php';
45require_once DOL_DOCUMENT_ROOT.
'/product/dynamic_price/class/price_parser.class.php';
46require_once DOL_DOCUMENT_ROOT.
'/core/class/extrafields.class.php';
59 require_once DOL_DOCUMENT_ROOT.
'/product/class/productcustomerprice.class.php';
65$langs->loadLangs(array(
'products',
'bills',
'companies',
'other'));
73$action =
GETPOST(
'action',
'aZ09');
74$cancel =
GETPOST(
'cancel',
'alpha');
77$search_soc =
GETPOST(
'search_soc');
80$fieldvalue = (!empty($id) ?
$id : (!empty($ref) ? $ref :
''));
81$fieldtype = (!empty($ref) ?
'ref' :
'rowid');
83 $socid = $user->socid;
87if ($id > 0 || !empty($ref)) {
95 $conf->global->PRODUIT_MULTIPRICES_LIMIT = 5;
99$hookmanager->initHooks(array(
'productpricecard',
'globalcard'));
102 if (
$object->type == $object::TYPE_PRODUCT) {
105 if (
$object->type == $object::TYPE_SERVICE) {
109 restrictedArea($user,
'produit|service', $fieldvalue,
'product&product',
'',
'', $fieldtype);
112$maxpricesupplier = 0;
115 $permissiontoadd =
$object->getRights()->creer;
117 $permissiontoadd = ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'));
129$parameters = array(
'id' => $id,
'ref' => $ref);
130$reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
132 setEventMessages($hookmanager->error, $hookmanager->errors,
'errors');
135if (empty($reshook)) {
136 if (
GETPOST(
'button_removefilter_x',
'alpha') ||
GETPOST(
'button_removefilter.x',
'alpha') ||
GETPOST(
'button_removefilter',
'alpha')) {
140 if ($action ==
'setlabelsellingprice' && $user->admin) {
141 require_once DOL_DOCUMENT_ROOT.
'/core/lib/admin.lib.php';
142 $keyforlabel =
'PRODUIT_MULTIPRICES_LABEL'.GETPOST(
'pricelevel');
147 if (($action ==
'update_vat') && !$cancel && $permissiontoadd) {
148 $tva_tx_txt =
GETPOST(
'tva_tx',
'alpha');
150 $price_label =
GETPOST(
'price_label',
'alpha');
153 $tva_tx = $tva_tx_txt;
156 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
157 $vatratecode = $reg[1];
158 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
161 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
162 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
165 $localtax1_type =
'0';
166 $localtax2_type =
'0';
169 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
171 $vatratecode = $reg[1];
173 $sql =
"SELECT t.rowid, t.type_vat, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
174 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
175 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
176 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
177 $sql .=
" AND t.code = '".$db->escape($vatratecode).
"'";
178 $sql .=
" AND t.type_vat IN (0, 1)";
179 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
180 $resql = $db->query($sql);
182 $obj = $db->fetch_object($resql);
184 $npr = $obj->recuperableonly;
185 $localtax1 = $obj->localtax1;
186 $localtax2 = $obj->localtax2;
187 $localtax1_type = $obj->localtax1_type;
188 $localtax2_type = $obj->localtax2_type;
193 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
194 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
195 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
196 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
197 $sql .=
" AND t.code = ''";
198 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
199 $resql = $db->query($sql);
201 $obj = $db->fetch_object($resql);
203 $npr = $obj->recuperableonly;
204 $localtax1 = $obj->localtax1;
205 $localtax2 = $obj->localtax2;
206 $localtax1_type = $obj->localtax1_type;
207 $localtax2_type = $obj->localtax2_type;
212 $object->default_vat_code = $vatratecode;
215 $object->localtax1_tx = $localtax1;
216 $object->localtax2_tx = $localtax2;
217 $object->localtax1_type = $localtax1_type;
218 $object->localtax2_type = $localtax2_type;
219 $object->price_label = $price_label;
231 $produit_multiprices_limit =
getDolGlobalInt(
'PRODUIT_MULTIPRICES_LIMIT');
232 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
234 if (
$object->multiprices_base_type[$i] ==
'HT') {
235 $oldprice =
$object->multiprices[$i];
236 $oldminprice =
$object->multiprices_min[$i];
238 $oldprice =
$object->multiprices_ttc[$i];
239 $oldminprice =
$object->multiprices_min_ttc[$i];
241 $oldpricebasetype =
$object->multiprices_base_type[$i];
242 $oldnpr =
$object->multiprices_recuperableonly[$i];
245 $localtaxarray = array();
247 $ret =
$object->updatePrice($oldprice, $oldpricebasetype, $user, (
float) $tva_tx, $oldminprice, $level, $oldnpr, 0, 0, $localtaxarray, $vatratecode, $price_label);
256 if (
$object->price_base_type ==
'HT') {
258 $oldminprice =
$object->price_min;
260 $oldprice =
$object->price_ttc;
261 $oldminprice =
$object->price_min_ttc;
263 $oldpricebasetype =
$object->price_base_type;
267 $localtaxarray = array();
269 $ret =
$object->updatePrice($oldprice, $oldpricebasetype, $user, (
float) $tva_tx, $oldminprice, $level, $oldnpr, 0, 0, $localtaxarray, $vatratecode, $price_label);
287 $maxpricesupplier = 0;
289 if (($action ==
'update_price' || $action ==
'update_level_price') && !$cancel && $permissiontoadd) {
291 $pricestoupdate = array();
296 $maxpricesupplier =
$object->min_recommended_price();
302 $object->fk_price_expression = empty($eid) ? 0 : $eid;
304 if (
$object->fk_price_expression != 0) {
306 require_once DOL_DOCUMENT_ROOT.
'/product/dynamic_price/class/price_parser.class.php';
309 if ($priceparser->parseProduct($object) < 0) {
311 setEventMessages($priceparser->translatedError(),
null,
'errors');
318 || ($action ==
'update_level_price' &&
getDolGlobalString(
'PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')))) {
319 $newprice =
GETPOST(
'price',
'array');
320 $newprice_min =
GETPOST(
'price_min',
'array');
321 $newpricebase =
GETPOST(
'multiprices_base_type',
'array');
322 $newvattx =
GETPOST(
'tva_tx',
'array');
323 $newvatnpr =
GETPOST(
'tva_npr',
'array');
324 $newlocaltax1_tx =
GETPOST(
'localtax1_tx',
'array');
325 $newlocaltax1_type =
GETPOST(
'localtax1_type',
'array');
326 $newlocaltax2_tx =
GETPOST(
'localtax2_tx',
'array');
327 $newlocaltax2_type =
GETPOST(
'localtax2_type',
'array');
330 $object->price_autogen = (int) (
GETPOST(
'usePriceRules') ==
'on');
332 $produit_multiprices_limit =
getDolGlobalInt(
'PRODUIT_MULTIPRICES_LIMIT');
333 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
334 if (!isset($newprice[$i])) {
338 $tva_tx_txt = $newvattx[$i];
340 $tva_tx = $tva_tx_txt;
343 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
344 $vat_src_code = $reg[1];
345 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
347 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
349 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
350 $localtax1 = $newlocaltax1_tx[$i];
351 $localtax1_type = $newlocaltax1_type[$i];
352 $localtax2 = $newlocaltax2_tx[$i];
353 $localtax2_type = $newlocaltax2_type[$i];
354 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
356 $vatratecode = $reg[1];
358 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
359 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
360 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
361 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
362 $sql .=
" AND t.code ='".$db->escape($vatratecode).
"'";
363 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
364 $resql = $db->query($sql);
366 $obj = $db->fetch_object($resql);
368 $npr = $obj->recuperableonly;
369 $localtax1 = $obj->localtax1;
370 $localtax2 = $obj->localtax2;
371 $localtax1_type = $obj->localtax1_type;
372 $localtax2_type = $obj->localtax2_type;
376 if (in_array(
$mysoc->country_code, array(
'ES'))) {
383 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
384 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
385 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
386 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
387 $sql .=
" AND t.code = ''";
388 $resql = $db->query($sql);
390 $obj = $db->fetch_object($resql);
392 $npr = $obj->recuperableonly;
393 $localtax1 = $obj->localtax1;
394 $localtax2 = $obj->localtax2;
395 $localtax1_type = $obj->localtax1_type;
396 $localtax2_type = $obj->localtax2_type;
401 $pricestoupdate[$i] = array(
403 'price' =>
price2num($newprice[$i],
'', 2),
404 'price_min' =>
price2num($newprice_min[$i],
'', 2),
405 'price_base_type' => $newpricebase[$i],
406 'default_vat_code' => $vatratecode,
409 'localtaxes_array' => array(
'0' => $localtax1_type,
'1' => $localtax1,
'2' => $localtax2_type,
'3' => $localtax2)
420 $newpricebase =
GETPOST(
'price_base_type',
'alpha');
421 $tva_tx_txt =
GETPOST(
'tva_tx',
'alpha');
422 $price_label =
GETPOST(
'price_label',
'alpha');
424 $tva_tx = $tva_tx_txt;
427 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
428 $vat_src_code = $reg[1];
429 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
431 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
433 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
436 $localtax1_type =
'0';
437 $localtax2_type =
'0';
439 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
441 $vatratecode = $reg[1];
443 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
444 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
445 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
446 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
447 $sql .=
" AND t.code ='".$db->escape($vatratecode).
"'";
448 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
449 $resql = $db->query($sql);
451 $obj = $db->fetch_object($resql);
453 $npr = $obj->recuperableonly;
454 $localtax1 = $obj->localtax1;
455 $localtax2 = $obj->localtax2;
456 $localtax1_type = $obj->localtax1_type;
457 $localtax2_type = $obj->localtax2_type;
461 if (in_array(
$mysoc->country_code, array(
'ES'))) {
468 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
469 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
470 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
471 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
472 $sql .=
" AND t.code = ''";
473 $resql = $db->query($sql);
475 $obj = $db->fetch_object($resql);
477 $npr = $obj->recuperableonly;
478 $localtax1 = $obj->localtax1;
479 $localtax2 = $obj->localtax2;
480 $localtax1_type = $obj->localtax1_type;
481 $localtax2_type = $obj->localtax2_type;
486 $pricestoupdate[0] = array(
487 'price' => $newprice,
488 'price_label' => $price_label,
489 'price_min' => $newprice_min,
490 'price_base_type' => $newpricebase,
491 'default_vat_code' => $vatratecode,
494 'localtaxes_array' => array(
'0' => $localtax1_type,
'1' => $localtax1,
'2' => $localtax2_type,
'3' => $localtax2)
503 $object->packaging = (float) $packaging;
506 foreach ($pricestoupdate as $key => $val) {
507 $newprice = $val[
'price'];
509 if ($val[
'price'] < $val[
'price_min'] && !empty(
$object->fk_price_expression)) {
510 $newprice = $val[
'price_min'];
514 $newprice_min =
price2num($val[
'price_min'],
'MU');
517 if (
getDolGlobalString(
'PRODUCT_MINIMUM_RECOMMENDED_PRICE') && $newprice_min < $maxpricesupplier) {
518 setEventMessages($langs->trans(
"MinimumPriceLimit",
price($maxpricesupplier, 0,
'', 1, - 1, - 1,
'auto')),
null,
'errors');
523 if (!array_key_exists($key,
$object->multiprices) ||
$object->multiprices[$key] != $newprice ||
$object->multiprices_min[$key] != $newprice_min ||
$object->multiprices_base_type[$key] != $val[
'price_base_type'] ||
$object->multiprices_tva_tx[$key] != $newvattx) {
524 $res =
$object->updatePrice((
float) $newprice, $val[
'price_base_type'], $user, (
float) $val[
'vat_tx'], (
float) $newprice_min, $key, $val[
'npr'], $psq, 0, $val[
'localtaxes_array'], $val[
'default_vat_code'], $val[
'price_label']);
536 $price_extralabels = $extrafields->fetch_name_optionals_label(
"product_price");
538 $sql =
"SELECT rowid";
539 $sql .=
" FROM ".$object->db->prefix().
"product_price";
540 $sql .=
" WHERE entity IN (".getEntity(
'productprice').
")";
541 $sql .=
" AND price_level=".((int) $key);
542 $sql .=
" AND fk_product = ".((int)
$object->id);
543 $sql .=
" ORDER BY date_price DESC, rowid DESC";
545 $resql =
$object->db->query($sql);
547 $lineid =
$object->db->fetch_object($resql);
550 if (!empty($lineid->rowid)) {
551 require_once DOL_DOCUMENT_ROOT .
'/core/class/genericobject.class.php';
554 $genericObject->id = $lineid->rowid;
555 $genericObject->table_element =
'product_price';
556 foreach ($price_extralabels as $code => $label) {
557 $extrafield_values = $extrafields->getOptionalsFromPost(
'product_price', (
string) $key);
558 $genericObject->array_options[
'options_'.$code] = $extrafield_values[
'options_'.$code];
560 $result = $genericObject->insertExtraFields();
563 setEventMessages($genericObject->error, $genericObject->errors,
'errors');
578 setEventMessages($langs->trans(
"RecordSaved"),
null,
'mesgs');
581 $action =
'edit_price';
587 if ($action ==
'delete' && $user->hasRight(
'produit',
'supprimer')) {
595 if ($action ==
'activate_price_by_qty' && $permissiontoadd) {
600 $ret =
$object->updatePrice($basePrice,
$object->price_base_type, $user,
$object->tva_tx, $basePriceMin, $level,
$object->tva_npr, 1, 0, array(),
$object->default_vat_code);
607 if ($action ==
'disable_price_by_qty' && $permissiontoadd) {
612 $ret =
$object->updatePrice($basePrice,
$object->price_base_type, $user,
$object->tva_tx, $basePriceMin, $level,
$object->tva_npr, 0, 0, array(),
$object->default_vat_code);
619 if ($action ==
'edit_price_by_qty') {
624 if ($action ==
'update_price_by_qty' && $permissiontoadd) {
634 if (empty($quantity)) {
636 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentities(
"Qty")),
null,
'errors');
638 if (empty($newprice)) {
640 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentities(
"Price")),
null,
'errors');
642 if (!$error && !($rowid > 0)) {
644 $sql =
"SELECT pp.rowid FROM ".MAIN_DB_PREFIX.
"product_price as pp";
645 $sql .=
" WHERE pp.rowid = ".((int) $priceid).
" AND pp.fk_product = ".((int)
$object->id);
646 $resql = $db->query($sql);
647 if (!$resql || !$db->num_rows($resql)) {
649 setEventMessages($langs->trans(
"ErrorRecordNotFound"),
null,
'errors');
654 if (
$object->price_base_type ==
'TTC') {
659 $unitPrice =
price2num((
float) $price / (
float) $quantity,
'MU');
663 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"product_price_by_qty SET";
664 $sql .=
" price=".((float) $price).
",";
665 $sql .=
" unitprice=".((float) $unitPrice).
",";
666 $sql .=
" quantity=".((float) $quantity).
",";
667 $sql .=
" remise_percent=".((float) $remise_percent).
",";
668 $sql .=
" remise=".((float) $remise);
669 $sql .=
" WHERE rowid = ".((int) $rowid);
670 $sql .=
" AND fk_product_price IN (SELECT pp.rowid FROM ".MAIN_DB_PREFIX.
"product_price as pp WHERE pp.fk_product = ".((int)
$object->id).
")";
672 $result = $db->query($sql);
674 dol_print_error($db);
677 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"product_price_by_qty (fk_product_price,price,unitprice,quantity,remise_percent,remise) values (";
678 $sql .= ((int) $priceid).
','.((float) $price).
','.((float) $unitPrice).
','.((float) $quantity).
','.((float) $remise_percent).
','.((float) $remise).
')';
680 $result = $db->query($sql);
682 if ($db->lasterrno() ==
'DB_ERROR_RECORD_ALREADY_EXISTS') {
683 setEventMessages($langs->trans(
"DuplicateRecord"),
null,
'errors');
685 dol_print_error($db);
692 if ($action ==
'delete_price_by_qty' && $permissiontoadd) {
694 if (!empty($rowid)) {
695 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"product_price_by_qty";
696 $sql .=
" WHERE rowid = ".((int) $rowid);
697 $sql .=
" AND fk_product_price IN (SELECT pp.rowid FROM ".MAIN_DB_PREFIX.
"product_price as pp WHERE pp.fk_product = ".((int)
$object->id).
")";
699 $result = $db->query($sql);
701 setEventMessages((
'delete_price_by_qty'.$langs->transnoentities(
'MissingIds')),
null,
'errors');
705 if ($action ==
'delete_all_price_by_qty' && $permissiontoadd) {
707 if (!empty($priceid)) {
708 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"product_price_by_qty";
709 $sql .=
" WHERE fk_product_price = ".((int) $priceid);
710 $sql .=
" AND fk_product_price IN (SELECT pp.rowid FROM ".MAIN_DB_PREFIX.
"product_price as pp WHERE pp.fk_product = ".((int)
$object->id).
")";
712 $result = $db->query($sql);
714 setEventMessages((
'delete_price_by_qty'.$langs->transnoentities(
'MissingIds')),
null,
'errors');
723 if ($action ==
'add_customer_price_confirm' && !$cancel && $prodcustprice !==
null && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
724 $maxpricesupplier =
$object->min_recommended_price();
726 $update_child_soc =
GETPOSTINT(
'updatechildprice');
730 $prodcustprice->ref_customer =
GETPOST(
'ref_customer',
'alpha');
731 $prodcustprice->fk_product =
$object->id;
734 $prodcustprice->price_base_type =
GETPOST(
"price_base_type",
'alpha');
735 $prodcustprice->price_label =
GETPOST(
"price_label",
'alpha');
740 $extralabels = $extrafields->fetch_name_optionals_label(
"product_customer_price");
741 $extrafield_values = $extrafields->getOptionalsFromPost(
"product_customer_price");
743 $tva_tx_txt =
GETPOST(
"tva_tx",
'alpha');
745 $tva_tx = $tva_tx_txt;
747 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
748 $vat_src_code = $reg[1];
749 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
751 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
753 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
756 $localtax1_type =
'0';
757 $localtax2_type =
'0';
759 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
761 $vatratecode = $reg[1];
763 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
764 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
765 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
766 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
767 $sql .=
" AND t.code ='".$db->escape($vatratecode).
"'";
768 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
769 $resql = $db->query($sql);
771 $obj = $db->fetch_object($resql);
773 $npr = $obj->recuperableonly;
774 $localtax1 = $obj->localtax1;
775 $localtax2 = $obj->localtax2;
776 $localtax1_type = $obj->localtax1_type;
777 $localtax2_type = $obj->localtax2_type;
781 if (in_array(
$mysoc->country_code, array(
'ES'))) {
788 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
789 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
790 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
791 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
792 $sql .=
" AND t.code = ''";
793 $resql = $db->query($sql);
795 $obj = $db->fetch_object($resql);
797 $npr = $obj->recuperableonly;
798 $localtax1 = $obj->localtax1;
799 $localtax2 = $obj->localtax2;
800 $localtax1_type = $obj->localtax1_type;
801 $localtax2_type = $obj->localtax2_type;
806 $prodcustprice->default_vat_code = $vatratecode;
807 $prodcustprice->tva_tx = $tva_tx;
808 $prodcustprice->recuperableonly = $npr;
809 $prodcustprice->localtax1_tx = $localtax1;
810 $prodcustprice->localtax2_tx = $localtax2;
811 $prodcustprice->localtax1_type = $localtax1_type;
812 $prodcustprice->localtax2_type = $localtax2_type;
814 if (!($prodcustprice->fk_soc > 0)) {
815 $langs->load(
"errors");
816 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"ThirdParty")),
null,
'errors');
818 $action =
'add_customer_price';
820 if (
getDolGlobalString(
'PRODUCT_MINIMUM_RECOMMENDED_PRICE') && $prodcustprice->price_min < (
float) $maxpricesupplier) {
821 $langs->load(
"errors");
822 setEventMessages($langs->trans(
"MinimumPriceLimit",
price((
float) $maxpricesupplier, 0,
'', 1, -1, -1,
'auto')),
null,
'errors');
824 $action =
'add_customer_price';
829 $result = $prodcustprice->create($user, 0, $update_child_soc);
831 if (!empty($extrafield_values) && is_array($extrafield_values)) {
833 $res = $productcustomerprice->fetch($prodcustprice->id);
835 foreach ($extrafield_values as $key => $value) {
836 $productcustomerprice->array_options[$key] = $value;
838 $result2 = $productcustomerprice->insertExtraFields();
840 $prodcustprice->error = $productcustomerprice->error;
841 $prodcustprice->errors = $productcustomerprice->errors;
849 setEventMessages($prodcustprice->error, $prodcustprice->errors,
'errors');
850 $action =
'add_customer_price';
852 setEventMessages($langs->trans(
'RecordSaved'),
null,
'mesgs');
859 if (in_array($action, [
'confirm_remove_customer_price',
'update_customer_price_confirm']) && $prodcustprice !==
null) {
861 if ((
int) $prodcustprice->fk_product !== (
int)
$object->id) {
862 setEventMessages($langs->trans(
"ErrorRecordNotFound"),
null,
'errors');
867 if ($action ==
'confirm_remove_customer_price' && $prodcustprice !==
null && ($user->hasRight(
'produit',
'supprimer') || $user->hasRight(
'service',
'supprimer'))) {
869 $update_child_soc =
GETPOSTINT(
'updatechildprice');
872 $result = $prodcustprice->delete($user, 0, $update_child_soc);
875 $db->query(
"DELETE FROM ".MAIN_DB_PREFIX.
"product_customer_price_extrafields WHERE fk_object = ".((
int) $prodcustprice->id));
876 setEventMessages($langs->trans(
"PriceRemoved"),
null,
'mesgs');
883 setEventMessages($prodcustprice->error, $prodcustprice->errors,
'errors');
885 setEventMessages($langs->trans(
'RecordDeleted'),
null,
'mesgs');
890 if ($action ==
'update_customer_price_confirm' && !$cancel && $prodcustprice !==
null && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
891 $maxpricesupplier =
$object->min_recommended_price();
893 $update_child_soc =
GETPOSTINT(
'updatechildprice');
898 $prodcustprice->ref_customer =
GETPOST(
'ref_customer',
'alpha');
901 $prodcustprice->price_base_type =
GETPOST(
"price_base_type",
'alpha');
902 $prodcustprice->price_label =
GETPOST(
"price_label",
'alpha');
907 $extralabels = $extrafields->fetch_name_optionals_label(
"product_customer_price");
908 $extrafield_values = $extrafields->getOptionalsFromPost(
"product_customer_price");
910 $tva_tx_txt =
GETPOST(
"tva_tx");
912 $tva_tx = $tva_tx_txt;
914 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
915 $vat_src_code = $reg[1];
916 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
918 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
920 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
923 $localtax1_type =
'0';
924 $localtax2_type =
'0';
926 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
928 $vatratecode = $reg[1];
930 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
931 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
932 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
933 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
934 $sql .=
" AND t.code ='".$db->escape($vatratecode).
"'";
935 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
936 $resql = $db->query($sql);
938 $obj = $db->fetch_object($resql);
940 $npr = $obj->recuperableonly;
941 $localtax1 = $obj->localtax1;
942 $localtax2 = $obj->localtax2;
943 $localtax1_type = $obj->localtax1_type;
944 $localtax2_type = $obj->localtax2_type;
948 if (in_array(
$mysoc->country_code, array(
'ES'))) {
955 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
956 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
957 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
958 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
959 $sql .=
" AND t.code = ''";
960 $resql = $db->query($sql);
962 $obj = $db->fetch_object($resql);
964 $npr = $obj->recuperableonly;
965 $localtax1 = $obj->localtax1;
966 $localtax2 = $obj->localtax2;
967 $localtax1_type = $obj->localtax1_type;
968 $localtax2_type = $obj->localtax2_type;
973 $prodcustprice->default_vat_code = $vatratecode;
974 $prodcustprice->tva_tx = $tva_tx;
975 $prodcustprice->recuperableonly = $npr;
976 $prodcustprice->localtax1_tx = $localtax1;
977 $prodcustprice->localtax2_tx = $localtax2;
978 $prodcustprice->localtax1_type = $localtax1_type;
979 $prodcustprice->localtax2_type = $localtax2_type;
981 if ($prodcustprice->price_min < $maxpricesupplier &&
getDolGlobalString(
'PRODUCT_MINIMUM_RECOMMENDED_PRICE')) {
982 setEventMessages($langs->trans(
"MinimumPriceLimit",
price($maxpricesupplier, 0,
'', 1, -1, -1,
'auto')),
null,
'errors');
984 $action =
'update_customer_price';
988 $result = $prodcustprice->update($user, 0, $update_child_soc);
990 if (!empty($extrafield_values) && is_array($extrafield_values)) {
992 $res = $productcustomerprice->fetch($prodcustprice->id);
994 foreach ($extrafield_values as $key => $value) {
995 $productcustomerprice->array_options[$key] = $value;
997 $result2 = $productcustomerprice->insertExtraFields();
999 $prodcustprice->error = $productcustomerprice->error;
1000 $prodcustprice->errors = $productcustomerprice->errors;
1008 setEventMessages($prodcustprice->error, $prodcustprice->errors,
'errors');
1009 $action =
'update_customer_price';
1011 setEventMessages($langs->trans(
"Save"),
null,
'mesgs');
1023$form =
new Form($db);
1025if (!empty($id) || !empty($ref)) {
1030$title = $langs->trans(
'ProductServiceCard');
1034 $title = $langs->trans(
'Product').
" ".$shortlabel.
" - ".$langs->trans(
'SellingPrices');
1035 $helpurl =
'EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos';
1038 $title = $langs->trans(
'Service').
" ".$shortlabel.
" - ".$langs->trans(
'SellingPrices');
1039 $helpurl =
'EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios';
1042llxHeader(
'', $title, $helpurl,
'', 0, 0,
'',
'',
'',
'classforhorizontalscrolloftabs mod-product page-price');
1044if ($action ==
'ask_remove_customer_price' && ($user->hasRight(
'produit',
'supprimer') || $user->hasRight(
'service',
'supprimer'))) {
1045 $formquestion = array(
1046 array(
'type' =>
'checkbox',
'name' =>
'updatechildprice',
'label' => $langs->trans(
'ForceDeleteChildPriceSoc'),
'value' => 0),
1048 $formconfirm = $form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&lineid='.
GETPOSTINT(
'lineid'), $langs->trans(
'DeleteCustomerPrice'), $langs->trans(
'ConfirmDeleteCustomerPrice'),
'confirm_remove_customer_price', $formquestion, 0, 1);
1053$titre = $langs->trans(
"CardProduct".
$object->type);
1058$linkback =
'<a href="'.DOL_URL_ROOT.
'/product/list.php?restore_lastsearch_values=1&type='.
$object->type.
'">'.$langs->trans(
"BackToList").
'</a>';
1059$object->next_prev_filter =
"(te.fk_product_type:=:".((int)
$object->type).
")";
1062if ($user->socid && !in_array(
'product', explode(
',',
getDolGlobalString(
'MAIN_MODULES_FOR_EXTERNAL')))) {
1066dol_banner_tab($object,
'ref', $linkback, $shownav,
'ref');
1069print
'<div class="fichecenter">';
1071print
'<div class="underbanner clearboth"></div>';
1072print
'<table class="border tableforfield centpercent">';
1079 if (!empty($socid)) {
1082 $soc->fetch($socid);
1086 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
1087 print
'<tr><td class="">';
1088 print (!
getDolGlobalString(
'PRODUCT_DENY_CHANGE_PRODUCT_TYPE')) ? $form->editfieldkey(
"Type",
'fk_product_type', (
string)
$object->type, $object, 0, $typeformat) : $langs->trans(
'Type');
1090 print $form->editfieldval(
"Type",
'fk_product_type',
$object->type, $object, 0, $typeformat);
1095 print
'<tr><td class="titlefieldcreate">';
1096 print $langs->trans(
"SellingPrice");
1098 print
'<td colspan="2">';
1099 if (
$object->multiprices_base_type[$soc->price_level] ==
'TTC') {
1100 print
'<span class="amount">'.price(
$object->multiprices_ttc[$soc->price_level]).
'</span>';
1102 print
'<span class="amount">'.price(
$object->multiprices[$soc->price_level]).
'</span>';
1104 if (
$object->multiprices_base_type[$soc->price_level]) {
1105 print
' '.$langs->trans(
$object->multiprices_base_type[$soc->price_level]);
1107 print
' '.$langs->trans(
$object->price_base_type);
1112 print
'<tr><td>'.$langs->trans(
"MinPrice").
'</td><td colspan="2">';
1113 if (
$object->multiprices_base_type[$soc->price_level] ==
'TTC') {
1114 print
price(
$object->multiprices_min_ttc[$soc->price_level]).
' '.$langs->trans(
$object->multiprices_base_type[$soc->price_level]);
1116 print
price(
$object->multiprices_min[$soc->price_level]).
' '.$langs->trans(empty(
$object->multiprices_base_type[$soc->price_level]) ?
'HT' :
$object->multiprices_base_type[$soc->price_level]);
1122 print
'<tr><td>'.$langs->trans(
"DefaultTaxRate").
'</td><td colspan="2">';
1124 $positiverates =
'';
1126 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->multiprices_tva_tx[$soc->price_level]);
1129 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->multiprices_localtax1_tx[$soc->price_level]);
1132 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->multiprices_localtax2_tx[$soc->price_level]);
1134 if (empty($positiverates)) {
1135 $positiverates =
'0';
1137 echo
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr);
1142 print
'<tr><td>'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1144 $positiverates =
'';
1149 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax1_tx);
1152 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax2_tx);
1154 if (empty($positiverates)) {
1155 $positiverates =
'0';
1157 echo
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr);
1165 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
1166 print
'<tr><td class="">';
1167 print (!
getDolGlobalString(
'PRODUCT_DENY_CHANGE_PRODUCT_TYPE')) ? $form->editfieldkey(
"Type",
'fk_product_type', (
string)
$object->type, $object, 0, $typeformat) : $langs->trans(
'Type');
1169 print $form->editfieldval(
"Type",
'fk_product_type',
$object->type, $object, 0, $typeformat);
1174 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"DefaultTaxRate").
'</td>';
1175 print
'<td colspan="2">'.vatrate(
$object->multiprices_tva_tx[1],
true).
'</td>';
1180 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
1181 print
'<tr><td class="">';
1182 print (!
getDolGlobalString(
'PRODUCT_DENY_CHANGE_PRODUCT_TYPE')) ? $form->editfieldkey(
"Type",
'fk_product_type', (
string)
$object->type, $object, 0, $typeformat) : $langs->trans(
'Type');
1184 print $form->editfieldval(
"Type",
'fk_product_type',
$object->type, $object, 0, $typeformat);
1189 print
'<!-- Default VAT Rate -->';
1190 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1193 $positiverates =
'';
1195 $positiverates .= ($positiverates ?
'<span class="opacitymedium">/</span>' :
'').
price2num(
$object->tva_tx);
1198 $positiverates .= ($positiverates ?
'<span class="opacitymedium">/</span>' :
'').
price2num(
$object->localtax1_tx);
1201 $positiverates .= ($positiverates ?
'<span class="opacitymedium">/</span>' :
'').
price2num(
$object->localtax2_tx);
1203 if (empty($positiverates)) {
1204 $positiverates =
'0';
1207 print
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr, 1);
1220 print
'<table class="liste centpercent">';
1221 print
'<tr class="liste_titre"><td>';
1222 print $langs->trans(
"PriceLevel");
1224 print
' <a class="editfielda" href="'.dolBuildUrl($_SERVER[
"PHP_SELF"], [
'action' =>
'editlabelsellingprice',
'id' =>
$object->id],
true).
'">'.img_edit($langs->trans(
'EditSellingPriceLabel'), 0).
'</a>';
1227 print
'<td style="text-align: right">'.$langs->trans(
"SellingPrice").
'</td>';
1228 print
'<td style="text-align: right">'.$langs->trans(
"MinPrice").
'</td>';
1230 $extrafields->fetch_name_optionals_label(
"product_price");
1231 if ($extrafields->attributes[
"product_price"] && array_key_exists(
'label', $extrafields->attributes[
"product_price"])) {
1232 $extralabels = $extrafields->attributes[
"product_price"][
'label'];
1233 if (!empty($extralabels)) {
1234 foreach ($extralabels as $key => $value) {
1236 if (!empty($extrafields->attributes[
"product_price"][
'list'][$key]) && $extrafields->attributes[
"product_price"][
'list'][$key] != 3) {
1237 if (!empty($extrafields->attributes[
"product_price"][
'langfile'][$key])) {
1238 $langs->load($extrafields->attributes[
"product_price"][
'langfile'][$key]);
1240 if (!empty($extrafields->attributes[
"product_price"][
'help'][$key])) {
1241 $extratitle = $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_price"][
'help'][$key]));
1243 $extratitle = $langs->trans($value);
1245 $field =
'ef.' . $key;
1246 print
'<td style="text-align: right">'.$extratitle.
'</td>';
1253 $produit_multiprices_limit =
getDolGlobalInt(
'PRODUIT_MULTIPRICES_LIMIT');
1254 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
1255 print
'<tr class="oddeven">';
1259 $keyforlabel =
'PRODUIT_MULTIPRICES_LABEL'.$i;
1260 if (preg_match(
'/editlabelsellingprice/', $action)) {
1261 print
'<form method="post" action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'">';
1262 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1263 print
'<input type="hidden" name="action" value="setlabelsellingprice">';
1264 print
'<input type="hidden" name="pricelevel" value="'.$i.
'">';
1265 print $langs->trans(
"SellingPrice").
' '.$i.
' - ';
1266 print
'<input class="maxwidthonsmartphone" type="text" name="labelsellingprice" value="' .
getDolGlobalString($keyforlabel).
'">';
1267 print
' <input type="submit" class="button smallpaddingimp" value="'.$langs->trans(
"Modify").
'">';
1270 print $langs->trans(
"SellingPrice").
' '.$i;
1277 if (
$object->multiprices_base_type [$i] ==
'TTC') {
1278 print
'<td class="right"><span class="amount">'.price(
$object->multiprices_ttc[$i]);
1280 print
'<td class="right"><span class="amount">'.price(
$object->multiprices[$i]);
1283 if (
$object->multiprices_base_type[$i]) {
1284 print
' '.$langs->trans(
$object->multiprices_base_type [$i]).
'</span></td>';
1286 print
' '.$langs->trans(
$object->price_base_type).
'</span></td>';
1290 print
'<td style="text-align: right">';
1291 if (empty(
$object->multiprices_base_type[$i])) {
1292 $object->multiprices_base_type[$i] =
"HT";
1294 if (
$object->multiprices_base_type[$i] ==
'TTC') {
1295 print
price(
$object->multiprices_min_ttc[$i]).
' '.$langs->trans(
$object->multiprices_base_type[$i]);
1297 print
price(
$object->multiprices_min[$i]).
' '.$langs->trans(
$object->multiprices_base_type[$i]);
1300 if (!empty($extralabels)) {
1301 require_once DOL_DOCUMENT_ROOT .
'/core/class/genericobject.class.php';
1304 $genericObject->table_element =
'product_price';
1305 $sql1 =
"SELECT rowid";
1306 $sql1 .=
" FROM ".$object->db->prefix().
"product_price";
1307 $sql1 .=
" WHERE entity IN (".getEntity(
'productprice').
")";
1308 $sql1 .=
" AND price_level=".((int) $i);
1309 $sql1 .=
" AND fk_product = ".((int)
$object->id);
1310 $sql1 .=
" ORDER BY date_price DESC, rowid DESC";
1311 $sql1 .=
" LIMIT 1";
1312 $resql1 =
$object->db->query($sql1);
1313 if ($resql1 && $lineid =
$object->db->fetch_object($resql1)) {
1314 $genericObject->id = $lineid->rowid;
1315 $genericObject->fetch_optionals();
1317 foreach ($extralabels as $key => $value) {
1318 if (!empty($extrafields->attributes[
"product_price"][
'list'][$key]) && $extrafields->attributes[
"product_price"][
'list'][$key] != 3) {
1319 $extravalue = $genericObject->array_options[
'options_' . $key];
1321 if (!empty($extrafields->attributes[
"product_price"][
'computed'][$key])) {
1322 $genericObject->price =
$object->multiprices[$i];
1323 $genericObject->price_ttc =
$object->multiprices_ttc[$i];
1324 $genericObject->price_base_type =
$object->multiprices_base_type[$i];
1325 $genericObject->price_min =
$object->multiprices_min[$i];
1326 $genericObject->price_min_ttc =
$object->multiprices_min_ttc[$i];
1327 $genericObject->tva_tx =
$object->multiprices_tva_tx[$i];
1329 $objectoffield = $genericObject;
1330 $extravalue =
dol_eval((
string) $extrafields->attributes[
"product_price"][
'computed'][$key], 1, 1,
'2');
1332 print
'<td align="right">'.$extrafields->showOutputField($key, $extravalue,
'',
'product_price').
"</td>";
1341 print
'<tr><td>'.$langs->trans(
"PriceByQuantity").
' '.$i;
1345 print
'</td><td colspan="2">';
1347 if (
$object->prices_by_qty[$i] == 1) {
1348 print
'<table width="50%" class="border" summary="List of quantities">';
1350 print
'<tr class="liste_titre">';
1351 print
'<td>'.$langs->trans(
"PriceByQuantityRange").
' '.$i.
'</td>';
1352 print
'<td class="right">'.$langs->trans(
"HT").
'</td>';
1353 print
'<td class="right">'.$langs->trans(
"UnitPrice").
'</td>';
1354 print
'<td class="right">'.$langs->trans(
"Discount").
'</td>';
1355 print
'<td> </td>';
1358 foreach (
$object->prices_by_qty_list[$i] as $ii => $prices) {
1359 if ($action ==
'edit_price_by_qty' && $rowid == $prices[
'rowid'] && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1360 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1361 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1362 print
'<input type="hidden" name="action" value="update_price_by_qty">';
1363 print
'<input type="hidden" name="priceid" value="'.$object->prices_by_qty_id[$i].
'">';
1364 print
'<input type="hidden" value="'.$prices[
'rowid'].
'" name="rowid">';
1365 print
'<tr class="'.($ii % 2 == 0 ?
'pair' :
'impair').
'">';
1366 print
'<td><input size="5" type="text" value="'.$prices[
'quantity'].
'" name="quantity"></td>';
1367 print
'<td class="right" colspan="2"><input size="10" type="text" value="'.price2num($prices[
'price'],
'MU').
'" name="price"> '.
$object->price_base_type.
'</td>';
1368 print
'<td class="right nowraponall"><input size="5" type="text" value="'.$prices[
'remise_percent'].
'" name="remise_percent"> %</td>';
1369 print
'<td class="center"><input type="submit" value="'.$langs->trans(
"Modify").
'" class="button"></td>';
1373 print
'<tr class="'.($ii % 2 == 0 ?
'pair' :
'impair').
'">';
1374 print
'<td>'.$prices[
'quantity'].
'</td>';
1375 print
'<td class="right">'.price($prices[
'price']).
'</td>';
1376 print
'<td class="right">'.price($prices[
'unitprice']).
'</td>';
1377 print
'<td class="right">'.price($prices[
'remise_percent']).
' %</td>';
1378 print
'<td class="center">';
1379 if (($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1380 print
'<a class="editfielda marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=edit_price_by_qty&token='.
newToken().
'&rowid='.$prices[
"rowid"].
'">';
1381 print img_edit().
'</a>';
1382 print
'<a class="marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=delete_price_by_qty&token='.
newToken().
'&rowid='.$prices[
"rowid"].
'">';
1383 print img_delete().
'</a>';
1391 if ($action !=
'edit_price_by_qty' && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1392 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1393 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1394 print
'<input type="hidden" name="action" value="update_price_by_qty">';
1395 print
'<input type="hidden" name="priceid" value="'.$object->prices_by_qty_id[$i].
'">';
1396 print
'<input type="hidden" value="0" name="rowid">';
1397 print
'<tr class="'.($ii % 2 == 0 ?
'pair' :
'impair').
'">';
1398 print
'<td><input size="5" type="text" value="1" name="quantity"></td>';
1399 print
'<td class="right" class="nowrap"><input size="10" type="text" value="0" name="price"> '.$object->price_base_type.
'</td>';
1400 print
'<td class="right"> </td>';
1401 print
'<td class="right" class="nowraponall"><input size="5" type="text" value="0" name="remise_percent"> %</td>';
1402 print
'<td class="center"><input type="submit" value="'.$langs->trans(
"Add").
'" class="button"></td>';
1408 print
'<a class="editfielda marginleftonly marginrightonly" href="'.$_SERVER[
'PHP_SELF'].
'?id='.
$object->id.
'&action=disable_price_by_qty&level='.$i.
'&token='.
newToken().
'">('.$langs->trans(
"DisablePriceByQty").
')</a>';
1410 print $langs->trans(
"No");
1411 print
' <a class="marginleftonly marginrightonly" href="'.$_SERVER[
'PHP_SELF'].
'?id='.
$object->id.
'&action=activate_price_by_qty&level='.$i.
'&token='.
newToken().
'">('.$langs->trans(
"Activate").
')</a>';
1420 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
1421 print
'<tr><td class="">';
1422 print (!
getDolGlobalString(
'PRODUCT_DENY_CHANGE_PRODUCT_TYPE')) ? $form->editfieldkey(
"Type",
'fk_product_type', (
string)
$object->type, $object, 0, $typeformat) : $langs->trans(
'Type');
1424 print $form->editfieldval(
"Type",
'fk_product_type',
$object->type, $object, 0, $typeformat);
1429 print
'<tr><td class="titlefield">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1431 $positiverates =
'';
1436 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax1_tx);
1439 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax2_tx);
1441 if (empty($positiverates)) {
1442 $positiverates =
'0';
1444 echo
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr, 0, 1);
1454 print
'<tr class="field_selling_price"><td>'.$langs->trans(
"SellingPrice").
'</td><td>';
1455 if (
$object->price_base_type ==
'TTC') {
1460 print
'<i class="opacitymedium"> - ' .
price(
$object->price_ttc).
' '.$langs->trans(
'TTC') .
'</i>';
1467 print
'<tr class="field_min_price"><td>'.$langs->trans(
"MinPrice").
'</td><td>';
1468 if (
$object->price_base_type ==
'TTC') {
1473 print
'<i class="opacitymedium"> - ' .
price(
$object->price_min_ttc).
' '.$langs->trans(
'TTC') .
'</i>';
1480 print
'<tr class="field_price_label"><td>'.$form->textwithpicto($langs->trans(
"PackagingForThisProduct"), $langs->trans(
"PackagingForThisProductDesc")).
'</td><td>';
1486 print
'<tr class="field_price_label"><td>'.$langs->trans(
"PriceLabel").
'</td><td>';
1493 print
'<tr><td>'.$langs->trans(
"PriceByQuantity");
1494 if (
$object->prices_by_qty[0] == 0) {
1495 print
' <a href="'.$_SERVER[
'PHP_SELF'].
'?id='.
$object->id.
'&action=activate_price_by_qty&level=1&token='.
newToken().
'">('.$langs->trans(
"Activate").
')';
1497 print
' <a href="'.$_SERVER[
'PHP_SELF'].
'?id='.
$object->id.
'&action=disable_price_by_qty&level=1&token='.
newToken().
'">('.$langs->trans(
"DisablePriceByQty").
')';
1501 if (
$object->prices_by_qty[0] == 1) {
1502 print
'<table width="50%" class="border" summary="List of quantities">';
1503 print
'<tr class="liste_titre">';
1505 print
'<td>'.$langs->trans(
"Quantity").
'</td>';
1506 print
'<td class="right">'.$langs->trans(
"Price").
'</td>';
1507 print
'<td class="right"></td>';
1508 print
'<td class="right">'.$langs->trans(
"UnitPrice").
'</td>';
1509 print
'<td class="right">'.$langs->trans(
"Discount").
'</td>';
1510 print
'<td> </td>';
1512 if ($action !=
'edit_price_by_qty') {
1513 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1514 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1515 print
'<input type="hidden" name="action" value="update_price_by_qty">';
1516 print
'<input type="hidden" name="priceid" value="'.$object->prices_by_qty_id[0].
'">';
1517 print
'<input type="hidden" value="0" name="rowid">';
1519 print
'<tr class="'.(($ii % 2) == 0 ?
'pair' :
'impair').
'">';
1520 print
'<td><input size="5" type="text" value="1" name="quantity"></td>';
1521 print
'<td class="right"><input class="width50 right" type="text" value="0" name="price"></td>';
1525 print
'<td class="right"> </td>';
1526 print
'<td class="right nowraponall"><input type="text" class="width50 right" value="0" name="remise_percent"> %</td>';
1527 print
'<td class="center"><input type="submit" value="'.$langs->trans(
"Add").
'" class="button"></td>';
1532 foreach (
$object->prices_by_qty_list[0] as $ii => $prices) {
1533 if ($action ==
'edit_price_by_qty' && $rowid == $prices[
'rowid'] && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1534 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1535 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1536 print
'<input type="hidden" name="action" value="update_price_by_qty">';
1537 print
'<input type="hidden" name="priceid" value="'.$object->prices_by_qty_id[0].
'">';
1538 print
'<input type="hidden" value="'.$prices[
'rowid'].
'" name="rowid">';
1539 print
'<tr class="'.($ii % 2 == 0 ?
'pair' :
'impair').
'">';
1540 print
'<td><input size="5" type="text" value="'.$prices[
'quantity'].
'" name="quantity"></td>';
1541 print
'<td class="right"><input class="width50 right" type="text" value="'.price2num($prices[
'price'],
'MU').
'" name="price"></td>';
1542 print
'<td class="right">';
1544 print $prices[
'price_base_type'];
1546 print
'<td class="right"> </td>';
1547 print
'<td class="right nowraponall"><input class="width50 right" type="text" value="'.$prices[
'remise_percent'].
'" name="remise_percent"> %</td>';
1548 print
'<td class="center"><input type="submit" value="'.$langs->trans(
"Modify").
'" class="button"></td>';
1552 print
'<tr class="'.($ii % 2 == 0 ?
'pair' :
'impair').
'">';
1553 print
'<td>'.$prices[
'quantity'].
'</td>';
1554 print
'<td class="right">'.price($prices[
'price']).
'</td>';
1555 print
'<td class="right">';
1557 print $prices[
'price_base_type'];
1559 print
'<td class="right">'.price($prices[
'unitprice']).
'</td>';
1560 print
'<td class="right">'.price($prices[
'remise_percent']).
' %</td>';
1561 print
'<td class="center">';
1562 if (($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1563 print
'<a class="editfielda marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=edit_price_by_qty&token='.
newToken().
'&rowid='.$prices[
"rowid"].
'">';
1564 print img_edit().
'</a>';
1565 print
'<a class="marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=delete_price_by_qty&token='.
newToken().
'&rowid='.$prices[
"rowid"].
'">';
1566 print img_delete().
'</a>';
1576 print $langs->trans(
"No");
1585print
'<div class="clearboth"></div>';
1594if (!$action || $action ==
'delete' || $action ==
'showlog_customer_price' || $action ==
'showlog_default_price' || $action ==
'add_customer_price'
1595 || $action ==
'activate_price_by_qty' || $action ==
'disable_price_by_qty') {
1596 print
"\n".
'<div class="tabsAction">'.
"\n";
1598 $parameters = array();
1599 $reshook = $hookmanager->executeHooks(
'addMoreActionsButtons', $parameters, $object, $action);
1600 if (empty($reshook)) {
1603 print
'<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' .
dol_escape_htmltag($langs->trans(
"NoEditVariants")) .
'">' . $langs->trans(
"UpdateDefaultPrice") .
'</a></div>';
1607 if ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer')) {
1608 print
'<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER[
'PHP_SELF'] .
'?action=edit_price&token='.newToken().
'&id=' .
$object->id .
'">' . $langs->trans(
"UpdateDefaultPrice") .
'</a></div>';
1610 print
'<div class="inline-block divButAction"><span class="butActionRefused" title="'.dol_escape_htmltag($langs->trans(
"NotEnoughPermissions")).
'">' . $langs->trans(
"UpdateDefaultPrice") .
'</span></div>';
1615 if ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer')) {
1616 print
'<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER[
"PHP_SELF"] .
'?action=add_customer_price&token='.newToken().
'&id=' .
$object->id .
'">' . $langs->trans(
"AddCustomerPrice") .
'</a></div>';
1618 print
'<div class="inline-block divButAction"><span class="butActionRefused" title="'.dol_escape_htmltag($langs->trans(
"NotEnoughPermissions")).
'">' . $langs->trans(
"AddCustomerPrice") .
'</span></div>';
1623 if ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer')) {
1624 print
'<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER[
'PHP_SELF'] .
'?action=edit_vat&token='.newToken().
'&id=' .
$object->id .
'">' . $langs->trans(
"UpdateVAT") .
'</a></div>';
1626 print
'<div class="inline-block divButAction"><span class="butActionRefused" title="'.dol_escape_htmltag($langs->trans(
"NotEnoughPermissions")).
'">' . $langs->trans(
"UpdateVAT") .
'</span></div>';
1629 if ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer')) {
1630 print
'<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER[
'PHP_SELF'] .
'?action=edit_level_price&token='.newToken().
'&id=' .
$object->id .
'">' . $langs->trans(
"UpdateLevelPrices") .
'</a></div>';
1632 print
'<div class="inline-block divButAction"><span class="butActionRefused" title="'.dol_escape_htmltag($langs->trans(
"NotEnoughPermissions")).
'">' . $langs->trans(
"UpdateLevelPrices") .
'</span></div>';
1647if ($action ==
'edit_vat' && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1650 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1651 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1652 print
'<input type="hidden" name="action" value="update_vat">';
1653 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
1657 print
'<table class="border centpercent">';
1660 print
'<tr><td>'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1668 print $form->buttonsSaveCancel();
1670 print
'<br></form><br>';
1673if (($action ==
'edit_price' || $action ==
'edit_level_price') &&
$object->getRights()->creer) {
1678 print
'<!-- Edit price -->'.
"\n";
1679 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1680 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1681 print
'<input type="hidden" name="action" value="update_price">';
1682 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
1686 print
'<div class="div-table-responsive-no-min">';
1687 print
'<table class="border centpercent">';
1690 print
'<tr><td class="titlefield">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1696 print $langs->trans(
'PriceBase');
1699 print $form->selectPriceBaseType(
$object->price_base_type,
"price_base_type");
1706 print
'<!-- Show price mode of dynamicprices editor -->'.
"\n";
1707 print
'<tr><td>'.$langs->trans(
"PriceMode").
'</td><td>';
1708 print img_picto(
'',
'dynamicprice',
'class="pictofixedwidth"');
1710 $price_expression_list = array(0 => $langs->trans(
"Numeric").
' <span class="opacitymedium">('.$langs->trans(
"NoDynamicPrice").
')</span>');
1711 foreach ($price_expression->list_price_expression() as $entry) {
1712 $price_expression_list[$entry->id] = $entry->title;
1714 $price_expression_preselection =
GETPOST(
'eid') ?
GETPOST(
'eid') : (
$object->fk_price_expression ?
$object->fk_price_expression :
'0');
1715 print $form->selectarray(
'eid', $price_expression_list, $price_expression_preselection);
1716 print
' <a id="expression_editor" class="classlink">'.$langs->trans(
"PriceExpressionEditor").
'</a>';
1722 <script
type=
"text/javascript">
1723 jQuery(document).ready(
function() {
1724 jQuery(
"#expression_editor").click(
function() {
1725 window.location =
"<?php echo DOL_URL_ROOT ?>/product/dynamic_price/editor.php?id=<?php echo $id ?>&tab=price&eid=" + $(
"#eid").val();
1727 jQuery(
"#eid").change(on_change);
1730 function on_change() {
1731 if ($(
"#eid").val() == 0) {
1732 jQuery(
"#price_numeric").show();
1734 jQuery(
"#price_numeric").hide();
1743 $product->fetch($id, $ref,
'',
'1');
1744 print
'<tr id="price_numeric"><td>';
1745 $text = $langs->trans(
'SellingPrice');
1746 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
1748 if (
$object->price_base_type ==
'TTC') {
1749 print
'<input name="price" size="10" value="'.price($product->price_ttc).
'">';
1751 print
'<input name="price" size="10" value="'.price($product->price).
'">';
1757 $text = $langs->trans(
'MinPrice');
1758 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
1760 if (
$object->price_base_type ==
'TTC') {
1761 print
'<input name="price_min" size="10" value="'.($object->price_min_ttc ?
price(
$object->price_min_ttc) :
'').
'">';
1763 print
'<input name="price_min" size="10" value="'.($object->price_min ?
price(
$object->price_min) :
'').
'">';
1766 print
' '.$langs->trans(
"MinimumRecommendedPrice",
price((
float) $maxpricesupplier, 0,
'', 1, -1, -1,
'auto')).
' '.img_warning().
'</td>';
1774 print $form->textwithpicto($langs->trans(
"PackagingForThisProduct"), $langs->trans(
"PackagingForThisProductDesc"));
1776 $packaging =
$object->packaging;
1777 print
'<input class="flat" name="packaging" size="5" value="' . ($packaging ?
price($packaging, 0,
'', 1, -1, 2) :
'').
'">';
1784 print $langs->trans(
'PriceLabel');
1786 print
'<input name="price_label" maxlength="255" class="minwidth300 maxwidth400onsmartphone" value="'.$object->price_label.
'">';
1790 $parameters = array();
1791 $reshook = $hookmanager->executeHooks(
'formObjectOptions', $parameters, $object, $action);
1798 print $form->buttonsSaveCancel();
1801 } elseif ($action ==
'edit_level_price' &&
$object->getRights()->creer) {
1802 print
'<!-- Edit price per level -->'.
"\n"; ?>
1805 var showHidePriceRules =
function () {
1806 var otherPrices = $(
'div.fiche form table tbody tr:not(:first)');
1807 var minPrice1 = $(
'div.fiche form input[name="price_min[1]"]');
1809 if (jQuery(
'input#usePriceRules').prop(
'checked')) {
1818 jQuery(document).ready(
function () {
1819 showHidePriceRules();
1821 jQuery(
'input#usePriceRules').click(showHidePriceRules);
1826 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1827 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1828 print
'<input type="hidden" name="action" value="update_level_price">';
1829 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
1834 print $langs->trans(
'UseMultipriceRules').
' <input type="checkbox" id="usePriceRules" name="usePriceRules" '.(
$object->price_autogen ?
'checked' :
'').
'><br><br>';
1837 print
'<div class="div-table-responsive-no-min">';
1838 print
'<table class="noborder">';
1839 print
'<thead><tr class="liste_titre">';
1841 print
'<td>'.$langs->trans(
"PriceLevel").
'</td>';
1844 print
'<td style="text-align: center">'.$langs->trans(
"DefaultTaxRate").
'</td>';
1849 print
'<td class="center">'.$langs->trans(
"SellingPrice").
'</td>';
1851 print
'<td class="center">'.$langs->trans(
"MinPrice").
'</td>';
1858 $extrafields->fetch_name_optionals_label(
"product_price");
1859 if ($extrafields->attributes[
"product_price"] && array_key_exists(
'label', $extrafields->attributes[
"product_price"])) {
1860 $extralabels = $extrafields->attributes[
"product_price"][
'label'];
1861 if (!empty($extralabels)) {
1862 foreach ($extralabels as $key => $value) {
1864 if (!empty($extrafields->attributes[
"product_price"][
'list'][$key]) && $extrafields->attributes[
"product_price"][
'list'][$key] != 3) {
1865 if (!empty($extrafields->attributes[
"product_price"][
'langfile'][$key])) {
1866 $langs->load($extrafields->attributes[
"product_price"][
'langfile'][$key]);
1868 if (!empty($extrafields->attributes[
"product_price"][
'help'][$key])) {
1869 $extratitle = $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_price"][
'help'][$key]));
1871 $extratitle = $langs->trans($value);
1873 print
'<td style="text-align: right">'.$extratitle.
'</td>';
1878 print
'</tr></thead>';
1882 $produit_multiprices_limit =
getDolGlobalInt(
'PRODUIT_MULTIPRICES_LIMIT');
1883 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
1884 print
'<tr class="oddeven">';
1886 $keyforlabel =
'PRODUIT_MULTIPRICES_LABEL'.$i;
1888 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
1894 print
'<input type="hidden" name="tva_tx['.$i.
']" value="'.(
$object->default_vat_code ?
$object->tva_tx.
' ('.
$object->default_vat_code.
')' :
$object->tva_tx).
'">';
1895 print
'<input type="hidden" name="tva_npr['.$i.
']" value="'.
$object->tva_npr.
'">';
1896 print
'<input type="hidden" name="localtax1_tx['.$i.
']" value="'.
$object->localtax1_tx.
'">';
1897 print
'<input type="hidden" name="localtax1_type['.$i.
']" value="'.
$object->localtax1_type.
'">';
1898 print
'<input type="hidden" name="localtax2_tx['.$i.
']" value="'.
$object->localtax2_tx.
'">';
1899 print
'<input type="hidden" name="localtax2_type['.$i.
']" value="'.
$object->localtax2_type.
'">';
1903 print
'<td style="text-align: center">';
1909 print
'<td style="text-align: center">';
1910 if (
$object->multiprices_base_type [$i] ==
'TTC') {
1911 print
'<input name="price['.$i.
']" size="10" value="'.
price(
$object->multiprices_ttc [$i]).
'">';
1913 print
'<input name="price['.$i.
']" size="10" value="'.
price(
$object->multiprices [$i]).
'">';
1915 print
' '.$form->selectPriceBaseType(
$object->multiprices_base_type [$i],
"multiprices_base_type[".$i.
"]");
1919 print
'<td style="text-align: center">';
1920 if (
$object->multiprices_base_type [$i] ==
'TTC') {
1921 print
'<input name="price_min['.$i.
']" size="10" value="'.
price(
$object->multiprices_min_ttc [$i]).
'">';
1923 print
'<input name="price_min['.$i.
']" size="10" value="'.
price(
$object->multiprices_min [$i]).
'">';
1926 print
'<td class="left">'.$langs->trans(
"MinimumRecommendedPrice",
price((
float) $maxpricesupplier, 0,
'', 1, -1, -1,
'auto')).
' '.img_warning().
'</td>';
1930 if (!empty($extralabels)) {
1931 require_once DOL_DOCUMENT_ROOT .
'/core/class/genericobject.class.php';
1934 $genericObject->table_element =
'product_price';
1935 $sql1 =
"SELECT rowid";
1936 $sql1 .=
" FROM ".$object->db->prefix().
"product_price";
1937 $sql1 .=
" WHERE entity IN (".getEntity(
'productprice').
")";
1938 $sql1 .=
" AND price_level=".((int) $i);
1939 $sql1 .=
" AND fk_product = ".((int)
$object->id);
1940 $sql1 .=
" ORDER BY date_price DESC, rowid DESC";
1941 $sql1 .=
" LIMIT 1";
1942 $resql1 =
$object->db->query($sql1);
1943 if ($resql1 && $lineid =
$object->db->fetch_object($resql1)) {
1944 $genericObject->id = $lineid->rowid;
1945 $genericObject->fetch_optionals();
1947 foreach ($extralabels as $key => $value) {
1948 if (!empty($extrafields->attributes[
"product_price"][
'list'][$key]) && ($extrafields->attributes[
"product_price"][
'list'][$key] == 1 || $extrafields->attributes[
"product_price"][
'list'][$key] == 3 || ($action ==
"edit_level_price" && $extrafields->attributes[
"product_price"][
'list'][$key] == 4))) {
1949 if (!empty($extrafields->attributes[
"product_price"][
'langfile'][$key])) {
1950 $langs->load($extrafields->attributes[
"product_price"][
'langfile'][$key]);
1954 print
'<td align="center">';
1955 print $extrafields->showInputField($key, $genericObject->array_options[
'options_' . $key],
'', (
string) $i,
'',
'', $genericObject,
'product_price');
1971 print $form->buttonsSaveCancel();
1982 $sortfield =
GETPOST(
'sortfield',
'aZ09comma');
1983 $sortorder =
GETPOST(
'sortorder',
'aZ09comma');
1985 if (empty($page) || $page == -1) {
1988 $offset = $limit * $page;
1989 $pageprev = $page - 1;
1990 $pagenext = $page + 1;
1992 $sortorder =
"ASC,ASC";
1995 $sortfield =
"soc.nom,t.date_begin";
1999 $filter = array(
't.fk_product' => (
string)
$object->id);
2001 if (!empty($search_soc)) {
2002 $filter[
'soc.nom'] = (string) $search_soc;
2005 if ($action ==
'add_customer_price') {
2007 $maxpricesupplier =
$object->min_recommended_price();
2009 print
'<!-- add_customer_price -->';
2012 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
2013 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2014 print
'<input type="hidden" name="action" value="add_customer_price_confirm">';
2015 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
2017 print
'<div class="tabBar tabBarWithBottom">';
2019 print
'<table class="border centpercent">';
2021 print
'<td class="fieldrequired">'.$langs->trans(
'ThirdParty').
'</td>';
2023 $filter =
'(s.client:IN:1,2,3)';
2024 print img_picto(
'',
'company').$form->select_company(
GETPOSTINT(
'socid'),
'socid', $filter,
'SelectThirdParty', 0, 0, array(), 0,
'minwidth300');
2029 print
'<tr><td>' . $langs->trans(
'RefCustomer') .
'</td>';
2030 print
'<td><input name="ref_customer" size="12"></td></tr>';
2034 print
'<tr><td>'.$langs->trans(
"AppliedPricesFrom").
'</td><td>';
2035 print $form->selectDate(!empty($date_begin) ? $date_begin :
dol_now(),
"date_begin", 0, 0, 1,
"date_begin");
2040 print
'<tr><td>'.$langs->trans(
"AppliedPricesTo").
'</td><td>';
2041 print $form->selectDate($date_end,
"date_end", 0, 0, 1,
"date_end");
2045 print
'<tr><td class="fieldrequired">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
2050 print
'<tr><td class="fieldrequired">';
2051 print $langs->trans(
'PriceBase');
2054 print $form->selectPriceBaseType(
$object->price_base_type,
"price_base_type");
2059 print
'<tr><td class="fieldrequired">';
2060 $text = $langs->trans(
'SellingPrice');
2061 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
2063 if (
$object->price_base_type ==
'TTC') {
2064 print
'<input name="price" size="10" value="'.price(
$object->price_ttc).
'">';
2066 print
'<input name="price" size="10" value="'.price(
$object->price).
'">';
2072 $text = $langs->trans(
'MinPrice');
2073 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
2074 if (
$object->price_base_type ==
'TTC') {
2075 print
'<td><input name="price_min" size="10" value="'.price(
$object->price_min_ttc).
'">';
2077 print
'<td><input name="price_min" size="10" value="'.price(
$object->price_min).
'">';
2080 print
'<td class="left">'.$langs->trans(
"MinimumRecommendedPrice",
price($maxpricesupplier, 0,
'', 1, -1, -1,
'auto')).
' '.img_warning().
'</td>';
2086 print $langs->trans(
'PriceLabel');
2088 print
'<input name="price_label" maxlength="255" class="minwidth300 maxwidth400onsmartphone" value="'.$object->price_label.
'">';
2094 print
'<tr><td>'.$langs->trans(
"Discount").
'</td><td>';
2095 print
'<input name="discount_percent" size="10" value="'.price($discount_percent).
'">';
2099 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2100 $extralabels = !empty($extrafields->attributes[
"product_customer_price"][
'label']) ? $extrafields->attributes[
"product_customer_price"][
'label'] :
'';
2101 $extrafield_values = $extrafields->getOptionalsFromPost(
"product_customer_price");
2102 if (!empty($extralabels)) {
2103 if (empty($prodcustprice->id)) {
2104 foreach ($extralabels as $key => $value) {
2105 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))) {
2106 if (!empty($extrafields->attributes[
"product_customer_price"][
'langfile'][$key])) {
2107 $langs->load($extrafields->attributes[
"product_customer_price"][
'langfile'][$key]);
2110 print
'<tr><td'.($extrafields->attributes[
"product_customer_price"][
'required'][$key] ?
' class="fieldrequired"' :
'').
'>';
2111 if (!empty($extrafields->attributes[
"product_customer_price"][
'help'][$key])) {
2112 print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_customer_price"][
'help'][$key]));
2114 print $langs->trans($value);
2116 print
'</td><td>'.$extrafields->showInputField($key,
GETPOSTISSET(
'options_'.$key) ? $extrafield_values[
'options_'.$key] :
'',
'',
'',
'',
'', 0,
'product_customer_price').
'</td></tr>';
2127 print
'<div class="center">';
2130 print
'<div class="marginbottomonly">';
2131 print
'<input type="checkbox" name="updatechildprice" id="updatechildprice" value="1"> ';
2132 print
'<label for="updatechildprice">'.$langs->trans(
'ForceUpdateChildPriceSoc').
'</label>';
2135 print $form->buttonsSaveCancel();
2138 } elseif ($action ==
'edit_customer_price') {
2140 $maxpricesupplier =
$object->min_recommended_price();
2142 print
'<!-- edit_customer_price -->';
2145 $result = $prodcustprice->fetch(
GETPOSTINT(
'lineid'));
2147 setEventMessages($prodcustprice->error, $prodcustprice->errors,
'errors');
2150 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
2151 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2152 print
'<input type="hidden" name="action" value="update_customer_price_confirm">';
2153 print
'<input type="hidden" name="lineid" value="'.$prodcustprice->id.
'">';
2155 print
'<table class="liste centpercent">';
2157 print
'<td class="titlefield fieldrequired">'.$langs->trans(
'ThirdParty').
'</td>';
2158 $staticsoc =
new Societe($db);
2159 $staticsoc->fetch($prodcustprice->fk_soc);
2160 print
"<td>".$staticsoc->getNomUrl(1).
"</td>";
2164 print
'<tr><td>' . $langs->trans(
'RefCustomer') .
'</td>';
2165 print
'<td><input name="ref_customer" size="12" value="' .
dol_escape_htmltag($prodcustprice->ref_customer) .
'"></td></tr>';
2168 print
'<tr><td>'.$langs->trans(
"AppliedPricesFrom").
'</td><td>';
2169 print $form->selectDate($prodcustprice->date_begin,
"date_begin", 0, 0, 1,
"date_begin");
2173 print
'<tr><td>'.$langs->trans(
"AppliedPricesTo").
'</td><td>';
2174 print $form->selectDate($prodcustprice->date_end,
"date_end", 0, 0, 1,
"date_end");
2178 print
'<tr><td class="fieldrequired">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
2179 print $form->load_tva(
"tva_tx", $prodcustprice->default_vat_code ? $prodcustprice->tva_tx.
' ('.$prodcustprice->default_vat_code.
')' : $prodcustprice->tva_tx,
$mysoc, null,
$object->id, $prodcustprice->recuperableonly,
$object->
type, false, 1);
2183 print
'<tr><td class="fieldrequired">';
2184 print $langs->trans(
'PriceBase');
2187 print $form->selectPriceBaseType($prodcustprice->price_base_type,
"price_base_type");
2192 print
'<tr><td class="fieldrequired">';
2193 $text = $langs->trans(
'SellingPrice');
2194 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
2196 if ($prodcustprice->price_base_type ==
'TTC') {
2197 print
'<input name="price" size="10" value="'.price($prodcustprice->price_ttc).
'">';
2199 print
'<input name="price" size="10" value="'.price($prodcustprice->price).
'">';
2205 $text = $langs->trans(
'MinPrice');
2206 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
2208 if ($prodcustprice->price_base_type ==
'TTC') {
2209 print
'<input name="price_min" size="10" value="'.price($prodcustprice->price_min_ttc).
'">';
2211 print
'<input name="price_min" size="10" value="'.price($prodcustprice->price_min).
'">';
2215 print
'<td class="left">'.$langs->trans(
"MinimumRecommendedPrice",
price($maxpricesupplier, 0,
'', 1, -1, -1,
'auto')).
' '.img_warning().
'</td>';
2221 print $langs->trans(
'PriceLabel');
2223 print
'<input name="price_label" maxlength="255" class="minwidth300 maxwidth400onsmartphone" value="'.$prodcustprice->price_label.
'">';
2228 print
'<tr><td>'.$langs->trans(
"Discount").
'</td><td>';
2229 print
'<input name="discount_percent" size="10" value="'.price($prodcustprice->discount_percent).
'">';
2233 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2234 $extralabels = !empty($extrafields->attributes[
"product_customer_price"][
'label']) ? $extrafields->attributes[
"product_customer_price"][
'label'] :
'';
2235 $extrafield_values = $extrafields->getOptionalsFromPost(
"product_customer_price");
2236 if (!empty($extralabels)) {
2238 foreach ($extralabels as $key => $value) {
2239 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_customer_price" && $extrafields->attributes[
"product_customer_price"][
'list'][$key] == 4))) {
2240 if (!empty($extrafields->attributes[
"product_customer_price"][
'langfile'][$key])) {
2241 $langs->load($extrafields->attributes[
"product_customer_price"][
'langfile'][$key]);
2244 print
'<tr><td'.($extrafields->attributes[
"product_customer_price"][
'required'][$key] ?
' class="fieldrequired"' :
'').
'>';
2245 if (!empty($extrafields->attributes[
"product_customer_price"][
'help'][$key])) {
2246 print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_customer_price"][
'help'][$key]));
2248 print $langs->trans($value);
2250 print
'</td><td>'.$extrafields->showInputField($key,
GETPOSTISSET(
'options_'.$key) ? $extrafield_values[
'options_'.$key] :
'',
'',
'',
'',
'', 0,
'product_customer_price').
'</td></tr>';
2255 $sql .=
" fk_object";
2256 foreach ($extralabels as $key => $value) {
2257 $sql .=
", ".$db->sanitize($key);
2259 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product_customer_price_extrafields";
2260 $sql .=
" WHERE fk_object = ".((int) $prodcustprice->id);
2261 $resql = $db->query($sql);
2263 $obj = $db->fetch_object($resql);
2264 foreach ($extralabels as $key => $value) {
2265 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_customer_price" && $extrafields->attributes[
"product_customer_price"][
'list'][$key] == 4))) {
2266 if (!empty($extrafields->attributes[
"product_customer_price"][
'langfile'][$key])) {
2267 $langs->load($extrafields->attributes[
"product_customer_price"][
'langfile'][$key]);
2270 print
'<tr><td'.($extrafields->attributes[
"product_customer_price"][
'required'][$key] ?
' class="fieldrequired"' :
'').
'>';
2271 if (!empty($extrafields->attributes[
"product_customer_price"][
'help'][$key])) {
2272 print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_customer_price"][
'help'][$key]));
2274 print $langs->trans($value);
2276 print
'</td><td>'.$extrafields->showInputField($key,
GETPOSTISSET(
'options_'.$key) ? $extrafield_values[
'options_'.$key] : $obj->{$key},
'',
'',
'',
'', 0,
'product_customer_price');
2288 print
'<div class="center">';
2289 print
'<div class="marginbottomonly">';
2290 print
'<input type="checkbox" name="updatechildprice" id="updatechildprice" value="1"> ';
2291 print
'<label for="updatechildprice">'.$langs->trans(
'ForceUpdateChildPriceSoc').
'</label>';
2294 print $form->buttonsSaveCancel();
2296 print
'<br></form>';
2297 } elseif ($action ==
'showlog_customer_price') {
2299 print
'<!-- list of all log of prices per customer -->'.
"\n";
2301 $sortfield =
't.datec';
2302 $filter = array(
't.fk_product' => (
string)
$object->id,
't.fk_soc' => (
string)
GETPOSTINT(
'socid'));
2305 $nbtotalofrecords =
'';
2307 $nbtotalofrecords = $prodcustprice->fetchAllLog($sortorder, $sortfield,
$conf->liste_limit, $offset, $filter);
2310 $result = $prodcustprice->fetchAllLog($sortorder, $sortfield,
$conf->liste_limit, $offset, $filter);
2312 setEventMessages($prodcustprice->error, $prodcustprice->errors,
'errors');
2315 $option =
'&socid='.GETPOSTINT(
'socid').
'&id='.
$object->id;
2317 $staticsoc =
new Societe($db);
2320 $title = $langs->trans(
'PriceByCustomerLog');
2321 $title .=
' - '.$staticsoc->getNomUrl(1);
2323 $backbutton =
'<a class="justalink" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'">'.$langs->trans(
"GoBack").
'</a>';
2326 print_barre_liste($title, $page, $_SERVER[
'PHP_SELF'], $option, $sortfield, $sortorder, $backbutton, count($prodcustprice->lines), $nbtotalofrecords,
'title_accountancy.png');
2328 if (count($prodcustprice->lines) > 0) {
2329 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
2330 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2331 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
2333 print
'<div class="div-table-responsive-no-min">';
2334 print
'<table class="liste centpercent">';
2336 print
'<tr class="liste_titre">';
2337 print
'<td>'.$langs->trans(
"ThirdParty").
'</td>';
2338 print
'<td>'.$langs->trans(
'RefCustomer').
'</td>';
2339 print
'<td>'.$langs->trans(
"AppliedPricesFrom").
'</td>';
2340 print
'<td>'.$langs->trans(
"AppliedPricesTo").
'</td>';
2341 print
'<td class="center">'.$langs->trans(
"PriceBase").
'</td>';
2342 print
'<td class="right">'.$langs->trans(
"DefaultTaxRate").
'</td>';
2343 print
'<td class="right">'.$langs->trans(
"HT").
'</td>';
2344 print
'<td class="right">'.$langs->trans(
"TTC").
'</td>';
2345 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2346 print
'<td class="right">'.$langs->trans(
"INCT").
'</td>';
2348 print
'<td class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"HT").
'</td>';
2349 print
'<td class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"TTC").
'</td>';
2350 print
'<td class="right">'.$langs->trans(
"PriceLabel").
'</td>';
2351 print
'<td class="right">'.$langs->trans(
"Discount").
'</td>';
2352 print
'<td class="right">'.$langs->trans(
"ChangedBy").
'</td>';
2353 print
'<td>'.$langs->trans(
"DateCreation").
'</td>';
2356 foreach ($prodcustprice->lines as $line) {
2358 $staticsoc =
new Societe($db);
2359 $staticsoc->fetch($line->fk_soc);
2361 $tva_tx = $line->default_vat_code ? $line->tva_tx.
' ('.$line->default_vat_code.
')' : $line->tva_tx;
2364 if ($line->price_base_type ==
'HT') {
2367 $pu = $line->price_ttc;
2371 $localtaxarray =
getLocalTaxesFromRate($line->tva_tx.($line->default_vat_code ?
' ('.$line->default_vat_code.
')' :
''), 0, $staticsoc,
$mysoc);
2373 $resultarray =
calcul_price_total(1, $pu, 0, (
float) $line->tva_tx, 1, 1, 0, $line->price_base_type, $line->recuperableonly,
$object->type,
$mysoc, $localtaxarray);
2375 $total_ht = $resultarray[0];
2376 $total_vat = $resultarray[1];
2377 $total_localtax1 = $resultarray[9];
2378 $total_localtax2 = $resultarray[10];
2379 $total_ttc = $resultarray[2];
2381 print
'<tr class="oddeven">';
2383 print
'<td class="tdoverflowmax125">'.$staticsoc->getNomUrl(1).
"</td>";
2384 print
'<td>'.$line->ref_customer.
'</td>';
2385 print
"<td>".dol_print_date($line->date_begin,
"day",
'tzuserrel').
"</td>";
2386 print
"<td>".dol_print_date($line->date_end,
"day",
'tzuserrel').
"</td>";
2387 print
'<td class="center">'.$langs->trans($line->price_base_type).
"</td>";
2388 print
'<td class="right nowraponall">';
2390 $positiverates =
'';
2392 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->tva_tx);
2395 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->localtax1_tx);
2398 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->localtax2_tx);
2400 if (empty($positiverates)) {
2401 $positiverates =
'0';
2404 echo
vatrate($positiverates.($line->default_vat_code ?
' ('.$line->default_vat_code.
')' :
''), true, (!empty($line->tva_npr) ? $line->tva_npr : $line->recuperableonly));
2408 print
'<td class="right"><span class="amount">'.price($line->price).
"</span></td>";
2410 print
'<td class="right"><span class="amount">'.price($line->price_ttc).
"</span></td>";
2411 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2412 print
'<td class="right">'.price($resultarray[2]).
'</td>';
2415 print
'<td class="right">'.price($line->price_min).
'</td>';
2416 print
'<td class="right">'.price($line->price_min_ttc).
'</td>';
2417 print
'<td class="right">'.dolPrintHTML($line->price_label).
'</td>';
2418 print
'<td class="right">'.price($line->discount_percent).
'</td>';
2421 print
'<td class="tdoverflowmax125">';
2423 if ($line->fk_user > 0) {
2424 $userstatic =
new User($db);
2425 $userstatic->fetch($line->fk_user);
2426 print $userstatic->getNomUrl(1,
'', 0, 0, 24, 0,
'login');
2430 print
"<td>".dol_print_date($line->datec,
"dayhour",
'tzuserrel').
"</td>";
2436 print $langs->trans(
'None');
2438 } elseif ($action !=
'showlog_default_price' && $action !=
'edit_price' && $action !=
'edit_level_price') {
2440 print
'<!-- list of all prices per customer -->'.
"\n";
2443 $nbtotalofrecords =
'';
2445 $nbtotalofrecords = $prodcustprice->fetchAll($sortorder, $sortfield, 0, 0, $filter);
2448 $result = $prodcustprice->fetchAll($sortorder, $sortfield,
$conf->liste_limit, $offset, $filter);
2450 setEventMessages($prodcustprice->error, $prodcustprice->errors,
'errors');
2453 $option =
'&search_soc='.$search_soc.
'&id='.
$object->id;
2456 print_barre_liste($langs->trans(
'PriceByCustomer'), $page, $_SERVER [
'PHP_SELF'], $option, $sortfield, $sortorder,
'', count($prodcustprice->lines), $nbtotalofrecords,
'title_accountancy.png');
2458 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
2459 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2460 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
2462 print
'<!-- List of prices per customer -->'.
"\n";
2463 print
'<div class="div-table-responsive-no-min">'.
"\n";
2464 print
'<table class="liste centpercent">'.
"\n";
2466 if (count($prodcustprice->lines) > 0 || $search_soc) {
2467 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2468 $custom_price_extralabels = !empty($extrafields->attributes[
"product_customer_price"][
'label']) ? $extrafields->attributes[
"product_customer_price"][
'label'] :
'';
2474 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2477 if (!empty($custom_price_extralabels) && is_array($custom_price_extralabels)) {
2478 $colspan += count($custom_price_extralabels);
2481 print
'<tr class="liste_titre">';
2482 print
'<td class="liste_titre"><input type="text" class="flat maxwidth125" name="search_soc" value="'.$search_soc.
'"></td>';
2483 print
'<td class="liste_titre" colspan="'.$colspan.
'"> </td>';
2485 print
'<td class="liste_titre maxwidthsearch">';
2486 $searchpicto = $form->showFilterAndCheckAddButtons(0);
2492 print
'<tr class="liste_titre">';
2493 print
'<td>'.$langs->trans(
"ThirdParty").
'</td>';
2494 print
'<td>'.$langs->trans(
'RefCustomer').
'</td>';
2495 print
'<td>'.$langs->trans(
"AppliedPricesFrom").
'</td>';
2496 print
'<td>'.$langs->trans(
"AppliedPricesTo").
'</td>';
2497 print
'<td class="center">'.$langs->trans(
"PriceBase").
'</td>';
2498 print
'<td class="right">'.$langs->trans(
"DefaultTaxRate").
'</td>';
2499 print
'<td class="right">'.$langs->trans(
"HT").
'</td>';
2500 print
'<td class="right">'.$langs->trans(
"TTC").
'</td>';
2501 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2502 print
'<td class="right">'.$langs->trans(
"INCT").
'</td>';
2504 print
'<td class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"HT").
'</td>';
2505 print
'<td class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"TTC").
'</td>';
2506 print
'<td class="right">'.$langs->trans(
"PriceLabel").
'</td>';
2507 print
'<td class="right">'.$langs->trans(
"Discount").
'</td>';
2509 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2510 if ($extrafields->attributes[
"product_customer_price"] && array_key_exists(
'label', $extrafields->attributes[
"product_customer_price"])) {
2511 $extralabels = $extrafields->attributes[
"product_customer_price"][
'label'];
2512 if (!empty($extralabels)) {
2513 foreach ($extralabels as $key => $value) {
2515 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && $extrafields->attributes[
"product_customer_price"][
'list'][$key] != 3) {
2516 if (!empty($extrafields->attributes[
"product_customer_price"][
'langfile'][$key])) {
2517 $langs->load($extrafields->attributes[
"product_customer_price"][
'langfile'][$key]);
2519 if (!empty($extrafields->attributes[
"product_customer_price"][
'help'][$key])) {
2520 $extratitle = $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_customer_price"][
'help'][$key]));
2522 $extratitle = $langs->trans($value);
2524 print
'<td style="text-align: right">'.$extratitle.
'</td>';
2529 print
'<td>'.$langs->trans(
"ChangedBy").
'</td>';
2534 if (
$object->price_base_type ==
'HT') {
2543 $resultarray =
calcul_price_total(1, $pu, 0,
$object->tva_tx, 1, 1, 0,
$object->price_base_type, 0,
$object->type,
$mysoc, $localtaxarray);
2545 $total_ht = $resultarray[0];
2546 $total_vat = $resultarray[1];
2547 $total_localtax1 = $resultarray[9];
2548 $total_localtax2 = $resultarray[10];
2549 $total_ttc = $resultarray[2];
2552 print
'<!-- PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES -->'.
"\n";
2553 print
'<tr class="oddeven">';
2554 print
'<td colspan="4">' . $langs->trans(
'Default') .
'</td>';
2556 print
'<td class="center">'.$langs->trans(
$object->price_base_type).
"</td>";
2559 print
'<td class="right nowraponall">';
2561 $positiverates =
'';
2566 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax1_tx);
2569 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax2_tx);
2571 if (empty($positiverates)) {
2572 $positiverates =
'0';
2574 echo
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr);
2578 print
'<td class="right"><span class="amount">'.price(
$object->price).
"</span></td>";
2580 print
'<td class="right"><span class="amount">'.price(
$object->price_ttc).
"</span></td>";
2581 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2583 print
'<td class="right"><span class="amount">'.price($resultarray[2]).
'</span></td>';
2586 print
'<td class="right">'.price(
$object->price_min).
'</td>';
2587 print
'<td class="right">'.price(
$object->price_min_ttc).
'</td>';
2588 print
'<td class="right">'.dolPrintHTML(
$object->price_label).
'</td>';
2589 print
'<td class="right"></td>';
2590 print
'<td class="right"></td>';
2591 if (!empty($extralabels)) {
2592 foreach ($extralabels as $key) {
2594 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && $extrafields->attributes[
"product_customer_price"][
'list'][$key] != 3) {
2595 print
'<td class="right"></td>';
2599 if ($user->hasRight(
'produit',
'supprimer') || $user->hasRight(
'service',
'supprimer')) {
2600 print
'<td class="nowraponall">';
2601 print
'<a class="marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?action=showlog_default_price&token='.
newToken().
'&id='.
$object->id.
'">';
2602 print img_info($langs->trans(
'PriceByCustomerLog'));
2605 print
'<a class="marginleftonly marginrightonly editfielda" href="'.$_SERVER[
"PHP_SELF"].
'?action=edit_price&token='.
newToken().
'&id='.
$object->id.
'">';
2606 print img_edit(
'default', 0,
'style="vertical-align: middle;"');
2613 if (count($prodcustprice->lines) > 0) {
2614 foreach ($prodcustprice->lines as $line) {
2616 $staticsoc =
new Societe($db);
2617 $staticsoc->fetch($line->fk_soc);
2619 $tva_tx = $line->default_vat_code ? $line->tva_tx.
' ('.$line->default_vat_code.
')' : $line->tva_tx;
2622 if ($line->price_base_type ==
'HT') {
2625 $pu = $line->price_ttc;
2629 $localtaxarray =
getLocalTaxesFromRate($line->tva_tx.($line->default_vat_code ?
' ('.$line->default_vat_code.
')' :
''), 0, $staticsoc,
$mysoc);
2631 $resultarray =
calcul_price_total(1, $pu, 0, (
float) $line->tva_tx, 1, 1, 0, $line->price_base_type, $line->recuperableonly,
$object->type,
$mysoc, $localtaxarray);
2633 $total_ht = $resultarray[0];
2634 $total_vat = $resultarray[1];
2635 $total_localtax1 = $resultarray[9];
2636 $total_localtax2 = $resultarray[10];
2637 $total_ttc = $resultarray[2];
2639 print
'<tr class="oddeven">';
2641 print
'<td class="tdoverflowmax125">'.$staticsoc->getNomUrl(1).
"</td>";
2642 print
'<td>'.dolPrintHTML($line->ref_customer).
'</td>';
2643 print
"<td>".dol_print_date($line->date_begin,
"day",
'tzuserrel').
"</td>";
2644 print
"<td>".dol_print_date($line->date_end,
"day",
'tzuserrel').
"</td>";
2645 print
'<td class="center">'.$langs->trans($line->price_base_type).
"</td>";
2647 print
'<td class="right nowraponall">';
2649 $positiverates =
'';
2651 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->tva_tx);
2654 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->localtax1_tx);
2657 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->localtax2_tx);
2659 if (empty($positiverates)) {
2660 $positiverates =
'0';
2663 echo
vatrate($positiverates.($line->default_vat_code ?
' ('.$line->default_vat_code.
')' :
''), true, (!empty($line->tva_npr) ? $line->tva_npr : $line->recuperableonly));
2667 print
'<td class="right"><span class="amount">'.price($line->price).
"</span></td>";
2669 print
'<td class="right"><span class="amount">'.price($line->price_ttc).
"</span></td>";
2670 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2672 print
'<td class="right"><span class="amount">'.price($resultarray[2]).
'</span></td>';
2675 print
'<td class="right">'.price($line->price_min).
'</td>';
2676 print
'<td class="right">'.price($line->price_min_ttc).
'</td>';
2677 print
'<td class="right">'.dolPrintHTMLForAttribute($line->price_label).
'</td>';
2678 print
'<td class="right">'.price($line->discount_percent).
'</td>';
2681 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2682 $extralabels = $extrafields->attributes[
"product_customer_price"][
'label'] ?? array();
2683 if (!empty($extralabels)) {
2685 $sql .=
" fk_object";
2686 foreach ($extralabels as $key => $value) {
2687 $sql .=
", ".$db->sanitize($key);
2689 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product_customer_price_extrafields";
2690 $sql .=
" WHERE fk_object = ".((int) $line->id);
2691 $resql = $db->query($sql);
2694 $obj = ($db->num_rows($resql) == 1) ? $db->fetch_object($resql) :
null;
2695 foreach ($extralabels as $key => $value) {
2696 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && $extrafields->attributes[
"product_customer_price"][
'list'][$key] != 3) {
2698 if (!empty($extrafields->attributes[
"product_customer_price"][
'computed'][$key])) {
2699 $objectoffield = $line;
2700 $extravalue =
dol_eval((
string) $extrafields->attributes[
"product_customer_price"][
'computed'][$key], 1, 1,
'2');
2701 print
'<td align="right">'.$extrafields->showOutputField($key, $extravalue,
'',
'product_customer_price').
"</td>";
2703 print
'<td align="right">'.$extrafields->showOutputField($key, $obj->{$key},
'',
'product_customer_price').
"</td>";
2714 print
'<td class="tdoverflowmax125">';
2715 if ($line->fk_user > 0) {
2716 $userstatic =
new User($db);
2717 $userstatic->fetch($line->fk_user);
2719 print $userstatic->getNomUrl(-1,
'', 0, 0, 24, 0,
'login');
2725 print
'<td class="right nowraponall">';
2726 if ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer')) {
2727 print
'<a href="'.$_SERVER[
"PHP_SELF"].
'?action=showlog_customer_price&token='.
newToken().
'&id='.
$object->id.
'&socid='.$line->fk_soc.
'">';
2728 print img_info($langs->trans(
'PriceByCustomerLog'));
2731 print
'<a class="marginleftonly editfielda" href="'.$_SERVER[
"PHP_SELF"].
'?action=edit_customer_price&token='.
newToken().
'&id='.
$object->id.
'&lineid='.$line->id.
'">';
2732 print img_edit(
'default', 0,
'style="vertical-align: middle;"');
2736 if ($user->hasRight(
'produit',
'supprimer') || $user->hasRight(
'service',
'supprimer')) {
2737 print
'<a class="marginleftonly" href="'.$_SERVER[
"PHP_SELF"].
'?action=ask_remove_customer_price&token='.
newToken().
'&id='.
$object->id.
'&lineid='.$line->id.
'">';
2738 print img_delete(
'default',
'style="vertical-align: middle;"');
2756if ((!
getDolGlobalString(
'PRODUIT_CUSTOMER_PRICES') || $action ==
'showlog_default_price') && !in_array($action, array(
'edit_price',
'edit_level_price',
'edit_vat'))) {
2757 $sql =
"SELECT p.rowid, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.default_vat_code, p.recuperableonly, p.localtax1_tx, p.localtax1_type, p.localtax2_tx, p.localtax2_type,";
2758 $sql .=
" p.price_level, p.price_min, p.price_min_ttc,p.price_by_qty,";
2759 $sql .=
" p.date_price as dp, p.fk_price_expression, u.rowid as user_id, u.login";
2760 $sql .=
" ,p.price_label";
2761 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product_price as p,";
2762 $sql .=
" ".MAIN_DB_PREFIX.
"user as u";
2763 $sql .=
" WHERE fk_product = ".((int)
$object->id);
2764 $sql .=
" AND p.entity IN (".getEntity(
'productprice').
")";
2765 $sql .=
" AND p.fk_user_author = u.rowid";
2767 $sql .=
" AND p.price_level = ".((int) $soc->price_level);
2769 $sql .=
" ORDER BY p.date_price DESC, p.rowid DESC, p.price_level ASC";
2773 $result = $db->query($sql);
2775 print
'<div class="divlogofpreviouscustomerprice">';
2777 $num = $db->num_rows($result);
2786 $ret =
$object->updatePrice((
$object->multiprices_base_type[1] ==
'TTC' ?
$object->multiprices_ttc[1] :
$object->multiprices[1]),
$object->multiprices_base_type[1], $user, (empty(
$object->multiprices_tva_tx[1]) ? 0 :
$object->multiprices_tva_tx[1]), (
$object->multiprices_base_type[1] ==
'TTC' ?
$object->multiprices_min_ttc[1] :
$object->multiprices_min[1]), 1, 0, 0, 0, array(),
$object->default_vat_code);
2788 $ret =
$object->updatePrice((
$object->price_base_type ==
'TTC' ?
$object->price_ttc :
$object->
price),
$object->price_base_type, $user,
$object->tva_tx, (
$object->price_base_type ==
'TTC' ?
$object->price_min_ttc :
$object->price_min), 0,
$object->tva_npr, 0, 0, array(),
$object->default_vat_code);
2794 $result = $db->query($sql);
2795 $num = $db->num_rows($result);
2802 $backbutton =
'<a class="justalink" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'">'.$langs->trans(
"GoBack").
'</a>';
2806 print_barre_liste($langs->trans(
"DefaultPriceLog"), 0, $_SERVER[
"PHP_SELF"],
'',
'',
'', $backbutton, 0, $num,
'title_accountancy.png');
2809 print_barre_liste($langs->trans(
"PriceByCustomerLog"), 0, $_SERVER[
"PHP_SELF"],
'',
'',
'',
'', 0, $num,
'title_accountancy.png');
2812 print
'<!-- List of log prices -->'.
"\n";
2813 print
'<div class="div-table-responsive">'.
"\n";
2814 print
'<table class="liste centpercent noborder">'.
"\n";
2816 print
'<tr class="liste_titre">';
2817 print
'<th>'.$langs->trans(
"AppliedPricesFrom").
'</tg>';
2820 print
'<th class="center">'.$langs->trans(
"PriceLevel").
'</th>';
2823 print
'<th class="center">'.$langs->trans(
"Type").
'</th>';
2826 print
'<th class="center">'.$langs->trans(
"PriceBase").
'</th>';
2828 print
'<th class="right">'.$langs->trans(
"DefaultTaxRate").
'</th>';
2830 print
'<th class="right">'.$langs->trans(
"HT").
'</th>';
2831 print
'<th class="right">'.$langs->trans(
"TTC").
'</th>';
2832 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2833 print
'<th class="right">'.$langs->trans(
"INCT").
'</th>';
2836 print
'<th class="right">'.$langs->trans(
"PriceExpressionSelected").
'</th>';
2838 print
'<th class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"HT").
'</th>';
2839 print
'<th class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"TTC").
'</th>';
2840 print
'<th class="right">'.$langs->trans(
"Label").
'</th>';
2841 print
'<th>'.$langs->trans(
"ChangedBy").
'</th>';
2842 if ($user->hasRight(
'produit',
'supprimer')) {
2843 print
'<th class="right"> </th>';
2847 $notfirstlineforlevel = array();
2851 $objp = $db->fetch_object($result);
2853 print
'<tr class="oddeven">';
2855 print
"<td>".dol_print_date($db->jdate($objp->dp),
"dayhour",
'tzuserrel').
"</td>";
2859 print
'<td class="center">'.$objp->price_level.
"</td>";
2863 $type = ($objp->price_by_qty == 1) ?
'PriceByQuantity' :
'Standard';
2864 print
'<td class="center">'.$langs->trans($type).
"</td>";
2867 print
'<td class="center">';
2868 if (empty($objp->price_by_qty)) {
2869 print $langs->trans($objp->price_base_type);
2874 print
'<td class="right">';
2876 if (empty($objp->price_by_qty)) {
2877 $positiverates =
'';
2879 $positiverates .= ($positiverates ?
'/' :
'').
price2num($objp->tva_tx);
2882 $positiverates .= ($positiverates ?
'/' :
'').
price2num($objp->localtax1_tx);
2885 $positiverates .= ($positiverates ?
'/' :
'').
price2num($objp->localtax2_tx);
2887 if (empty($positiverates)) {
2888 $positiverates =
'0';
2890 echo
vatrate($positiverates.($objp->default_vat_code ?
' ('.$objp->default_vat_code.
')' :
''), true, !empty($objp->tva_npr) ? $objp->tva_npr : 0);
2903 if ($objp->price_base_type ==
'HT') {
2906 $pu = $objp->price_ttc;
2912 $resultarray =
calcul_price_total(1, $pu, 0, $objp->tva_tx, 1, 1, 0, $objp->price_base_type, $objp->recuperableonly,
$object->type,
$mysoc, $localtaxarray);
2914 $total_ht = $resultarray[0];
2915 $total_vat = $resultarray[1];
2916 $total_localtax1 = $resultarray[9];
2917 $total_localtax2 = $resultarray[10];
2918 $total_ttc = $resultarray[2];
2921 if (!empty($objp->fk_price_expression) && !empty(
$conf->dynamicprices->enabled)) {
2923 $res = $price_expression->fetch($objp->fk_price_expression);
2924 $title = $price_expression->title;
2925 print
'<td class="right"></td>';
2926 print
'<td class="right"></td>';
2927 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2928 print
'<td class="right"></td>';
2930 print
'<td class="right">'.$title.
"</td>";
2933 print
'<td class="right">';
2934 if (empty($objp->price_by_qty)) {
2935 print
'<span class="amount">'.price($objp->price).
'</span>';
2939 print
'<td class="right">';
2940 if (empty($objp->price_by_qty)) {
2941 $price_ttc = $objp->price_ttc;
2942 print
'<span class="amount">'.price($price_ttc).
'<span>';
2945 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2946 print
'<td class="right">';
2947 print $resultarray[2];
2951 print
'<td class="right"></td>';
2956 print
'<td class="right">';
2957 if (empty($objp->price_by_qty)) {
2958 print
price($objp->price_min);
2963 print
'<td class="right">';
2964 if (empty($objp->price_by_qty)) {
2965 $price_min_ttc = $objp->price_min_ttc;
2966 print
price($price_min_ttc);
2972 print dolPrintHTML($objp->price_label);
2976 print
'<td class="tdoverflowmax125">';
2977 if ($objp->user_id > 0) {
2979 $userstatic =
new User($db);
2980 $userstatic->fetch($objp->user_id);
2981 print $userstatic->getNomUrl(-1,
'', 0, 0, 24, 0,
'login');
2986 if ($user->hasRight(
'produit',
'supprimer')) {
2989 if (empty($notfirstlineforlevel[$objp->price_level])) {
2990 $notfirstlineforlevel[$objp->price_level] = 1;
2998 print
'<td class="right">';
2999 if ($candelete || ($db->jdate($objp->dp) >=
dol_now())) {
3000 print
'<a href="'.$_SERVER[
"PHP_SELF"].
'?action=delete&token='.
newToken().
'&id='.
$object->id.
'&lineid='.$objp->rowid.
'">';
3021 dol_print_error($db);
$id
Support class for third parties, contacts, members, users or resources.
if(! $sortfield) if(! $sortorder) $object
$propal type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
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.
Class of a generic business object.
Class for accessing price expression table.
Class to parse product price expressions.
File of class to manage predefined price products or services by customer.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
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 '.
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.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
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.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
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_localtax($vatrate, $local, $thirdparty_buyer=null, $thirdparty_seller=null, $vatnpr=0)
Return localtax rate for a particular VAT rate, when selling a product with vat $vatrate,...
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.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $notused, $price_base_type, $info_bits, $type, $seller=null, $localtaxes_array=[], $progress=100, $multicurrency_tx=1, $pu_devise=0, $multicurrency_code='')
Calculate totals (net, vat, ...) of a line.
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.