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'));
72$action =
GETPOST(
'action',
'aZ09');
73$cancel =
GETPOST(
'cancel',
'alpha');
76$search_soc =
GETPOST(
'search_soc');
79$fieldvalue = (!empty($id) ?
$id : (!empty($ref) ? $ref :
''));
80$fieldtype = (!empty($ref) ?
'ref' :
'rowid');
82 $socid = $user->socid;
86if ($id > 0 || !empty($ref)) {
94 $conf->global->PRODUIT_MULTIPRICES_LIMIT = 5;
98$hookmanager->initHooks(array(
'productpricecard',
'globalcard'));
101 if (
$object->type == $object::TYPE_PRODUCT) {
104 if (
$object->type == $object::TYPE_SERVICE) {
108 restrictedArea($user,
'produit|service', $fieldvalue,
'product&product',
'',
'', $fieldtype);
111$maxpricesupplier = 0;
114 $permissiontoadd =
$object->getRights()->creer;
116 $permissiontoadd = ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'));
128$parameters = array(
'id' => $id,
'ref' => $ref);
129$reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
134if (empty($reshook)) {
135 if (
GETPOST(
'button_removefilter_x',
'alpha') ||
GETPOST(
'button_removefilter.x',
'alpha') ||
GETPOST(
'button_removefilter',
'alpha')) {
139 if ($action ==
'setlabelsellingprice' && $user->admin) {
140 require_once DOL_DOCUMENT_ROOT.
'/core/lib/admin.lib.php';
141 $keyforlabel =
'PRODUIT_MULTIPRICES_LABEL'.GETPOST(
'pricelevel');
146 if (($action ==
'update_vat') && !$cancel && $permissiontoadd) {
147 $tva_tx_txt =
GETPOST(
'tva_tx',
'alpha');
149 $price_label =
GETPOST(
'price_label',
'alpha');
152 $tva_tx = $tva_tx_txt;
155 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
156 $vatratecode = $reg[1];
157 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
160 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
161 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
164 $localtax1_type =
'0';
165 $localtax2_type =
'0';
168 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
170 $vatratecode = $reg[1];
172 $sql =
"SELECT t.rowid, t.type_vat, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
173 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
174 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
175 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
176 $sql .=
" AND t.code = '".$db->escape($vatratecode).
"'";
177 $sql .=
" AND t.type_vat IN (0, 1)";
178 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
179 $resql = $db->query($sql);
181 $obj = $db->fetch_object($resql);
183 $npr = $obj->recuperableonly;
184 $localtax1 = $obj->localtax1;
185 $localtax2 = $obj->localtax2;
186 $localtax1_type = $obj->localtax1_type;
187 $localtax2_type = $obj->localtax2_type;
192 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
193 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
194 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
195 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
196 $sql .=
" AND t.code = ''";
197 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
198 $resql = $db->query($sql);
200 $obj = $db->fetch_object($resql);
202 $npr = $obj->recuperableonly;
203 $localtax1 = $obj->localtax1;
204 $localtax2 = $obj->localtax2;
205 $localtax1_type = $obj->localtax1_type;
206 $localtax2_type = $obj->localtax2_type;
211 $object->default_vat_code = $vatratecode;
214 $object->localtax1_tx = $localtax1;
215 $object->localtax2_tx = $localtax2;
216 $object->localtax1_type = $localtax1_type;
217 $object->localtax2_type = $localtax2_type;
218 $object->price_label = $price_label;
230 $produit_multiprices_limit =
getDolGlobalInt(
'PRODUIT_MULTIPRICES_LIMIT');
231 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
233 if (
$object->multiprices_base_type[$i] ==
'HT') {
234 $oldprice =
$object->multiprices[$i];
235 $oldminprice =
$object->multiprices_min[$i];
237 $oldprice =
$object->multiprices_ttc[$i];
238 $oldminprice =
$object->multiprices_min_ttc[$i];
240 $oldpricebasetype =
$object->multiprices_base_type[$i];
241 $oldnpr =
$object->multiprices_recuperableonly[$i];
244 $localtaxarray = array();
246 $ret =
$object->updatePrice($oldprice, $oldpricebasetype, $user, (
float) $tva_tx, $oldminprice, $level, $oldnpr, 0, 0, $localtaxarray, $vatratecode, $price_label);
255 if (
$object->price_base_type ==
'HT') {
257 $oldminprice =
$object->price_min;
259 $oldprice =
$object->price_ttc;
260 $oldminprice =
$object->price_min_ttc;
262 $oldpricebasetype =
$object->price_base_type;
266 $localtaxarray = array();
268 $ret =
$object->updatePrice($oldprice, $oldpricebasetype, $user, (
float) $tva_tx, $oldminprice, $level, $oldnpr, 0, 0, $localtaxarray, $vatratecode, $price_label);
286 $maxpricesupplier = 0;
288 if (($action ==
'update_price' || $action ==
'update_level_price') && !$cancel && $permissiontoadd) {
290 $pricestoupdate = array();
295 $maxpricesupplier =
$object->min_recommended_price();
301 $object->fk_price_expression = empty($eid) ? 0 : $eid;
303 if (
$object->fk_price_expression != 0) {
305 require_once DOL_DOCUMENT_ROOT.
'/product/dynamic_price/class/price_parser.class.php';
308 if ($priceparser->parseProduct($object) < 0) {
317 || ($action ==
'update_level_price' &&
getDolGlobalString(
'PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')))) {
318 $newprice =
GETPOST(
'price',
'array');
319 $newprice_min =
GETPOST(
'price_min',
'array');
320 $newpricebase =
GETPOST(
'multiprices_base_type',
'array');
321 $newvattx =
GETPOST(
'tva_tx',
'array');
322 $newvatnpr =
GETPOST(
'tva_npr',
'array');
323 $newlocaltax1_tx =
GETPOST(
'localtax1_tx',
'array');
324 $newlocaltax1_type =
GETPOST(
'localtax1_type',
'array');
325 $newlocaltax2_tx =
GETPOST(
'localtax2_tx',
'array');
326 $newlocaltax2_type =
GETPOST(
'localtax2_type',
'array');
329 $object->price_autogen = (int) (
GETPOST(
'usePriceRules') ==
'on');
331 $produit_multiprices_limit =
getDolGlobalInt(
'PRODUIT_MULTIPRICES_LIMIT');
332 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
333 if (!isset($newprice[$i])) {
337 $tva_tx_txt = $newvattx[$i];
339 $tva_tx = $tva_tx_txt;
342 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
343 $vat_src_code = $reg[1];
344 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
346 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
348 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
349 $localtax1 = $newlocaltax1_tx[$i];
350 $localtax1_type = $newlocaltax1_type[$i];
351 $localtax2 = $newlocaltax2_tx[$i];
352 $localtax2_type = $newlocaltax2_type[$i];
353 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
355 $vatratecode = $reg[1];
357 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
358 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
359 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
360 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
361 $sql .=
" AND t.code ='".$db->escape($vatratecode).
"'";
362 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
363 $resql = $db->query($sql);
365 $obj = $db->fetch_object($resql);
367 $npr = $obj->recuperableonly;
368 $localtax1 = $obj->localtax1;
369 $localtax2 = $obj->localtax2;
370 $localtax1_type = $obj->localtax1_type;
371 $localtax2_type = $obj->localtax2_type;
375 if (in_array(
$mysoc->country_code, array(
'ES'))) {
382 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
383 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
384 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
385 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
386 $sql .=
" AND t.code = ''";
387 $resql = $db->query($sql);
389 $obj = $db->fetch_object($resql);
391 $npr = $obj->recuperableonly;
392 $localtax1 = $obj->localtax1;
393 $localtax2 = $obj->localtax2;
394 $localtax1_type = $obj->localtax1_type;
395 $localtax2_type = $obj->localtax2_type;
400 $pricestoupdate[$i] = array(
402 'price' =>
price2num($newprice[$i],
'', 2),
403 'price_min' =>
price2num($newprice_min[$i],
'', 2),
404 'price_base_type' => $newpricebase[$i],
405 'default_vat_code' => $vatratecode,
408 'localtaxes_array' => array(
'0' => $localtax1_type,
'1' => $localtax1,
'2' => $localtax2_type,
'3' => $localtax2)
419 $newpricebase =
GETPOST(
'price_base_type',
'alpha');
420 $tva_tx_txt =
GETPOST(
'tva_tx',
'alpha');
421 $price_label =
GETPOST(
'price_label',
'alpha');
423 $tva_tx = $tva_tx_txt;
426 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
427 $vat_src_code = $reg[1];
428 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
430 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
432 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
435 $localtax1_type =
'0';
436 $localtax2_type =
'0';
438 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
440 $vatratecode = $reg[1];
442 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
443 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
444 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
445 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
446 $sql .=
" AND t.code ='".$db->escape($vatratecode).
"'";
447 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
448 $resql = $db->query($sql);
450 $obj = $db->fetch_object($resql);
452 $npr = $obj->recuperableonly;
453 $localtax1 = $obj->localtax1;
454 $localtax2 = $obj->localtax2;
455 $localtax1_type = $obj->localtax1_type;
456 $localtax2_type = $obj->localtax2_type;
460 if (in_array(
$mysoc->country_code, array(
'ES'))) {
467 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
468 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
469 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
470 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
471 $sql .=
" AND t.code = ''";
472 $resql = $db->query($sql);
474 $obj = $db->fetch_object($resql);
476 $npr = $obj->recuperableonly;
477 $localtax1 = $obj->localtax1;
478 $localtax2 = $obj->localtax2;
479 $localtax1_type = $obj->localtax1_type;
480 $localtax2_type = $obj->localtax2_type;
485 $pricestoupdate[0] = array(
486 'price' => $newprice,
487 'price_label' => $price_label,
488 'price_min' => $newprice_min,
489 'price_base_type' => $newpricebase,
490 'default_vat_code' => $vatratecode,
493 'localtaxes_array' => array(
'0' => $localtax1_type,
'1' => $localtax1,
'2' => $localtax2_type,
'3' => $localtax2)
502 $object->packaging = (float) $packaging;
505 foreach ($pricestoupdate as $key => $val) {
506 $newprice = $val[
'price'];
508 if ($val[
'price'] < $val[
'price_min'] && !empty(
$object->fk_price_expression)) {
509 $newprice = $val[
'price_min'];
513 $newprice_min =
price2num($val[
'price_min'],
'MU');
516 if (
getDolGlobalString(
'PRODUCT_MINIMUM_RECOMMENDED_PRICE') && $newprice_min < $maxpricesupplier) {
517 setEventMessages($langs->trans(
"MinimumPriceLimit",
price($maxpricesupplier, 0,
'', 1, - 1, - 1,
'auto')),
null,
'errors');
522 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) {
523 $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']);
535 $price_extralabels = $extrafields->fetch_name_optionals_label(
"product_price");
537 $sql =
"SELECT rowid";
538 $sql .=
" FROM ".$object->db->prefix().
"product_price";
539 $sql .=
" WHERE entity IN (".getEntity(
'productprice').
")";
540 $sql .=
" AND price_level=".((int) $key);
541 $sql .=
" AND fk_product = ".((int)
$object->id);
542 $sql .=
" ORDER BY date_price DESC, rowid DESC";
544 $resql =
$object->db->query($sql);
546 $lineid =
$object->db->fetch_object($resql);
549 if (!empty($lineid->rowid)) {
550 foreach ($price_extralabels as $code => $label) {
551 $code_array =
GETPOST($code,
'array');
552 $object->array_options[
'options_'.$code] = $code_array[$key];
556 $object->table_element =
'product_price';
557 $result =
$object->insertExtraFields();
560 $object->table_element =
'product';
579 $action =
'edit_price';
585 if ($action ==
'delete' && $user->hasRight(
'produit',
'supprimer')) {
593 if ($action ==
'activate_price_by_qty' && $permissiontoadd) {
605 if ($action ==
'disable_price_by_qty' && $permissiontoadd) {
617 if ($action ==
'edit_price_by_qty') {
622 if ($action ==
'update_price_by_qty' && $permissiontoadd) {
632 if (empty($quantity)) {
634 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentities(
"Qty")),
null,
'errors');
636 if (empty($newprice)) {
638 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentities(
"Price")),
null,
'errors');
640 if (!$error && !($rowid > 0)) {
642 $sql =
"SELECT pp.rowid FROM ".MAIN_DB_PREFIX.
"product_price as pp";
643 $sql .=
" WHERE pp.rowid = ".((int) $priceid).
" AND pp.fk_product = ".((int)
$object->id);
644 $resql = $db->query($sql);
645 if (!$resql || !$db->num_rows($resql)) {
652 if (
$object->price_base_type ==
'TTC') {
657 $unitPrice =
price2num((
float) $price / (
float) $quantity,
'MU');
661 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"product_price_by_qty SET";
662 $sql .=
" price=".((float) $price).
",";
663 $sql .=
" unitprice=".((float) $unitPrice).
",";
664 $sql .=
" quantity=".((float) $quantity).
",";
665 $sql .=
" remise_percent=".((float) $remise_percent).
",";
666 $sql .=
" remise=".((float) $remise);
667 $sql .=
" WHERE rowid = ".((int) $rowid);
668 $sql .=
" AND fk_product_price IN (SELECT pp.rowid FROM ".MAIN_DB_PREFIX.
"product_price as pp WHERE pp.fk_product = ".((int)
$object->id).
")";
670 $result = $db->query($sql);
675 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"product_price_by_qty (fk_product_price,price,unitprice,quantity,remise_percent,remise) values (";
676 $sql .= ((int) $priceid).
','.((float) $price).
','.((float) $unitPrice).
','.((float) $quantity).
','.((float) $remise_percent).
','.((float) $remise).
')';
678 $result = $db->query($sql);
680 if ($db->lasterrno() ==
'DB_ERROR_RECORD_ALREADY_EXISTS') {
690 if ($action ==
'delete_price_by_qty' && $permissiontoadd) {
692 if (!empty($rowid)) {
693 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"product_price_by_qty";
694 $sql .=
" WHERE rowid = ".((int) $rowid);
695 $sql .=
" AND fk_product_price IN (SELECT pp.rowid FROM ".MAIN_DB_PREFIX.
"product_price as pp WHERE pp.fk_product = ".((int)
$object->id).
")";
697 $result = $db->query($sql);
699 setEventMessages((
'delete_price_by_qty'.$langs->transnoentities(
'MissingIds')),
null,
'errors');
703 if ($action ==
'delete_all_price_by_qty' && $permissiontoadd) {
705 if (!empty($priceid)) {
706 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"product_price_by_qty";
707 $sql .=
" WHERE fk_product_price = ".((int) $priceid);
708 $sql .=
" AND fk_product_price IN (SELECT pp.rowid FROM ".MAIN_DB_PREFIX.
"product_price as pp WHERE pp.fk_product = ".((int)
$object->id).
")";
710 $result = $db->query($sql);
712 setEventMessages((
'delete_price_by_qty'.$langs->transnoentities(
'MissingIds')),
null,
'errors');
721 if ($action ==
'add_customer_price_confirm' && !$cancel && $prodcustprice !==
null && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
722 $maxpricesupplier =
$object->min_recommended_price();
724 $update_child_soc =
GETPOSTINT(
'updatechildprice');
728 $prodcustprice->ref_customer =
GETPOST(
'ref_customer',
'alpha');
729 $prodcustprice->fk_product =
$object->id;
732 $prodcustprice->price_base_type =
GETPOST(
"price_base_type",
'alpha');
733 $prodcustprice->price_label =
GETPOST(
"price_label",
'alpha');
738 $extralabels = $extrafields->fetch_name_optionals_label(
"product_customer_price");
739 $extrafield_values = $extrafields->getOptionalsFromPost(
"product_customer_price");
741 $tva_tx_txt =
GETPOST(
"tva_tx",
'alpha');
743 $tva_tx = $tva_tx_txt;
745 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
746 $vat_src_code = $reg[1];
747 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
749 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
751 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
754 $localtax1_type =
'0';
755 $localtax2_type =
'0';
757 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
759 $vatratecode = $reg[1];
761 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
762 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
763 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
764 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
765 $sql .=
" AND t.code ='".$db->escape($vatratecode).
"'";
766 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
767 $resql = $db->query($sql);
769 $obj = $db->fetch_object($resql);
771 $npr = $obj->recuperableonly;
772 $localtax1 = $obj->localtax1;
773 $localtax2 = $obj->localtax2;
774 $localtax1_type = $obj->localtax1_type;
775 $localtax2_type = $obj->localtax2_type;
779 if (in_array(
$mysoc->country_code, array(
'ES'))) {
786 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
787 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
788 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
789 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
790 $sql .=
" AND t.code = ''";
791 $resql = $db->query($sql);
793 $obj = $db->fetch_object($resql);
795 $npr = $obj->recuperableonly;
796 $localtax1 = $obj->localtax1;
797 $localtax2 = $obj->localtax2;
798 $localtax1_type = $obj->localtax1_type;
799 $localtax2_type = $obj->localtax2_type;
804 $prodcustprice->default_vat_code = $vatratecode;
805 $prodcustprice->tva_tx = $tva_tx;
806 $prodcustprice->recuperableonly = $npr;
807 $prodcustprice->localtax1_tx = $localtax1;
808 $prodcustprice->localtax2_tx = $localtax2;
809 $prodcustprice->localtax1_type = $localtax1_type;
810 $prodcustprice->localtax2_type = $localtax2_type;
812 if (!($prodcustprice->fk_soc > 0)) {
813 $langs->load(
"errors");
814 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"ThirdParty")),
null,
'errors');
816 $action =
'add_customer_price';
818 if (
getDolGlobalString(
'PRODUCT_MINIMUM_RECOMMENDED_PRICE') && $prodcustprice->price_min < (
float) $maxpricesupplier) {
819 $langs->load(
"errors");
820 setEventMessages($langs->trans(
"MinimumPriceLimit",
price((
float) $maxpricesupplier, 0,
'', 1, -1, -1,
'auto')),
null,
'errors');
822 $action =
'add_customer_price';
827 $result = $prodcustprice->create($user, 0, $update_child_soc);
829 if (!empty($extrafield_values) && is_array($extrafield_values)) {
831 $res = $productcustomerprice->fetch($prodcustprice->id);
833 foreach ($extrafield_values as $key => $value) {
834 $productcustomerprice->array_options[$key] = $value;
836 $result2 = $productcustomerprice->insertExtraFields();
838 $prodcustprice->error = $productcustomerprice->error;
839 $prodcustprice->errors = $productcustomerprice->errors;
848 $action =
'add_customer_price';
857 if (in_array($action, [
'confirm_remove_customer_price',
'update_customer_price_confirm']) && $prodcustprice !==
null) {
859 if ((
int) $prodcustprice->fk_product !== (
int)
$object->id) {
865 if ($action ==
'confirm_remove_customer_price' && $prodcustprice !==
null && ($user->hasRight(
'produit',
'supprimer') || $user->hasRight(
'service',
'supprimer'))) {
867 $update_child_soc =
GETPOSTINT(
'updatechildprice');
870 $result = $prodcustprice->delete($user, 0, $update_child_soc);
873 $db->query(
"DELETE FROM ".MAIN_DB_PREFIX.
"product_customer_price_extrafields WHERE fk_object = ".((
int) $prodcustprice->id));
888 if ($action ==
'update_customer_price_confirm' && !$cancel && $prodcustprice !==
null && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
889 $maxpricesupplier =
$object->min_recommended_price();
891 $update_child_soc =
GETPOSTINT(
'updatechildprice');
896 $prodcustprice->ref_customer =
GETPOST(
'ref_customer',
'alpha');
899 $prodcustprice->price_base_type =
GETPOST(
"price_base_type",
'alpha');
900 $prodcustprice->price_label =
GETPOST(
"price_label",
'alpha');
905 $extralabels = $extrafields->fetch_name_optionals_label(
"product_customer_price");
906 $extrafield_values = $extrafields->getOptionalsFromPost(
"product_customer_price");
908 $tva_tx_txt =
GETPOST(
"tva_tx");
910 $tva_tx = $tva_tx_txt;
912 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
913 $vat_src_code = $reg[1];
914 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
916 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
918 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
921 $localtax1_type =
'0';
922 $localtax2_type =
'0';
924 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
926 $vatratecode = $reg[1];
928 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
929 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
930 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
931 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
932 $sql .=
" AND t.code ='".$db->escape($vatratecode).
"'";
933 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
934 $resql = $db->query($sql);
936 $obj = $db->fetch_object($resql);
938 $npr = $obj->recuperableonly;
939 $localtax1 = $obj->localtax1;
940 $localtax2 = $obj->localtax2;
941 $localtax1_type = $obj->localtax1_type;
942 $localtax2_type = $obj->localtax2_type;
946 if (in_array(
$mysoc->country_code, array(
'ES'))) {
953 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
954 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
955 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
956 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
957 $sql .=
" AND t.code = ''";
958 $resql = $db->query($sql);
960 $obj = $db->fetch_object($resql);
962 $npr = $obj->recuperableonly;
963 $localtax1 = $obj->localtax1;
964 $localtax2 = $obj->localtax2;
965 $localtax1_type = $obj->localtax1_type;
966 $localtax2_type = $obj->localtax2_type;
971 $prodcustprice->default_vat_code = $vatratecode;
972 $prodcustprice->tva_tx = $tva_tx;
973 $prodcustprice->recuperableonly = $npr;
974 $prodcustprice->localtax1_tx = $localtax1;
975 $prodcustprice->localtax2_tx = $localtax2;
976 $prodcustprice->localtax1_type = $localtax1_type;
977 $prodcustprice->localtax2_type = $localtax2_type;
979 if ($prodcustprice->price_min < $maxpricesupplier &&
getDolGlobalString(
'PRODUCT_MINIMUM_RECOMMENDED_PRICE')) {
980 setEventMessages($langs->trans(
"MinimumPriceLimit",
price($maxpricesupplier, 0,
'', 1, -1, -1,
'auto')),
null,
'errors');
982 $action =
'update_customer_price';
986 $result = $prodcustprice->update($user, 0, $update_child_soc);
988 if (!empty($extrafield_values) && is_array($extrafield_values)) {
990 $res = $productcustomerprice->fetch($prodcustprice->id);
992 foreach ($extrafield_values as $key => $value) {
993 $productcustomerprice->array_options[$key] = $value;
995 $result2 = $productcustomerprice->insertExtraFields();
997 $prodcustprice->error = $productcustomerprice->error;
998 $prodcustprice->errors = $productcustomerprice->errors;
1007 $action =
'update_customer_price';
1021$form =
new Form($db);
1023if (!empty($id) || !empty($ref)) {
1028$title = $langs->trans(
'ProductServiceCard');
1032 $title = $langs->trans(
'Product').
" ".$shortlabel.
" - ".$langs->trans(
'SellingPrices');
1033 $helpurl =
'EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos';
1036 $title = $langs->trans(
'Service').
" ".$shortlabel.
" - ".$langs->trans(
'SellingPrices');
1037 $helpurl =
'EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios';
1040llxHeader(
'', $title, $helpurl,
'', 0, 0,
'',
'',
'',
'classforhorizontalscrolloftabs mod-product page-price');
1042if ($action ==
'ask_remove_customer_price' && ($user->hasRight(
'produit',
'supprimer') || $user->hasRight(
'service',
'supprimer'))) {
1043 $formquestion = array(
1044 array(
'type' =>
'checkbox',
'name' =>
'updatechildprice',
'label' => $langs->trans(
'ForceDeleteChildPriceSoc'),
'value' => 0),
1046 $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);
1051$titre = $langs->trans(
"CardProduct".
$object->type);
1056$linkback =
'<a href="'.DOL_URL_ROOT.
'/product/list.php?restore_lastsearch_values=1&type='.
$object->type.
'">'.$langs->trans(
"BackToList").
'</a>';
1057$object->next_prev_filter =
"(te.fk_product_type:=:".((int)
$object->type).
")";
1060if ($user->socid && !in_array(
'product', explode(
',',
getDolGlobalString(
'MAIN_MODULES_FOR_EXTERNAL')))) {
1064dol_banner_tab($object,
'ref', $linkback, $shownav,
'ref');
1067print
'<div class="fichecenter">';
1069print
'<div class="underbanner clearboth"></div>';
1070print
'<table class="border tableforfield centpercent">';
1077 if (!empty($socid)) {
1080 $soc->fetch($socid);
1084 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
1085 print
'<tr><td class="">';
1086 print (!
getDolGlobalString(
'PRODUCT_DENY_CHANGE_PRODUCT_TYPE')) ? $form->editfieldkey(
"Type",
'fk_product_type', (
string)
$object->type, $object, 0, $typeformat) : $langs->trans(
'Type');
1088 print $form->editfieldval(
"Type",
'fk_product_type',
$object->type, $object, 0, $typeformat);
1093 print
'<tr><td class="titlefieldcreate">';
1094 print $langs->trans(
"SellingPrice");
1096 print
'<td colspan="2">';
1097 if (
$object->multiprices_base_type[$soc->price_level] ==
'TTC') {
1098 print
'<span class="amount">'.price(
$object->multiprices_ttc[$soc->price_level]).
'</span>';
1100 print
'<span class="amount">'.price(
$object->multiprices[$soc->price_level]).
'</span>';
1102 if (
$object->multiprices_base_type[$soc->price_level]) {
1103 print
' '.$langs->trans(
$object->multiprices_base_type[$soc->price_level]);
1105 print
' '.$langs->trans(
$object->price_base_type);
1110 print
'<tr><td>'.$langs->trans(
"MinPrice").
'</td><td colspan="2">';
1111 if (
$object->multiprices_base_type[$soc->price_level] ==
'TTC') {
1112 print
price(
$object->multiprices_min_ttc[$soc->price_level]).
' '.$langs->trans(
$object->multiprices_base_type[$soc->price_level]);
1114 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]);
1120 print
'<tr><td>'.$langs->trans(
"DefaultTaxRate").
'</td><td colspan="2">';
1122 $positiverates =
'';
1124 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->multiprices_tva_tx[$soc->price_level]);
1127 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->multiprices_localtax1_tx[$soc->price_level]);
1130 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->multiprices_localtax2_tx[$soc->price_level]);
1132 if (empty($positiverates)) {
1133 $positiverates =
'0';
1135 echo
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr);
1140 print
'<tr><td>'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1142 $positiverates =
'';
1147 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax1_tx);
1150 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax2_tx);
1152 if (empty($positiverates)) {
1153 $positiverates =
'0';
1155 echo
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr);
1163 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
1164 print
'<tr><td class="">';
1165 print (!
getDolGlobalString(
'PRODUCT_DENY_CHANGE_PRODUCT_TYPE')) ? $form->editfieldkey(
"Type",
'fk_product_type', (
string)
$object->type, $object, 0, $typeformat) : $langs->trans(
'Type');
1167 print $form->editfieldval(
"Type",
'fk_product_type',
$object->type, $object, 0, $typeformat);
1172 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"DefaultTaxRate").
'</td>';
1173 print
'<td colspan="2">'.vatrate(
$object->multiprices_tva_tx[1],
true).
'</td>';
1178 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
1179 print
'<tr><td class="">';
1180 print (!
getDolGlobalString(
'PRODUCT_DENY_CHANGE_PRODUCT_TYPE')) ? $form->editfieldkey(
"Type",
'fk_product_type', (
string)
$object->type, $object, 0, $typeformat) : $langs->trans(
'Type');
1182 print $form->editfieldval(
"Type",
'fk_product_type',
$object->type, $object, 0, $typeformat);
1187 print
'<!-- Default VAT Rate -->';
1188 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1191 $positiverates =
'';
1193 $positiverates .= ($positiverates ?
'<span class="opacitymedium">/</span>' :
'').
price2num(
$object->tva_tx);
1196 $positiverates .= ($positiverates ?
'<span class="opacitymedium">/</span>' :
'').
price2num(
$object->localtax1_tx);
1199 $positiverates .= ($positiverates ?
'<span class="opacitymedium">/</span>' :
'').
price2num(
$object->localtax2_tx);
1201 if (empty($positiverates)) {
1202 $positiverates =
'0';
1205 print
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr, 1);
1218 print
'<table class="liste centpercent">';
1219 print
'<tr class="liste_titre"><td>';
1220 print $langs->trans(
"PriceLevel");
1222 print
' <a class="editfielda" href="'.$_SERVER[
"PHP_SELF"].
'?action=editlabelsellingprice&token='.
newToken().
'&pricelevel='.$i.
'&id='.
$object->id.
'">'.
img_edit($langs->trans(
'EditSellingPriceLabel'), 0).
'</a>';
1225 print
'<td style="text-align: right">'.$langs->trans(
"SellingPrice").
'</td>';
1226 print
'<td style="text-align: right">'.$langs->trans(
"MinPrice").
'</td>';
1228 $extrafields->fetch_name_optionals_label(
"product_price");
1229 if ($extrafields->attributes[
"product_price"] && array_key_exists(
'label', $extrafields->attributes[
"product_price"])) {
1230 $extralabels = $extrafields->attributes[
"product_price"][
'label'];
1231 if (!empty($extralabels)) {
1232 foreach ($extralabels as $key => $value) {
1234 if (!empty($extrafields->attributes[
"product_price"][
'list'][$key]) && $extrafields->attributes[
"product_price"][
'list'][$key] != 3) {
1235 if (!empty($extrafields->attributes[
"product_price"][
'langfile'][$key])) {
1236 $langs->load($extrafields->attributes[
"product_price"][
'langfile'][$key]);
1238 if (!empty($extrafields->attributes[
"product_price"][
'help'][$key])) {
1239 $extratitle = $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_price"][
'help'][$key]));
1241 $extratitle = $langs->trans($value);
1243 $field =
'ef.' . $key;
1244 print
'<td style="text-align: right">'.$extratitle.
'</td>';
1251 $produit_multiprices_limit =
getDolGlobalInt(
'PRODUIT_MULTIPRICES_LIMIT');
1252 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
1253 print
'<tr class="oddeven">';
1257 $keyforlabel =
'PRODUIT_MULTIPRICES_LABEL'.$i;
1258 if (preg_match(
'/editlabelsellingprice/', $action)) {
1259 print
'<form method="post" action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'">';
1260 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1261 print
'<input type="hidden" name="action" value="setlabelsellingprice">';
1262 print
'<input type="hidden" name="pricelevel" value="'.$i.
'">';
1263 print $langs->trans(
"SellingPrice").
' '.$i.
' - ';
1264 print
'<input class="maxwidthonsmartphone" type="text" name="labelsellingprice" value="' .
getDolGlobalString($keyforlabel).
'">';
1265 print
' <input type="submit" class="button smallpaddingimp" value="'.$langs->trans(
"Modify").
'">';
1268 print $langs->trans(
"SellingPrice").
' '.$i;
1275 if (
$object->multiprices_base_type [$i] ==
'TTC') {
1276 print
'<td class="right"><span class="amount">'.price(
$object->multiprices_ttc[$i]);
1278 print
'<td class="right"><span class="amount">'.price(
$object->multiprices[$i]);
1281 if (
$object->multiprices_base_type[$i]) {
1282 print
' '.$langs->trans(
$object->multiprices_base_type [$i]).
'</span></td>';
1284 print
' '.$langs->trans(
$object->price_base_type).
'</span></td>';
1288 print
'<td style="text-align: right">';
1289 if (empty(
$object->multiprices_base_type[$i])) {
1290 $object->multiprices_base_type[$i] =
"HT";
1292 if (
$object->multiprices_base_type[$i] ==
'TTC') {
1293 print
price(
$object->multiprices_min_ttc[$i]).
' '.$langs->trans(
$object->multiprices_base_type[$i]);
1295 print
price(
$object->multiprices_min[$i]).
' '.$langs->trans(
$object->multiprices_base_type[$i]);
1298 if (!empty($extralabels)) {
1299 $sql1 =
"SELECT rowid";
1300 $sql1 .=
" FROM ".$object->db->prefix().
"product_price";
1301 $sql1 .=
" WHERE entity IN (".getEntity(
'productprice').
")";
1302 $sql1 .=
" AND price_level=".((int) $i);
1303 $sql1 .=
" AND fk_product = ".((int)
$object->id);
1304 $sql1 .=
" ORDER BY date_price DESC, rowid DESC";
1305 $sql1 .=
" LIMIT 1";
1306 $resql1 =
$object->db->query($sql1);
1308 $lineid =
$object->db->fetch_object($resql1);
1311 $sql2 .=
" fk_object";
1312 foreach ($extralabels as $key => $value) {
1313 $sql2 .=
", ".$db->sanitize($key);
1315 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"product_price_extrafields";
1316 $sql2 .=
" WHERE fk_object = ".((int) $lineid->rowid);
1317 $resql2 = $db->query($sql2);
1319 if ($db->num_rows($resql2) != 1) {
1320 foreach ($extralabels as $key => $value) {
1321 if (!empty($extrafields->attributes[
"product_price"][
'list'][$key]) && $extrafields->attributes[
"product_price"][
'list'][$key] != 3) {
1322 print
'<td align="right"></td>';
1326 $obj = $db->fetch_object($resql2);
1327 foreach ($extralabels as $key => $value) {
1328 if (!empty($extrafields->attributes[
"product_price"][
'list'][$key]) && $extrafields->attributes[
"product_price"][
'list'][$key] != 3) {
1329 print
'<td align="right">'.$extrafields->showOutputField($key, $obj->{$key},
'',
'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"].
'">';
1382 print
'<a class="marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=delete_price_by_qty&token='.
newToken().
'&rowid='.$prices[
"rowid"].
'">';
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"].
'">';
1565 print
'<a class="marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=delete_price_by_qty&token='.
newToken().
'&rowid='.$prices[
"rowid"].
'">';
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>';
1670 print $form->buttonsSaveCancel();
1672 print
'<br></form><br>';
1675if (($action ==
'edit_price' || $action ==
'edit_level_price') &&
$object->getRights()->creer) {
1680 print
'<!-- Edit price -->'.
"\n";
1681 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1682 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1683 print
'<input type="hidden" name="action" value="update_price">';
1684 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
1688 print
'<div class="div-table-responsive-no-min">';
1689 print
'<table class="border centpercent">';
1692 print
'<tr><td class="titlefield">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1698 print $langs->trans(
'PriceBase');
1701 print $form->selectPriceBaseType(
$object->price_base_type,
"price_base_type");
1708 print
'<!-- Show price mode of dynamicprices editor -->'.
"\n";
1709 print
'<tr><td>'.$langs->trans(
"PriceMode").
'</td><td>';
1710 print
img_picto(
'',
'dynamicprice',
'class="pictofixedwidth"');
1712 $price_expression_list = array(0 => $langs->trans(
"Numeric").
' <span class="opacitymedium">('.$langs->trans(
"NoDynamicPrice").
')</span>');
1713 foreach ($price_expression->list_price_expression() as $entry) {
1714 $price_expression_list[$entry->id] = $entry->title;
1716 $price_expression_preselection =
GETPOST(
'eid') ?
GETPOST(
'eid') : (
$object->fk_price_expression ?
$object->fk_price_expression :
'0');
1717 print $form->selectarray(
'eid', $price_expression_list, $price_expression_preselection);
1718 print
' <a id="expression_editor" class="classlink">'.$langs->trans(
"PriceExpressionEditor").
'</a>';
1724 <script
type=
"text/javascript">
1725 jQuery(document).ready(
function() {
1726 jQuery(
"#expression_editor").click(
function() {
1727 window.location =
"<?php echo DOL_URL_ROOT ?>/product/dynamic_price/editor.php?id=<?php echo $id ?>&tab=price&eid=" + $(
"#eid").val();
1729 jQuery(
"#eid").change(on_change);
1732 function on_change() {
1733 if ($(
"#eid").val() == 0) {
1734 jQuery(
"#price_numeric").show();
1736 jQuery(
"#price_numeric").hide();
1745 $product->fetch($id, $ref,
'',
'1');
1746 print
'<tr id="price_numeric"><td>';
1747 $text = $langs->trans(
'SellingPrice');
1748 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
1750 if (
$object->price_base_type ==
'TTC') {
1751 print
'<input name="price" size="10" value="'.price($product->price_ttc).
'">';
1753 print
'<input name="price" size="10" value="'.price($product->price).
'">';
1759 $text = $langs->trans(
'MinPrice');
1760 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
1762 if (
$object->price_base_type ==
'TTC') {
1763 print
'<input name="price_min" size="10" value="'.($object->price_min_ttc ?
price(
$object->price_min_ttc) :
'').
'">';
1765 print
'<input name="price_min" size="10" value="'.($object->price_min ?
price(
$object->price_min) :
'').
'">';
1768 print
' '.$langs->trans(
"MinimumRecommendedPrice",
price((
float) $maxpricesupplier, 0,
'', 1, -1, -1,
'auto')).
' '.
img_warning().
'</td>';
1776 print $form->textwithpicto($langs->trans(
"PackagingForThisProduct"), $langs->trans(
"PackagingForThisProductDesc"));
1778 $packaging =
$object->packaging;
1779 print
'<input class="flat" name="packaging" size="5" value="' . ($packaging ?
price($packaging, 0,
'', 1, -1, 2) :
'').
'">';
1786 print $langs->trans(
'PriceLabel');
1788 print
'<input name="price_label" maxlength="255" class="minwidth300 maxwidth400onsmartphone" value="'.$object->price_label.
'">';
1792 $parameters = array();
1793 $reshook = $hookmanager->executeHooks(
'formObjectOptions', $parameters, $object, $action);
1800 print $form->buttonsSaveCancel();
1803 } elseif ($action ==
'edit_level_price' &&
$object->getRights()->creer) {
1804 print
'<!-- Edit price per level -->'.
"\n"; ?>
1807 var showHidePriceRules =
function () {
1808 var otherPrices = $(
'div.fiche form table tbody tr:not(:first)');
1809 var minPrice1 = $(
'div.fiche form input[name="price_min[1]"]');
1811 if (jQuery(
'input#usePriceRules').prop(
'checked')) {
1820 jQuery(document).ready(
function () {
1821 showHidePriceRules();
1823 jQuery(
'input#usePriceRules').click(showHidePriceRules);
1828 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1829 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1830 print
'<input type="hidden" name="action" value="update_level_price">';
1831 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
1836 print $langs->trans(
'UseMultipriceRules').
' <input type="checkbox" id="usePriceRules" name="usePriceRules" '.(
$object->price_autogen ?
'checked' :
'').
'><br><br>';
1839 print
'<div class="div-table-responsive-no-min">';
1840 print
'<table class="noborder">';
1841 print
'<thead><tr class="liste_titre">';
1843 print
'<td>'.$langs->trans(
"PriceLevel").
'</td>';
1846 print
'<td style="text-align: center">'.$langs->trans(
"DefaultTaxRate").
'</td>';
1851 print
'<td class="center">'.$langs->trans(
"SellingPrice").
'</td>';
1853 print
'<td class="center">'.$langs->trans(
"MinPrice").
'</td>';
1860 $extrafields->fetch_name_optionals_label(
"product_price");
1861 if ($extrafields->attributes[
"product_price"] && array_key_exists(
'label', $extrafields->attributes[
"product_price"])) {
1862 $extralabels = $extrafields->attributes[
"product_price"][
'label'];
1863 if (!empty($extralabels)) {
1864 foreach ($extralabels as $key => $value) {
1866 if (!empty($extrafields->attributes[
"product_price"][
'list'][$key]) && $extrafields->attributes[
"product_price"][
'list'][$key] != 3) {
1867 if (!empty($extrafields->attributes[
"product_price"][
'langfile'][$key])) {
1868 $langs->load($extrafields->attributes[
"product_price"][
'langfile'][$key]);
1870 if (!empty($extrafields->attributes[
"product_price"][
'help'][$key])) {
1871 $extratitle = $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_price"][
'help'][$key]));
1873 $extratitle = $langs->trans($value);
1875 print
'<td style="text-align: right">'.$extratitle.
'</td>';
1880 print
'</tr></thead>';
1884 $produit_multiprices_limit =
getDolGlobalInt(
'PRODUIT_MULTIPRICES_LIMIT');
1885 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
1886 print
'<tr class="oddeven">';
1888 $keyforlabel =
'PRODUIT_MULTIPRICES_LABEL'.$i;
1890 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
1896 print
'<input type="hidden" name="tva_tx['.$i.
']" value="'.(
$object->default_vat_code ?
$object->tva_tx.
' ('.
$object->default_vat_code.
')' :
$object->tva_tx).
'">';
1897 print
'<input type="hidden" name="tva_npr['.$i.
']" value="'.
$object->tva_npr.
'">';
1898 print
'<input type="hidden" name="localtax1_tx['.$i.
']" value="'.
$object->localtax1_tx.
'">';
1899 print
'<input type="hidden" name="localtax1_type['.$i.
']" value="'.
$object->localtax1_type.
'">';
1900 print
'<input type="hidden" name="localtax2_tx['.$i.
']" value="'.
$object->localtax2_tx.
'">';
1901 print
'<input type="hidden" name="localtax2_type['.$i.
']" value="'.
$object->localtax2_type.
'">';
1905 print
'<td style="text-align: center">';
1906 print $form->load_tva(
"tva_tx[".$i.
']',
$object->multiprices_tva_tx[$i],
$mysoc,
null,
$object->id, 0,
$object->type,
false, 1, 1);
1911 print
'<td style="text-align: center">';
1912 if (
$object->multiprices_base_type [$i] ==
'TTC') {
1913 print
'<input name="price['.$i.
']" size="10" value="'.
price(
$object->multiprices_ttc [$i]).
'">';
1915 print
'<input name="price['.$i.
']" size="10" value="'.
price(
$object->multiprices [$i]).
'">';
1917 print
' '.$form->selectPriceBaseType(
$object->multiprices_base_type [$i],
"multiprices_base_type[".$i.
"]");
1921 print
'<td style="text-align: center">';
1922 if (
$object->multiprices_base_type [$i] ==
'TTC') {
1923 print
'<input name="price_min['.$i.
']" size="10" value="'.
price(
$object->multiprices_min_ttc [$i]).
'">';
1925 print
'<input name="price_min['.$i.
']" size="10" value="'.
price(
$object->multiprices_min [$i]).
'">';
1928 print
'<td class="left">'.$langs->trans(
"MinimumRecommendedPrice",
price((
float) $maxpricesupplier, 0,
'', 1, -1, -1,
'auto')).
' '.
img_warning().
'</td>';
1932 if (!empty($extralabels)) {
1933 $sql1 =
"SELECT rowid";
1934 $sql1 .=
" FROM ".$object->db->prefix().
"product_price";
1935 $sql1 .=
" WHERE entity IN (".getEntity(
'productprice').
")";
1936 $sql1 .=
" AND price_level=".((int) $i);
1937 $sql1 .=
" AND fk_product = ".((int)
$object->id);
1938 $sql1 .=
" ORDER BY date_price DESC, rowid DESC";
1939 $sql1 .=
" LIMIT 1";
1940 $resql1 =
$object->db->query($sql1);
1942 $lineid =
$object->db->fetch_object($resql1);
1944 if (empty($lineid->rowid)) {
1945 foreach ($extralabels as $key => $value) {
1946 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))) {
1947 if (!empty($extrafields->attributes[
"product_price"][
'langfile'][$key])) {
1948 $langs->load($extrafields->attributes[
"product_price"][
'langfile'][$key]);
1951 $extravalue = GETPOSTISSET(
'options_'.$key) ? $extrafield_values[
'options_'.$key] : $obj->{$key};
1952 print
'<td align="center"><input name="'.$key.
'['.$i.
']" size="10" value="'.$extravalue.
'"></td>';
1957 $sql .=
" fk_object";
1958 foreach ($extralabels as $key => $value) {
1959 $sql .=
", ".$db->sanitize($key);
1961 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product_price_extrafields";
1962 $sql .=
" WHERE fk_object = ".((int) $lineid->rowid);
1963 $resql = $db->query($sql);
1965 $obj = $db->fetch_object($resql);
1966 foreach ($extralabels as $key => $value) {
1967 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))) {
1968 if (!empty($extrafields->attributes[
"product_price"][
'langfile'][$key])) {
1969 $langs->load($extrafields->attributes[
"product_price"][
'langfile'][$key]);
1972 $extravalue = (GETPOSTISSET(
'options_'.$key) ? $extrafield_values[
'options_'.$key] : $obj->{$key} ??
'');
1973 print
'<td align="center"><input name="'.$key.
'['.$i.
']" size="10" value="'.$extravalue.
'"></td>';
1990 print $form->buttonsSaveCancel();
2001 $sortfield =
GETPOST(
'sortfield',
'aZ09comma');
2002 $sortorder =
GETPOST(
'sortorder',
'aZ09comma');
2004 if (empty($page) || $page == -1) {
2007 $offset = $limit * $page;
2008 $pageprev = $page - 1;
2009 $pagenext = $page + 1;
2011 $sortorder =
"ASC,ASC";
2014 $sortfield =
"soc.nom,t.date_begin";
2018 $filter = array(
't.fk_product' => (
string)
$object->id);
2020 if (!empty($search_soc)) {
2021 $filter[
'soc.nom'] = (string) $search_soc;
2024 if ($action ==
'add_customer_price') {
2026 $maxpricesupplier =
$object->min_recommended_price();
2028 print
'<!-- add_customer_price -->';
2031 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
2032 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2033 print
'<input type="hidden" name="action" value="add_customer_price_confirm">';
2034 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
2036 print
'<div class="tabBar tabBarWithBottom">';
2038 print
'<table class="border centpercent">';
2040 print
'<td class="fieldrequired">'.$langs->trans(
'ThirdParty').
'</td>';
2042 $filter =
'(s.client:IN:1,2,3)';
2043 print
img_picto(
'',
'company').$form->select_company(
GETPOSTINT(
'socid'),
'socid', $filter,
'SelectThirdParty', 0, 0, array(), 0,
'minwidth300');
2048 print
'<tr><td>' . $langs->trans(
'RefCustomer') .
'</td>';
2049 print
'<td><input name="ref_customer" size="12"></td></tr>';
2053 print
'<tr><td>'.$langs->trans(
"AppliedPricesFrom").
'</td><td>';
2054 print $form->selectDate(!empty($date_begin) ? $date_begin :
dol_now(),
"date_begin", 0, 0, 1,
"date_begin");
2059 print
'<tr><td>'.$langs->trans(
"AppliedPricesTo").
'</td><td>';
2060 print $form->selectDate($date_end,
"date_end", 0, 0, 1,
"date_end");
2064 print
'<tr><td class="fieldrequired">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
2069 print
'<tr><td class="fieldrequired">';
2070 print $langs->trans(
'PriceBase');
2073 print $form->selectPriceBaseType(
$object->price_base_type,
"price_base_type");
2078 print
'<tr><td class="fieldrequired">';
2079 $text = $langs->trans(
'SellingPrice');
2080 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
2082 if (
$object->price_base_type ==
'TTC') {
2083 print
'<input name="price" size="10" value="'.price(
$object->price_ttc).
'">';
2085 print
'<input name="price" size="10" value="'.price(
$object->price).
'">';
2091 $text = $langs->trans(
'MinPrice');
2092 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
2093 if (
$object->price_base_type ==
'TTC') {
2094 print
'<td><input name="price_min" size="10" value="'.price(
$object->price_min_ttc).
'">';
2096 print
'<td><input name="price_min" size="10" value="'.price(
$object->price_min).
'">';
2099 print
'<td class="left">'.$langs->trans(
"MinimumRecommendedPrice",
price($maxpricesupplier, 0,
'', 1, -1, -1,
'auto')).
' '.
img_warning().
'</td>';
2105 print $langs->trans(
'PriceLabel');
2107 print
'<input name="price_label" maxlength="255" class="minwidth300 maxwidth400onsmartphone" value="'.$object->price_label.
'">';
2113 print
'<tr><td>'.$langs->trans(
"Discount").
'</td><td>';
2114 print
'<input name="discount_percent" size="10" value="'.price($discount_percent).
'">';
2118 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2119 $extralabels = !empty($extrafields->attributes[
"product_customer_price"][
'label']) ? $extrafields->attributes[
"product_customer_price"][
'label'] :
'';
2120 $extrafield_values = $extrafields->getOptionalsFromPost(
"product_customer_price");
2121 if (!empty($extralabels)) {
2122 if (empty($prodcustprice->id)) {
2123 foreach ($extralabels as $key => $value) {
2124 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))) {
2125 if (!empty($extrafields->attributes[
"product_customer_price"][
'langfile'][$key])) {
2126 $langs->load($extrafields->attributes[
"product_customer_price"][
'langfile'][$key]);
2129 print
'<tr><td'.($extrafields->attributes[
"product_customer_price"][
'required'][$key] ?
' class="fieldrequired"' :
'').
'>';
2130 if (!empty($extrafields->attributes[
"product_customer_price"][
'help'][$key])) {
2131 print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_customer_price"][
'help'][$key]));
2133 print $langs->trans($value);
2135 print
'</td><td>'.$extrafields->showInputField($key, GETPOSTISSET(
'options_'.$key) ? $extrafield_values[
'options_'.$key] :
'',
'',
'',
'',
'', 0,
'product_customer_price').
'</td></tr>';
2146 print
'<div class="center">';
2149 print
'<div class="marginbottomonly">';
2150 print
'<input type="checkbox" name="updatechildprice" id="updatechildprice" value="1"> ';
2151 print
'<label for="updatechildprice">'.$langs->trans(
'ForceUpdateChildPriceSoc').
'</label>';
2154 print $form->buttonsSaveCancel();
2157 } elseif ($action ==
'edit_customer_price') {
2159 $maxpricesupplier =
$object->min_recommended_price();
2161 print
'<!-- edit_customer_price -->';
2164 $result = $prodcustprice->fetch(
GETPOSTINT(
'lineid'));
2169 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
2170 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2171 print
'<input type="hidden" name="action" value="update_customer_price_confirm">';
2172 print
'<input type="hidden" name="lineid" value="'.$prodcustprice->id.
'">';
2174 print
'<table class="liste centpercent">';
2176 print
'<td class="titlefield fieldrequired">'.$langs->trans(
'ThirdParty').
'</td>';
2177 $staticsoc =
new Societe($db);
2178 $staticsoc->fetch($prodcustprice->fk_soc);
2179 print
"<td>".$staticsoc->getNomUrl(1).
"</td>";
2183 print
'<tr><td>' . $langs->trans(
'RefCustomer') .
'</td>';
2184 print
'<td><input name="ref_customer" size="12" value="' .
dol_escape_htmltag($prodcustprice->ref_customer) .
'"></td></tr>';
2187 print
'<tr><td>'.$langs->trans(
"AppliedPricesFrom").
'</td><td>';
2188 print $form->selectDate($prodcustprice->date_begin,
"date_begin", 0, 0, 1,
"date_begin");
2192 print
'<tr><td>'.$langs->trans(
"AppliedPricesTo").
'</td><td>';
2193 print $form->selectDate($prodcustprice->date_end,
"date_end", 0, 0, 1,
"date_end");
2197 print
'<tr><td class="fieldrequired">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
2198 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, 1);
2202 print
'<tr><td class="fieldrequired">';
2203 print $langs->trans(
'PriceBase');
2206 print $form->selectPriceBaseType($prodcustprice->price_base_type,
"price_base_type");
2211 print
'<tr><td class="fieldrequired">';
2212 $text = $langs->trans(
'SellingPrice');
2213 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
2215 if ($prodcustprice->price_base_type ==
'TTC') {
2216 print
'<input name="price" size="10" value="'.price($prodcustprice->price_ttc).
'">';
2218 print
'<input name="price" size="10" value="'.price($prodcustprice->price).
'">';
2224 $text = $langs->trans(
'MinPrice');
2225 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
2227 if ($prodcustprice->price_base_type ==
'TTC') {
2228 print
'<input name="price_min" size="10" value="'.price($prodcustprice->price_min_ttc).
'">';
2230 print
'<input name="price_min" size="10" value="'.price($prodcustprice->price_min).
'">';
2234 print
'<td class="left">'.$langs->trans(
"MinimumRecommendedPrice",
price($maxpricesupplier, 0,
'', 1, -1, -1,
'auto')).
' '.
img_warning().
'</td>';
2240 print $langs->trans(
'PriceLabel');
2242 print
'<input name="price_label" maxlength="255" class="minwidth300 maxwidth400onsmartphone" value="'.$prodcustprice->price_label.
'">';
2247 print
'<tr><td>'.$langs->trans(
"Discount").
'</td><td>';
2248 print
'<input name="discount_percent" size="10" value="'.price($prodcustprice->discount_percent).
'">';
2252 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2253 $extralabels = !empty($extrafields->attributes[
"product_customer_price"][
'label']) ? $extrafields->attributes[
"product_customer_price"][
'label'] :
'';
2254 $extrafield_values = $extrafields->getOptionalsFromPost(
"product_customer_price");
2255 if (!empty($extralabels)) {
2257 foreach ($extralabels as $key => $value) {
2258 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))) {
2259 if (!empty($extrafields->attributes[
"product_customer_price"][
'langfile'][$key])) {
2260 $langs->load($extrafields->attributes[
"product_customer_price"][
'langfile'][$key]);
2263 print
'<tr><td'.($extrafields->attributes[
"product_customer_price"][
'required'][$key] ?
' class="fieldrequired"' :
'').
'>';
2264 if (!empty($extrafields->attributes[
"product_customer_price"][
'help'][$key])) {
2265 print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_customer_price"][
'help'][$key]));
2267 print $langs->trans($value);
2269 print
'</td><td>'.$extrafields->showInputField($key, GETPOSTISSET(
'options_'.$key) ? $extrafield_values[
'options_'.$key] :
'',
'',
'',
'',
'', 0,
'product_customer_price').
'</td></tr>';
2274 $sql .=
" fk_object";
2275 foreach ($extralabels as $key => $value) {
2276 $sql .=
", ".$db->sanitize($key);
2278 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product_customer_price_extrafields";
2279 $sql .=
" WHERE fk_object = ".((int) $prodcustprice->id);
2280 $resql = $db->query($sql);
2282 $obj = $db->fetch_object($resql);
2283 foreach ($extralabels as $key => $value) {
2284 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))) {
2285 if (!empty($extrafields->attributes[
"product_customer_price"][
'langfile'][$key])) {
2286 $langs->load($extrafields->attributes[
"product_customer_price"][
'langfile'][$key]);
2289 print
'<tr><td'.($extrafields->attributes[
"product_customer_price"][
'required'][$key] ?
' class="fieldrequired"' :
'').
'>';
2290 if (!empty($extrafields->attributes[
"product_customer_price"][
'help'][$key])) {
2291 print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_customer_price"][
'help'][$key]));
2293 print $langs->trans($value);
2295 print
'</td><td>'.$extrafields->showInputField($key, GETPOSTISSET(
'options_'.$key) ? $extrafield_values[
'options_'.$key] : $obj->{$key},
'',
'',
'',
'', 0,
'product_customer_price');
2307 print
'<div class="center">';
2308 print
'<div class="marginbottomonly">';
2309 print
'<input type="checkbox" name="updatechildprice" id="updatechildprice" value="1"> ';
2310 print
'<label for="updatechildprice">'.$langs->trans(
'ForceUpdateChildPriceSoc').
'</label>';
2313 print $form->buttonsSaveCancel();
2315 print
'<br></form>';
2316 } elseif ($action ==
'showlog_customer_price') {
2318 print
'<!-- list of all log of prices per customer -->'.
"\n";
2320 $sortfield =
't.datec';
2321 $filter = array(
't.fk_product' => (
string)
$object->id,
't.fk_soc' => (
string)
GETPOSTINT(
'socid'));
2324 $nbtotalofrecords =
'';
2326 $nbtotalofrecords = $prodcustprice->fetchAllLog($sortorder, $sortfield, $conf->liste_limit, $offset, $filter);
2329 $result = $prodcustprice->fetchAllLog($sortorder, $sortfield, $conf->liste_limit, $offset, $filter);
2334 $option =
'&socid='.GETPOSTINT(
'socid').
'&id='.
$object->id;
2336 $staticsoc =
new Societe($db);
2339 $title = $langs->trans(
'PriceByCustomerLog');
2340 $title .=
' - '.$staticsoc->getNomUrl(1);
2342 $backbutton =
'<a class="justalink" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'">'.$langs->trans(
"GoBack").
'</a>';
2345 print_barre_liste($title, $page, $_SERVER[
'PHP_SELF'], $option, $sortfield, $sortorder, $backbutton, count($prodcustprice->lines), $nbtotalofrecords,
'title_accountancy.png');
2347 if (count($prodcustprice->lines) > 0) {
2348 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
2349 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2350 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
2352 print
'<div class="div-table-responsive-no-min">';
2353 print
'<table class="liste centpercent">';
2355 print
'<tr class="liste_titre">';
2356 print
'<td>'.$langs->trans(
"ThirdParty").
'</td>';
2357 print
'<td>'.$langs->trans(
'RefCustomer').
'</td>';
2358 print
'<td>'.$langs->trans(
"AppliedPricesFrom").
'</td>';
2359 print
'<td>'.$langs->trans(
"AppliedPricesTo").
'</td>';
2360 print
'<td class="center">'.$langs->trans(
"PriceBase").
'</td>';
2361 print
'<td class="right">'.$langs->trans(
"DefaultTaxRate").
'</td>';
2362 print
'<td class="right">'.$langs->trans(
"HT").
'</td>';
2363 print
'<td class="right">'.$langs->trans(
"TTC").
'</td>';
2364 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2365 print
'<td class="right">'.$langs->trans(
"INCT").
'</td>';
2367 print
'<td class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"HT").
'</td>';
2368 print
'<td class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"TTC").
'</td>';
2369 print
'<td class="right">'.$langs->trans(
"PriceLabel").
'</td>';
2370 print
'<td class="right">'.$langs->trans(
"Discount").
'</td>';
2371 print
'<td class="right">'.$langs->trans(
"ChangedBy").
'</td>';
2372 print
'<td>'.$langs->trans(
"DateCreation").
'</td>';
2375 foreach ($prodcustprice->lines as $line) {
2377 $staticsoc =
new Societe($db);
2378 $staticsoc->fetch($line->fk_soc);
2380 $tva_tx = $line->default_vat_code ? $line->tva_tx.
' ('.$line->default_vat_code.
')' : $line->tva_tx;
2383 if ($line->price_base_type ==
'HT') {
2386 $pu = $line->price_ttc;
2390 $localtaxarray =
getLocalTaxesFromRate($line->tva_tx.($line->default_vat_code ?
' ('.$line->default_vat_code.
')' :
''), 0, $staticsoc,
$mysoc);
2392 $resultarray =
calcul_price_total(1, $pu, 0, (
float) $line->tva_tx, 1, 1, 0, $line->price_base_type, $line->recuperableonly,
$object->type,
$mysoc, $localtaxarray);
2394 $total_ht = $resultarray[0];
2395 $total_vat = $resultarray[1];
2396 $total_localtax1 = $resultarray[9];
2397 $total_localtax2 = $resultarray[10];
2398 $total_ttc = $resultarray[2];
2400 print
'<tr class="oddeven">';
2402 print
'<td class="tdoverflowmax125">'.$staticsoc->getNomUrl(1).
"</td>";
2403 print
'<td>'.$line->ref_customer.
'</td>';
2404 print
"<td>".dol_print_date($line->date_begin,
"day",
'tzuserrel').
"</td>";
2405 print
"<td>".dol_print_date($line->date_end,
"day",
'tzuserrel').
"</td>";
2406 print
'<td class="center">'.$langs->trans($line->price_base_type).
"</td>";
2407 print
'<td class="right nowraponall">';
2409 $positiverates =
'';
2411 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->tva_tx);
2414 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->localtax1_tx);
2417 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->localtax2_tx);
2419 if (empty($positiverates)) {
2420 $positiverates =
'0';
2423 echo
vatrate($positiverates.($line->default_vat_code ?
' ('.$line->default_vat_code.
')' :
''), true, ($line->tva_npr ? $line->tva_npr : $line->recuperableonly));
2427 print
'<td class="right"><span class="amount">'.price($line->price).
"</span></td>";
2429 print
'<td class="right"><span class="amount">'.price($line->price_ttc).
"</span></td>";
2430 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2431 print
'<td class="right">'.price($resultarray[2]).
'</td>';
2434 print
'<td class="right">'.price($line->price_min).
'</td>';
2435 print
'<td class="right">'.price($line->price_min_ttc).
'</td>';
2436 print
'<td class="right">'.dolPrintHTML($line->price_label).
'</td>';
2437 print
'<td class="right">'.price($line->discount_percent).
'</td>';
2440 print
'<td class="tdoverflowmax125">';
2442 if ($line->fk_user > 0) {
2443 $userstatic =
new User($db);
2444 $userstatic->fetch($line->fk_user);
2445 print $userstatic->getNomUrl(1,
'', 0, 0, 24, 0,
'login');
2449 print
"<td>".dol_print_date($line->datec,
"dayhour",
'tzuserrel').
"</td>";
2455 print $langs->trans(
'None');
2457 } elseif ($action !=
'showlog_default_price' && $action !=
'edit_price' && $action !=
'edit_level_price') {
2459 print
'<!-- list of all prices per customer -->'.
"\n";
2462 $nbtotalofrecords =
'';
2464 $nbtotalofrecords = $prodcustprice->fetchAll($sortorder, $sortfield, 0, 0, $filter);
2467 $result = $prodcustprice->fetchAll($sortorder, $sortfield, $conf->liste_limit, $offset, $filter);
2472 $option =
'&search_soc='.$search_soc.
'&id='.
$object->id;
2475 print_barre_liste($langs->trans(
'PriceByCustomer'), $page, $_SERVER [
'PHP_SELF'], $option, $sortfield, $sortorder,
'', count($prodcustprice->lines), $nbtotalofrecords,
'title_accountancy.png');
2477 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
2478 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2479 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
2481 print
'<!-- List of prices per customer -->'.
"\n";
2482 print
'<div class="div-table-responsive-no-min">'.
"\n";
2483 print
'<table class="liste centpercent">'.
"\n";
2485 if (count($prodcustprice->lines) > 0 || $search_soc) {
2486 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2487 $custom_price_extralabels = !empty($extrafields->attributes[
"product_customer_price"][
'label']) ? $extrafields->attributes[
"product_customer_price"][
'label'] :
'';
2493 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2496 if (!empty($custom_price_extralabels) && is_array($custom_price_extralabels)) {
2497 $colspan += count($custom_price_extralabels);
2500 print
'<tr class="liste_titre">';
2501 print
'<td class="liste_titre"><input type="text" class="flat maxwidth125" name="search_soc" value="'.$search_soc.
'"></td>';
2502 print
'<td class="liste_titre" colspan="'.$colspan.
'"> </td>';
2504 print
'<td class="liste_titre maxwidthsearch">';
2505 $searchpicto = $form->showFilterAndCheckAddButtons(0);
2511 print
'<tr class="liste_titre">';
2512 print
'<td>'.$langs->trans(
"ThirdParty").
'</td>';
2513 print
'<td>'.$langs->trans(
'RefCustomer').
'</td>';
2514 print
'<td>'.$langs->trans(
"AppliedPricesFrom").
'</td>';
2515 print
'<td>'.$langs->trans(
"AppliedPricesTo").
'</td>';
2516 print
'<td class="center">'.$langs->trans(
"PriceBase").
'</td>';
2517 print
'<td class="right">'.$langs->trans(
"DefaultTaxRate").
'</td>';
2518 print
'<td class="right">'.$langs->trans(
"HT").
'</td>';
2519 print
'<td class="right">'.$langs->trans(
"TTC").
'</td>';
2520 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2521 print
'<td class="right">'.$langs->trans(
"INCT").
'</td>';
2523 print
'<td class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"HT").
'</td>';
2524 print
'<td class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"TTC").
'</td>';
2525 print
'<td class="right">'.$langs->trans(
"PriceLabel").
'</td>';
2526 print
'<td class="right">'.$langs->trans(
"Discount").
'</td>';
2528 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2529 if ($extrafields->attributes[
"product_customer_price"] && array_key_exists(
'label', $extrafields->attributes[
"product_customer_price"])) {
2530 $extralabels = $extrafields->attributes[
"product_customer_price"][
'label'];
2531 if (!empty($extralabels)) {
2532 foreach ($extralabels as $key => $value) {
2534 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && $extrafields->attributes[
"product_customer_price"][
'list'][$key] != 3) {
2535 if (!empty($extrafields->attributes[
"product_customer_price"][
'langfile'][$key])) {
2536 $langs->load($extrafields->attributes[
"product_customer_price"][
'langfile'][$key]);
2538 if (!empty($extrafields->attributes[
"product_customer_price"][
'help'][$key])) {
2539 $extratitle = $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_customer_price"][
'help'][$key]));
2541 $extratitle = $langs->trans($value);
2543 print
'<td style="text-align: right">'.$extratitle.
'</td>';
2548 print
'<td>'.$langs->trans(
"ChangedBy").
'</td>';
2553 if (
$object->price_base_type ==
'HT') {
2562 $resultarray =
calcul_price_total(1, $pu, 0,
$object->tva_tx, 1, 1, 0,
$object->price_base_type, 0,
$object->type,
$mysoc, $localtaxarray);
2564 $total_ht = $resultarray[0];
2565 $total_vat = $resultarray[1];
2566 $total_localtax1 = $resultarray[9];
2567 $total_localtax2 = $resultarray[10];
2568 $total_ttc = $resultarray[2];
2571 print
'<!-- PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES -->'.
"\n";
2572 print
'<tr class="oddeven">';
2573 print
'<td colspan="4">' . $langs->trans(
'Default') .
'</td>';
2575 print
'<td class="center">'.$langs->trans(
$object->price_base_type).
"</td>";
2578 print
'<td class="right nowraponall">';
2580 $positiverates =
'';
2585 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax1_tx);
2588 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax2_tx);
2590 if (empty($positiverates)) {
2591 $positiverates =
'0';
2593 echo
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr);
2597 print
'<td class="right"><span class="amount">'.price(
$object->price).
"</span></td>";
2599 print
'<td class="right"><span class="amount">'.price(
$object->price_ttc).
"</span></td>";
2600 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2602 print
'<td class="right"><span class="amount">'.price($resultarray[2]).
'</span></td>';
2605 print
'<td class="right">'.price(
$object->price_min).
'</td>';
2606 print
'<td class="right">'.price(
$object->price_min_ttc).
'</td>';
2607 print
'<td class="right">'.dolPrintHTML(
$object->price_label).
'</td>';
2608 print
'<td class="right"></td>';
2609 print
'<td class="right"></td>';
2610 if (!empty($extralabels)) {
2611 foreach ($extralabels as $key) {
2613 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && $extrafields->attributes[
"product_customer_price"][
'list'][$key] != 3) {
2614 print
'<td class="right"></td>';
2618 if ($user->hasRight(
'produit',
'supprimer') || $user->hasRight(
'service',
'supprimer')) {
2619 print
'<td class="nowraponall">';
2620 print
'<a class="marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?action=showlog_default_price&token='.
newToken().
'&id='.
$object->id.
'">';
2621 print
img_info($langs->trans(
'PriceByCustomerLog'));
2624 print
'<a class="marginleftonly marginrightonly editfielda" href="'.$_SERVER[
"PHP_SELF"].
'?action=edit_price&token='.
newToken().
'&id='.
$object->id.
'">';
2625 print
img_edit(
'default', 0,
'style="vertical-align: middle;"');
2632 if (count($prodcustprice->lines) > 0) {
2633 foreach ($prodcustprice->lines as $line) {
2635 $staticsoc =
new Societe($db);
2636 $staticsoc->fetch($line->fk_soc);
2638 $tva_tx = $line->default_vat_code ? $line->tva_tx.
' ('.$line->default_vat_code.
')' : $line->tva_tx;
2641 if ($line->price_base_type ==
'HT') {
2644 $pu = $line->price_ttc;
2648 $localtaxarray =
getLocalTaxesFromRate($line->tva_tx.($line->default_vat_code ?
' ('.$line->default_vat_code.
')' :
''), 0, $staticsoc,
$mysoc);
2650 $resultarray =
calcul_price_total(1, $pu, 0, (
float) $line->tva_tx, 1, 1, 0, $line->price_base_type, $line->recuperableonly,
$object->type,
$mysoc, $localtaxarray);
2652 $total_ht = $resultarray[0];
2653 $total_vat = $resultarray[1];
2654 $total_localtax1 = $resultarray[9];
2655 $total_localtax2 = $resultarray[10];
2656 $total_ttc = $resultarray[2];
2658 print
'<tr class="oddeven">';
2660 print
'<td class="tdoverflowmax125">'.$staticsoc->getNomUrl(1).
"</td>";
2661 print
'<td>'.dolPrintHTML($line->ref_customer).
'</td>';
2662 print
"<td>".dol_print_date($line->date_begin,
"day",
'tzuserrel').
"</td>";
2663 print
"<td>".dol_print_date($line->date_end,
"day",
'tzuserrel').
"</td>";
2664 print
'<td class="center">'.$langs->trans($line->price_base_type).
"</td>";
2666 print
'<td class="right nowraponall">';
2668 $positiverates =
'';
2670 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->tva_tx);
2673 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->localtax1_tx);
2676 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->localtax2_tx);
2678 if (empty($positiverates)) {
2679 $positiverates =
'0';
2682 echo
vatrate($positiverates.($line->default_vat_code ?
' ('.$line->default_vat_code.
')' :
''), true, (!empty($line->tva_npr) ? $line->tva_npr : $line->recuperableonly));
2686 print
'<td class="right"><span class="amount">'.price($line->price).
"</span></td>";
2688 print
'<td class="right"><span class="amount">'.price($line->price_ttc).
"</span></td>";
2689 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2691 print
'<td class="right"><span class="amount">'.price($resultarray[2]).
'</span></td>';
2694 print
'<td class="right">'.price($line->price_min).
'</td>';
2695 print
'<td class="right">'.price($line->price_min_ttc).
'</td>';
2696 print
'<td class="right">'.dolPrintHTMLForAttribute($line->price_label).
'</td>';
2697 print
'<td class="right">'.price($line->discount_percent).
'</td>';
2700 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2701 $extralabels = $extrafields->attributes[
"product_customer_price"][
'label'] ?? array();
2702 if (!empty($extralabels)) {
2704 $sql .=
" fk_object";
2705 foreach ($extralabels as $key => $value) {
2706 $sql .=
", ".$db->sanitize($key);
2708 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product_customer_price_extrafields";
2709 $sql .=
" WHERE fk_object = ".((int) $line->id);
2710 $resql = $db->query($sql);
2712 if ($db->num_rows($resql) != 1) {
2713 foreach ($extralabels as $key => $value) {
2714 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && $extrafields->attributes[
"product_customer_price"][
'list'][$key] != 3) {
2719 $obj = $db->fetch_object($resql);
2720 foreach ($extralabels as $key => $value) {
2721 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && $extrafields->attributes[
"product_customer_price"][
'list'][$key] != 3) {
2722 print
'<td align="right">'.$extrafields->showOutputField($key, $obj->{$key},
'',
'product_customer_price').
"</td>";
2731 print
'<td class="tdoverflowmax125">';
2732 if ($line->fk_user > 0) {
2733 $userstatic =
new User($db);
2734 $userstatic->fetch($line->fk_user);
2736 print $userstatic->getNomUrl(-1,
'', 0, 0, 24, 0,
'login');
2742 print
'<td class="right nowraponall">';
2743 if ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer')) {
2744 print
'<a href="'.$_SERVER[
"PHP_SELF"].
'?action=showlog_customer_price&token='.
newToken().
'&id='.
$object->id.
'&socid='.$line->fk_soc.
'">';
2745 print
img_info($langs->trans(
'PriceByCustomerLog'));
2748 print
'<a class="marginleftonly editfielda" href="'.$_SERVER[
"PHP_SELF"].
'?action=edit_customer_price&token='.
newToken().
'&id='.
$object->id.
'&lineid='.$line->id.
'">';
2749 print
img_edit(
'default', 0,
'style="vertical-align: middle;"');
2753 if ($user->hasRight(
'produit',
'supprimer') || $user->hasRight(
'service',
'supprimer')) {
2754 print
'<a class="marginleftonly" href="'.$_SERVER[
"PHP_SELF"].
'?action=ask_remove_customer_price&token='.
newToken().
'&id='.
$object->id.
'&lineid='.$line->id.
'">';
2755 print
img_delete(
'default',
'style="vertical-align: middle;"');
2773if ((!
getDolGlobalString(
'PRODUIT_CUSTOMER_PRICES') || $action ==
'showlog_default_price') && !in_array($action, array(
'edit_price',
'edit_level_price',
'edit_vat'))) {
2774 $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,";
2775 $sql .=
" p.price_level, p.price_min, p.price_min_ttc,p.price_by_qty,";
2776 $sql .=
" p.date_price as dp, p.fk_price_expression, u.rowid as user_id, u.login";
2777 $sql .=
" ,p.price_label";
2778 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product_price as p,";
2779 $sql .=
" ".MAIN_DB_PREFIX.
"user as u";
2780 $sql .=
" WHERE fk_product = ".((int)
$object->id);
2781 $sql .=
" AND p.entity IN (".getEntity(
'productprice').
")";
2782 $sql .=
" AND p.fk_user_author = u.rowid";
2784 $sql .=
" AND p.price_level = ".((int) $soc->price_level);
2786 $sql .=
" ORDER BY p.date_price DESC, p.rowid DESC, p.price_level ASC";
2790 $result = $db->query($sql);
2792 print
'<div class="divlogofpreviouscustomerprice">';
2794 $num = $db->num_rows($result);
2803 $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);
2805 $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);
2811 $result = $db->query($sql);
2812 $num = $db->num_rows($result);
2819 $backbutton =
'<a class="justalink" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'">'.$langs->trans(
"GoBack").
'</a>';
2823 print_barre_liste($langs->trans(
"DefaultPriceLog"), 0, $_SERVER[
"PHP_SELF"],
'',
'',
'', $backbutton, 0, $num,
'title_accountancy.png');
2826 print_barre_liste($langs->trans(
"PriceByCustomerLog"), 0, $_SERVER[
"PHP_SELF"],
'',
'',
'',
'', 0, $num,
'title_accountancy.png');
2829 print
'<!-- List of log prices -->'.
"\n";
2830 print
'<div class="div-table-responsive">'.
"\n";
2831 print
'<table class="liste centpercent noborder">'.
"\n";
2833 print
'<tr class="liste_titre">';
2834 print
'<th>'.$langs->trans(
"AppliedPricesFrom").
'</tg>';
2837 print
'<th class="center">'.$langs->trans(
"PriceLevel").
'</th>';
2840 print
'<th class="center">'.$langs->trans(
"Type").
'</th>';
2843 print
'<th class="center">'.$langs->trans(
"PriceBase").
'</th>';
2845 print
'<th class="right">'.$langs->trans(
"DefaultTaxRate").
'</th>';
2847 print
'<th class="right">'.$langs->trans(
"HT").
'</th>';
2848 print
'<th class="right">'.$langs->trans(
"TTC").
'</th>';
2849 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2850 print
'<th class="right">'.$langs->trans(
"INCT").
'</th>';
2853 print
'<th class="right">'.$langs->trans(
"PriceExpressionSelected").
'</th>';
2855 print
'<th class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"HT").
'</th>';
2856 print
'<th class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"TTC").
'</th>';
2857 print
'<th class="right">'.$langs->trans(
"Label").
'</th>';
2858 print
'<th>'.$langs->trans(
"ChangedBy").
'</th>';
2859 if ($user->hasRight(
'produit',
'supprimer')) {
2860 print
'<th class="right"> </th>';
2864 $notfirstlineforlevel = array();
2868 $objp = $db->fetch_object($result);
2870 print
'<tr class="oddeven">';
2872 print
"<td>".dol_print_date($db->jdate($objp->dp),
"dayhour",
'tzuserrel').
"</td>";
2876 print
'<td class="center">'.$objp->price_level.
"</td>";
2880 $type = ($objp->price_by_qty == 1) ?
'PriceByQuantity' :
'Standard';
2881 print
'<td class="center">'.$langs->trans($type).
"</td>";
2884 print
'<td class="center">';
2885 if (empty($objp->price_by_qty)) {
2886 print $langs->trans($objp->price_base_type);
2891 print
'<td class="right">';
2893 if (empty($objp->price_by_qty)) {
2894 $positiverates =
'';
2896 $positiverates .= ($positiverates ?
'/' :
'').
price2num($objp->tva_tx);
2899 $positiverates .= ($positiverates ?
'/' :
'').
price2num($objp->localtax1_tx);
2902 $positiverates .= ($positiverates ?
'/' :
'').
price2num($objp->localtax2_tx);
2904 if (empty($positiverates)) {
2905 $positiverates =
'0';
2907 echo
vatrate($positiverates.($objp->default_vat_code ?
' ('.$objp->default_vat_code.
')' :
''), true, !empty($objp->tva_npr) ? $objp->tva_npr : 0);
2920 if ($objp->price_base_type ==
'HT') {
2923 $pu = $objp->price_ttc;
2929 $resultarray =
calcul_price_total(1, $pu, 0, $objp->tva_tx, 1, 1, 0, $objp->price_base_type, $objp->recuperableonly,
$object->type,
$mysoc, $localtaxarray);
2931 $total_ht = $resultarray[0];
2932 $total_vat = $resultarray[1];
2933 $total_localtax1 = $resultarray[9];
2934 $total_localtax2 = $resultarray[10];
2935 $total_ttc = $resultarray[2];
2938 if (!empty($objp->fk_price_expression) && !empty($conf->dynamicprices->enabled)) {
2940 $res = $price_expression->fetch($objp->fk_price_expression);
2941 $title = $price_expression->title;
2942 print
'<td class="right"></td>';
2943 print
'<td class="right"></td>';
2944 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2945 print
'<td class="right"></td>';
2947 print
'<td class="right">'.$title.
"</td>";
2950 print
'<td class="right">';
2951 if (empty($objp->price_by_qty)) {
2952 print
'<span class="amount">'.price($objp->price).
'</span>';
2956 print
'<td class="right">';
2957 if (empty($objp->price_by_qty)) {
2958 $price_ttc = $objp->price_ttc;
2959 print
'<span class="amount">'.price($price_ttc).
'<span>';
2962 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2963 print
'<td class="right">';
2964 print $resultarray[2];
2968 print
'<td class="right"></td>';
2973 print
'<td class="right">';
2974 if (empty($objp->price_by_qty)) {
2975 print
price($objp->price_min);
2980 print
'<td class="right">';
2981 if (empty($objp->price_by_qty)) {
2982 $price_min_ttc = $objp->price_min_ttc;
2983 print
price($price_min_ttc);
2993 print
'<td class="tdoverflowmax125">';
2994 if ($objp->user_id > 0) {
2996 $userstatic =
new User($db);
2997 $userstatic->fetch($objp->user_id);
2998 print $userstatic->getNomUrl(-1,
'', 0, 0, 24, 0,
'login');
3003 if ($user->hasRight(
'produit',
'supprimer')) {
3006 if (empty($notfirstlineforlevel[$objp->price_level])) {
3007 $notfirstlineforlevel[$objp->price_level] = 1;
3015 print
'<td class="right">';
3016 if ($candelete || ($db->jdate($objp->dp) >=
dol_now())) {
3017 print
'<a href="'.$_SERVER[
"PHP_SELF"].
'?action=delete&token='.
newToken().
'&id='.
$object->id.
'&lineid='.$objp->rowid.
'">';
$id
Support class for third parties, contacts, members, users or resources.
if(! $sortfield) if(! $sortorder) $object
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 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...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
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.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
dolPrintHTML($s, $allowiframe=0)
Return a string (that can be on several lines) ready to be output on a HTML page.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
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)
Return value of a param into GET or POST supervariable.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
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.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
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,...
img_info($titlealt='default')
Show info logo.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $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.
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.