40require
'../main.inc.php';
41require_once DOL_DOCUMENT_ROOT.
'/core/lib/product.lib.php';
42require_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
43require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
44require_once DOL_DOCUMENT_ROOT.
'/product/dynamic_price/class/price_expression.class.php';
45require_once DOL_DOCUMENT_ROOT.
'/product/dynamic_price/class/price_parser.class.php';
46require_once DOL_DOCUMENT_ROOT.
'/core/class/extrafields.class.php';
59 require_once DOL_DOCUMENT_ROOT.
'/product/class/productcustomerprice.class.php';
65$langs->loadLangs(array(
'products',
'bills',
'companies',
'other'));
73$action =
GETPOST(
'action',
'aZ09');
74$cancel =
GETPOST(
'cancel',
'alpha');
77$search_soc =
GETPOST(
'search_soc');
80$fieldvalue = (!empty($id) ?
$id : (!empty($ref) ? $ref :
''));
81$fieldtype = (!empty($ref) ?
'ref' :
'rowid');
83 $socid = $user->socid;
87if ($id > 0 || !empty($ref)) {
95 $conf->global->PRODUIT_MULTIPRICES_LIMIT = 5;
99$hookmanager->initHooks(array(
'productpricecard',
'globalcard'));
102 if (
$object->type == $object::TYPE_PRODUCT) {
105 if (
$object->type == $object::TYPE_SERVICE) {
109 restrictedArea($user,
'produit|service', $fieldvalue,
'product&product',
'',
'', $fieldtype);
112$maxpricesupplier = 0;
115 $permissiontoadd =
$object->getRights()->creer;
117 $permissiontoadd = ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'));
129$parameters = array(
'id' => $id,
'ref' => $ref);
130$reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
135if (empty($reshook)) {
136 if (
GETPOST(
'button_removefilter_x',
'alpha') ||
GETPOST(
'button_removefilter.x',
'alpha') ||
GETPOST(
'button_removefilter',
'alpha')) {
140 if ($action ==
'setlabelsellingprice' && $user->admin) {
141 require_once DOL_DOCUMENT_ROOT.
'/core/lib/admin.lib.php';
142 $keyforlabel =
'PRODUIT_MULTIPRICES_LABEL'.GETPOST(
'pricelevel');
147 if (($action ==
'update_vat') && !$cancel && $permissiontoadd) {
148 $tva_tx_txt =
GETPOST(
'tva_tx',
'alpha');
150 $price_label =
GETPOST(
'price_label',
'alpha');
153 $tva_tx = $tva_tx_txt;
156 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
157 $vatratecode = $reg[1];
158 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
161 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
162 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
165 $localtax1_type =
'0';
166 $localtax2_type =
'0';
169 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
171 $vatratecode = $reg[1];
173 $sql =
"SELECT t.rowid, t.type_vat, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
174 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
175 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
176 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
177 $sql .=
" AND t.code = '".$db->escape($vatratecode).
"'";
178 $sql .=
" AND t.type_vat IN (0, 1)";
179 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
180 $resql =
$db->query($sql);
182 $obj =
$db->fetch_object($resql);
184 $npr = $obj->recuperableonly;
185 $localtax1 = $obj->localtax1;
186 $localtax2 = $obj->localtax2;
187 $localtax1_type = $obj->localtax1_type;
188 $localtax2_type = $obj->localtax2_type;
193 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
194 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
195 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
196 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
197 $sql .=
" AND t.code = ''";
198 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
199 $resql =
$db->query($sql);
201 $obj =
$db->fetch_object($resql);
203 $npr = $obj->recuperableonly;
204 $localtax1 = $obj->localtax1;
205 $localtax2 = $obj->localtax2;
206 $localtax1_type = $obj->localtax1_type;
207 $localtax2_type = $obj->localtax2_type;
212 $object->default_vat_code = $vatratecode;
215 $object->localtax1_tx = $localtax1;
216 $object->localtax2_tx = $localtax2;
217 $object->localtax1_type = $localtax1_type;
218 $object->localtax2_type = $localtax2_type;
219 $object->price_label = $price_label;
231 $produit_multiprices_limit =
getDolGlobalInt(
'PRODUIT_MULTIPRICES_LIMIT');
232 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
234 if (
$object->multiprices_base_type[$i] ==
'HT') {
235 $oldprice =
$object->multiprices[$i];
236 $oldminprice =
$object->multiprices_min[$i];
238 $oldprice =
$object->multiprices_ttc[$i];
239 $oldminprice =
$object->multiprices_min_ttc[$i];
241 $oldpricebasetype =
$object->multiprices_base_type[$i];
242 $oldnpr =
$object->multiprices_recuperableonly[$i];
245 $localtaxarray = array();
247 $ret =
$object->updatePrice($oldprice, $oldpricebasetype, $user, (
float) $tva_tx, $oldminprice, $level, $oldnpr, 0, 0, $localtaxarray, $vatratecode, $price_label);
256 if (
$object->price_base_type ==
'HT') {
258 $oldminprice =
$object->price_min;
260 $oldprice =
$object->price_ttc;
261 $oldminprice =
$object->price_min_ttc;
263 $oldpricebasetype =
$object->price_base_type;
267 $localtaxarray = array();
269 $ret =
$object->updatePrice($oldprice, $oldpricebasetype, $user, (
float) $tva_tx, $oldminprice, $level, $oldnpr, 0, 0, $localtaxarray, $vatratecode, $price_label);
287 $maxpricesupplier = 0;
289 if (($action ==
'update_price' || $action ==
'update_level_price') && !$cancel && $permissiontoadd) {
291 $pricestoupdate = array();
296 $maxpricesupplier =
$object->min_recommended_price();
302 $object->fk_price_expression = empty($eid) ? 0 : $eid;
304 if (
$object->fk_price_expression != 0) {
306 require_once DOL_DOCUMENT_ROOT.
'/product/dynamic_price/class/price_parser.class.php';
309 if ($priceparser->parseProduct($object) < 0) {
318 || ($action ==
'update_level_price' &&
getDolGlobalString(
'PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')))) {
319 $newprice =
GETPOST(
'price',
'array');
320 $newprice_min =
GETPOST(
'price_min',
'array');
321 $newpricebase =
GETPOST(
'multiprices_base_type',
'array');
322 $newvattx =
GETPOST(
'tva_tx',
'array');
323 $newvatnpr =
GETPOST(
'tva_npr',
'array');
324 $newlocaltax1_tx =
GETPOST(
'localtax1_tx',
'array');
325 $newlocaltax1_type =
GETPOST(
'localtax1_type',
'array');
326 $newlocaltax2_tx =
GETPOST(
'localtax2_tx',
'array');
327 $newlocaltax2_type =
GETPOST(
'localtax2_type',
'array');
330 $object->price_autogen = (int) (
GETPOST(
'usePriceRules') ==
'on');
332 $produit_multiprices_limit =
getDolGlobalInt(
'PRODUIT_MULTIPRICES_LIMIT');
333 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
334 if (!isset($newprice[$i])) {
338 $tva_tx_txt = $newvattx[$i];
340 $tva_tx = $tva_tx_txt;
343 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
344 $vat_src_code = $reg[1];
345 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
347 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
349 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
350 $localtax1 = $newlocaltax1_tx[$i];
351 $localtax1_type = $newlocaltax1_type[$i];
352 $localtax2 = $newlocaltax2_tx[$i];
353 $localtax2_type = $newlocaltax2_type[$i];
354 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
356 $vatratecode = $reg[1];
358 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
359 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
360 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
361 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
362 $sql .=
" AND t.code ='".$db->escape($vatratecode).
"'";
363 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
364 $resql =
$db->query($sql);
366 $obj =
$db->fetch_object($resql);
368 $npr = $obj->recuperableonly;
369 $localtax1 = $obj->localtax1;
370 $localtax2 = $obj->localtax2;
371 $localtax1_type = $obj->localtax1_type;
372 $localtax2_type = $obj->localtax2_type;
376 if (in_array(
$mysoc->country_code, array(
'ES'))) {
383 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
384 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
385 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
386 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
387 $sql .=
" AND t.code = ''";
388 $resql =
$db->query($sql);
390 $obj =
$db->fetch_object($resql);
392 $npr = $obj->recuperableonly;
393 $localtax1 = $obj->localtax1;
394 $localtax2 = $obj->localtax2;
395 $localtax1_type = $obj->localtax1_type;
396 $localtax2_type = $obj->localtax2_type;
401 $pricestoupdate[$i] = array(
403 'price' =>
price2num($newprice[$i],
'', 2),
404 'price_min' =>
price2num($newprice_min[$i],
'', 2),
405 'price_base_type' => $newpricebase[$i],
406 'default_vat_code' => $vatratecode,
409 'localtaxes_array' => array(
'0' => $localtax1_type,
'1' => $localtax1,
'2' => $localtax2_type,
'3' => $localtax2)
420 $newpricebase =
GETPOST(
'price_base_type',
'alpha');
421 $tva_tx_txt =
GETPOST(
'tva_tx',
'alpha');
422 $price_label =
GETPOST(
'price_label',
'alpha');
424 $tva_tx = $tva_tx_txt;
427 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
428 $vat_src_code = $reg[1];
429 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
431 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
433 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
436 $localtax1_type =
'0';
437 $localtax2_type =
'0';
439 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
441 $vatratecode = $reg[1];
443 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
444 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
445 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
446 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
447 $sql .=
" AND t.code ='".$db->escape($vatratecode).
"'";
448 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
449 $resql =
$db->query($sql);
451 $obj =
$db->fetch_object($resql);
453 $npr = $obj->recuperableonly;
454 $localtax1 = $obj->localtax1;
455 $localtax2 = $obj->localtax2;
456 $localtax1_type = $obj->localtax1_type;
457 $localtax2_type = $obj->localtax2_type;
461 if (in_array(
$mysoc->country_code, array(
'ES'))) {
468 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
469 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
470 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
471 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
472 $sql .=
" AND t.code = ''";
473 $resql =
$db->query($sql);
475 $obj =
$db->fetch_object($resql);
477 $npr = $obj->recuperableonly;
478 $localtax1 = $obj->localtax1;
479 $localtax2 = $obj->localtax2;
480 $localtax1_type = $obj->localtax1_type;
481 $localtax2_type = $obj->localtax2_type;
486 $pricestoupdate[0] = array(
487 'price' => $newprice,
488 'price_label' => $price_label,
489 'price_min' => $newprice_min,
490 'price_base_type' => $newpricebase,
491 'default_vat_code' => $vatratecode,
494 'localtaxes_array' => array(
'0' => $localtax1_type,
'1' => $localtax1,
'2' => $localtax2_type,
'3' => $localtax2)
503 $object->packaging = (float) $packaging;
506 foreach ($pricestoupdate as $key => $val) {
507 $newprice = $val[
'price'];
509 if ($val[
'price'] < $val[
'price_min'] && !empty(
$object->fk_price_expression)) {
510 $newprice = $val[
'price_min'];
514 $newprice_min =
price2num($val[
'price_min'],
'MU');
517 if (
getDolGlobalString(
'PRODUCT_MINIMUM_RECOMMENDED_PRICE') && $newprice_min < $maxpricesupplier) {
518 setEventMessages($langs->trans(
"MinimumPriceLimit",
price($maxpricesupplier, 0,
'', 1, - 1, - 1,
'auto')),
null,
'errors');
523 if (!array_key_exists($key,
$object->multiprices) ||
$object->multiprices[$key] != $newprice ||
$object->multiprices_min[$key] != $newprice_min ||
$object->multiprices_base_type[$key] != $val[
'price_base_type'] ||
$object->multiprices_tva_tx[$key] != $newvattx) {
524 $res =
$object->updatePrice((
float) $newprice, $val[
'price_base_type'], $user, (
float) $val[
'vat_tx'], (
float) $newprice_min, $key, $val[
'npr'], $psq, 0, $val[
'localtaxes_array'], $val[
'default_vat_code'], $val[
'price_label']);
536 $price_extralabels = $extrafields->fetch_name_optionals_label(
"product_price");
538 $sql =
"SELECT rowid";
539 $sql .=
" FROM ".$object->db->prefix().
"product_price";
540 $sql .=
" WHERE entity IN (".getEntity(
'productprice').
")";
541 $sql .=
" AND price_level=".((int) $key);
542 $sql .=
" AND fk_product = ".((int)
$object->id);
543 $sql .=
" ORDER BY date_price DESC, rowid DESC";
545 $resql =
$object->db->query($sql);
547 $lineid =
$object->db->fetch_object($resql);
550 if (!empty($lineid->rowid)) {
551 require_once DOL_DOCUMENT_ROOT .
'/core/class/genericobject.class.php';
554 $genericObject->id = $lineid->rowid;
555 $genericObject->table_element =
'product_price';
556 foreach ($price_extralabels as $code => $label) {
557 $extrafield_values = $extrafields->getOptionalsFromPost(
'product_price', (
string) $key);
558 $genericObject->array_options[
'options_'.$code] = $extrafield_values[
'options_'.$code];
560 $result = $genericObject->insertExtraFields();
581 $action =
'edit_price';
587 if ($action ==
'delete' && $user->hasRight(
'produit',
'supprimer')) {
595 if ($action ==
'activate_price_by_qty' && $permissiontoadd) {
600 $ret =
$object->updatePrice($basePrice,
$object->price_base_type, $user,
$object->tva_tx, $basePriceMin, $level,
$object->tva_npr, 1, 0, array(),
$object->default_vat_code);
607 if ($action ==
'disable_price_by_qty' && $permissiontoadd) {
612 $ret =
$object->updatePrice($basePrice,
$object->price_base_type, $user,
$object->tva_tx, $basePriceMin, $level,
$object->tva_npr, 0, 0, array(),
$object->default_vat_code);
619 if ($action ==
'edit_price_by_qty') {
624 if ($action ==
'update_price_by_qty' && $permissiontoadd) {
634 if (empty($quantity)) {
636 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentities(
"Qty")),
null,
'errors');
638 if (empty($newprice)) {
640 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentities(
"Price")),
null,
'errors');
644 if (
$object->price_base_type ==
'TTC') {
649 $unitPrice =
price2num((
float) $price / (
float) $quantity,
'MU');
653 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"product_price_by_qty SET";
654 $sql .=
" price=".((float) $price).
",";
655 $sql .=
" unitprice=".((float) $unitPrice).
",";
656 $sql .=
" quantity=".((float) $quantity).
",";
657 $sql .=
" remise_percent=".((float) $remise_percent).
",";
658 $sql .=
" remise=".((float) $remise);
659 $sql .=
" WHERE rowid = ".((int) $rowid);
661 $result =
$db->query($sql);
666 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"product_price_by_qty (fk_product_price,price,unitprice,quantity,remise_percent,remise) values (";
667 $sql .= ((int) $priceid).
','.((float) $price).
','.((float) $unitPrice).
','.((float) $quantity).
','.((float) $remise_percent).
','.((float) $remise).
')';
669 $result =
$db->query($sql);
671 if (
$db->lasterrno() ==
'DB_ERROR_RECORD_ALREADY_EXISTS') {
681 if ($action ==
'delete_price_by_qty' && $permissiontoadd) {
683 if (!empty($rowid)) {
684 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"product_price_by_qty";
685 $sql .=
" WHERE rowid = ".((int) $rowid);
687 $result =
$db->query($sql);
689 setEventMessages((
'delete_price_by_qty'.$langs->transnoentities(
'MissingIds')),
null,
'errors');
693 if ($action ==
'delete_all_price_by_qty' && $permissiontoadd) {
695 if (!empty($priceid)) {
696 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"product_price_by_qty";
697 $sql .=
" WHERE fk_product_price = ".((int) $priceid);
699 $result =
$db->query($sql);
701 setEventMessages((
'delete_price_by_qty'.$langs->transnoentities(
'MissingIds')),
null,
'errors');
710 if ($action ==
'add_customer_price_confirm' && !$cancel && $prodcustprice !==
null && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
711 $maxpricesupplier =
$object->min_recommended_price();
713 $update_child_soc =
GETPOSTINT(
'updatechildprice');
717 $prodcustprice->ref_customer =
GETPOST(
'ref_customer',
'alpha');
718 $prodcustprice->fk_product =
$object->id;
721 $prodcustprice->price_base_type =
GETPOST(
"price_base_type",
'alpha');
722 $prodcustprice->price_label =
GETPOST(
"price_label",
'alpha');
727 $extralabels = $extrafields->fetch_name_optionals_label(
"product_customer_price");
728 $extrafield_values = $extrafields->getOptionalsFromPost(
"product_customer_price");
730 $tva_tx_txt =
GETPOST(
"tva_tx",
'alpha');
732 $tva_tx = $tva_tx_txt;
734 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
735 $vat_src_code = $reg[1];
736 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
738 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
740 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
743 $localtax1_type =
'0';
744 $localtax2_type =
'0';
746 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
748 $vatratecode = $reg[1];
750 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
751 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
752 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
753 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
754 $sql .=
" AND t.code ='".$db->escape($vatratecode).
"'";
755 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
756 $resql =
$db->query($sql);
758 $obj =
$db->fetch_object($resql);
760 $npr = $obj->recuperableonly;
761 $localtax1 = $obj->localtax1;
762 $localtax2 = $obj->localtax2;
763 $localtax1_type = $obj->localtax1_type;
764 $localtax2_type = $obj->localtax2_type;
768 if (in_array(
$mysoc->country_code, array(
'ES'))) {
775 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
776 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
777 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
778 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
779 $sql .=
" AND t.code = ''";
780 $resql =
$db->query($sql);
782 $obj =
$db->fetch_object($resql);
784 $npr = $obj->recuperableonly;
785 $localtax1 = $obj->localtax1;
786 $localtax2 = $obj->localtax2;
787 $localtax1_type = $obj->localtax1_type;
788 $localtax2_type = $obj->localtax2_type;
793 $prodcustprice->default_vat_code = $vatratecode;
794 $prodcustprice->tva_tx = $tva_tx;
795 $prodcustprice->recuperableonly = $npr;
796 $prodcustprice->localtax1_tx = $localtax1;
797 $prodcustprice->localtax2_tx = $localtax2;
798 $prodcustprice->localtax1_type = $localtax1_type;
799 $prodcustprice->localtax2_type = $localtax2_type;
801 if (!($prodcustprice->fk_soc > 0)) {
802 $langs->load(
"errors");
803 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"ThirdParty")),
null,
'errors');
805 $action =
'add_customer_price';
807 if (
getDolGlobalString(
'PRODUCT_MINIMUM_RECOMMENDED_PRICE') && $prodcustprice->price_min < (
float) $maxpricesupplier) {
808 $langs->load(
"errors");
809 setEventMessages($langs->trans(
"MinimumPriceLimit",
price((
float) $maxpricesupplier, 0,
'', 1, -1, -1,
'auto')),
null,
'errors');
811 $action =
'add_customer_price';
816 $result = $prodcustprice->create($user, 0, $update_child_soc);
818 if (!empty($extrafield_values) && is_array($extrafield_values)) {
820 $res = $productcustomerprice->fetch($prodcustprice->id);
822 foreach ($extrafield_values as $key => $value) {
823 $productcustomerprice->array_options[$key] = $value;
825 $result2 = $productcustomerprice->insertExtraFields();
827 $prodcustprice->error = $productcustomerprice->error;
828 $prodcustprice->errors = $productcustomerprice->errors;
837 $action =
'add_customer_price';
845 if ($action ==
'delete_customer_price' && $prodcustprice !==
null && ($user->hasRight(
'produit',
'supprimer') || $user->hasRight(
'service',
'supprimer'))) {
848 $result = $prodcustprice->delete($user);
851 $db->query(
"DELETE FROM ".MAIN_DB_PREFIX.
"product_customer_price_extrafields WHERE fk_object = ".((
int) $prodcustprice->id));
866 if ($action ==
'update_customer_price_confirm' && !$cancel && $prodcustprice !==
null && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
867 $maxpricesupplier =
$object->min_recommended_price();
869 $update_child_soc =
GETPOSTINT(
'updatechildprice');
874 $prodcustprice->ref_customer =
GETPOST(
'ref_customer',
'alpha');
877 $prodcustprice->price_base_type =
GETPOST(
"price_base_type",
'alpha');
878 $prodcustprice->price_label =
GETPOST(
"price_label",
'alpha');
883 $extralabels = $extrafields->fetch_name_optionals_label(
"product_customer_price");
884 $extrafield_values = $extrafields->getOptionalsFromPost(
"product_customer_price");
886 $tva_tx_txt =
GETPOST(
"tva_tx");
888 $tva_tx = $tva_tx_txt;
890 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
891 $vat_src_code = $reg[1];
892 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
894 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
896 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
899 $localtax1_type =
'0';
900 $localtax2_type =
'0';
902 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
904 $vatratecode = $reg[1];
906 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
907 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
908 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
909 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
910 $sql .=
" AND t.code ='".$db->escape($vatratecode).
"'";
911 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
912 $resql =
$db->query($sql);
914 $obj =
$db->fetch_object($resql);
916 $npr = $obj->recuperableonly;
917 $localtax1 = $obj->localtax1;
918 $localtax2 = $obj->localtax2;
919 $localtax1_type = $obj->localtax1_type;
920 $localtax2_type = $obj->localtax2_type;
924 if (in_array(
$mysoc->country_code, array(
'ES'))) {
931 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
932 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
933 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(
$mysoc->country_code).
"'";
934 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
935 $sql .=
" AND t.code = ''";
936 $resql =
$db->query($sql);
938 $obj =
$db->fetch_object($resql);
940 $npr = $obj->recuperableonly;
941 $localtax1 = $obj->localtax1;
942 $localtax2 = $obj->localtax2;
943 $localtax1_type = $obj->localtax1_type;
944 $localtax2_type = $obj->localtax2_type;
949 $prodcustprice->default_vat_code = $vatratecode;
950 $prodcustprice->tva_tx = $tva_tx;
951 $prodcustprice->recuperableonly = $npr;
952 $prodcustprice->localtax1_tx = $localtax1;
953 $prodcustprice->localtax2_tx = $localtax2;
954 $prodcustprice->localtax1_type = $localtax1_type;
955 $prodcustprice->localtax2_type = $localtax2_type;
957 if ($prodcustprice->price_min < $maxpricesupplier &&
getDolGlobalString(
'PRODUCT_MINIMUM_RECOMMENDED_PRICE')) {
958 setEventMessages($langs->trans(
"MinimumPriceLimit",
price($maxpricesupplier, 0,
'', 1, -1, -1,
'auto')),
null,
'errors');
960 $action =
'update_customer_price';
964 $result = $prodcustprice->update($user, 0, $update_child_soc);
966 if (!empty($extrafield_values) && is_array($extrafield_values)) {
968 $res = $productcustomerprice->fetch($prodcustprice->id);
970 foreach ($extrafield_values as $key => $value) {
971 $productcustomerprice->array_options[$key] = $value;
973 $result2 = $productcustomerprice->insertExtraFields();
975 $prodcustprice->error = $productcustomerprice->error;
976 $prodcustprice->errors = $productcustomerprice->errors;
985 $action =
'update_customer_price';
1001if (!empty($id) || !empty($ref)) {
1006$title = $langs->trans(
'ProductServiceCard');
1010 $title = $langs->trans(
'Product').
" ".$shortlabel.
" - ".$langs->trans(
'SellingPrices');
1011 $helpurl =
'EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos';
1014 $title = $langs->trans(
'Service').
" ".$shortlabel.
" - ".$langs->trans(
'SellingPrices');
1015 $helpurl =
'EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios';
1018llxHeader(
'', $title, $helpurl,
'', 0, 0,
'',
'',
'',
'classforhorizontalscrolloftabs mod-product page-price');
1021$titre = $langs->trans(
"CardProduct".
$object->type);
1026$linkback =
'<a href="'.DOL_URL_ROOT.
'/product/list.php?restore_lastsearch_values=1&type='.
$object->type.
'">'.$langs->trans(
"BackToList").
'</a>';
1027$object->next_prev_filter =
"(te.fk_product_type:=:".((int)
$object->type).
")";
1030if ($user->socid && !in_array(
'product', explode(
',',
getDolGlobalString(
'MAIN_MODULES_FOR_EXTERNAL')))) {
1034dol_banner_tab($object,
'ref', $linkback, $shownav,
'ref');
1037print
'<div class="fichecenter">';
1039print
'<div class="underbanner clearboth"></div>';
1040print
'<table class="border tableforfield centpercent">';
1047 if (!empty($socid)) {
1050 $soc->fetch($socid);
1054 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
1055 print
'<tr><td class="">';
1056 print (!
getDolGlobalString(
'PRODUCT_DENY_CHANGE_PRODUCT_TYPE')) ? $form->editfieldkey(
"Type",
'fk_product_type', (
string)
$object->type, $object, 0, $typeformat) : $langs->trans(
'Type');
1058 print $form->editfieldval(
"Type",
'fk_product_type',
$object->type, $object, 0, $typeformat);
1063 print
'<tr><td class="titlefieldcreate">';
1064 print $langs->trans(
"SellingPrice");
1066 print
'<td colspan="2">';
1067 if (
$object->multiprices_base_type[$soc->price_level] ==
'TTC') {
1068 print
'<span class="amount">'.price(
$object->multiprices_ttc[$soc->price_level]).
'</span>';
1070 print
'<span class="amount">'.price(
$object->multiprices[$soc->price_level]).
'</span>';
1072 if (
$object->multiprices_base_type[$soc->price_level]) {
1073 print
' '.$langs->trans(
$object->multiprices_base_type[$soc->price_level]);
1075 print
' '.$langs->trans(
$object->price_base_type);
1080 print
'<tr><td>'.$langs->trans(
"MinPrice").
'</td><td colspan="2">';
1081 if (
$object->multiprices_base_type[$soc->price_level] ==
'TTC') {
1082 print
price(
$object->multiprices_min_ttc[$soc->price_level]).
' '.$langs->trans(
$object->multiprices_base_type[$soc->price_level]);
1084 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]);
1090 print
'<tr><td>'.$langs->trans(
"DefaultTaxRate").
'</td><td colspan="2">';
1092 $positiverates =
'';
1094 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->multiprices_tva_tx[$soc->price_level]);
1097 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->multiprices_localtax1_tx[$soc->price_level]);
1100 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->multiprices_localtax2_tx[$soc->price_level]);
1102 if (empty($positiverates)) {
1103 $positiverates =
'0';
1105 echo
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr);
1110 print
'<tr><td>'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1112 $positiverates =
'';
1117 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax1_tx);
1120 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax2_tx);
1122 if (empty($positiverates)) {
1123 $positiverates =
'0';
1125 echo
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr);
1133 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
1134 print
'<tr><td class="">';
1135 print (!
getDolGlobalString(
'PRODUCT_DENY_CHANGE_PRODUCT_TYPE')) ? $form->editfieldkey(
"Type",
'fk_product_type', (
string)
$object->type, $object, 0, $typeformat) : $langs->trans(
'Type');
1137 print $form->editfieldval(
"Type",
'fk_product_type',
$object->type, $object, 0, $typeformat);
1142 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"DefaultTaxRate").
'</td>';
1143 print
'<td colspan="2">'.vatrate(
$object->multiprices_tva_tx[1],
true).
'</td>';
1148 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
1149 print
'<tr><td class="">';
1150 print (!
getDolGlobalString(
'PRODUCT_DENY_CHANGE_PRODUCT_TYPE')) ? $form->editfieldkey(
"Type",
'fk_product_type', (
string)
$object->type, $object, 0, $typeformat) : $langs->trans(
'Type');
1152 print $form->editfieldval(
"Type",
'fk_product_type',
$object->type, $object, 0, $typeformat);
1157 print
'<!-- Default VAT Rate -->';
1158 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1161 $positiverates =
'';
1163 $positiverates .= ($positiverates ?
'<span class="opacitymedium">/</span>' :
'').
price2num(
$object->tva_tx);
1166 $positiverates .= ($positiverates ?
'<span class="opacitymedium">/</span>' :
'').
price2num(
$object->localtax1_tx);
1169 $positiverates .= ($positiverates ?
'<span class="opacitymedium">/</span>' :
'').
price2num(
$object->localtax2_tx);
1171 if (empty($positiverates)) {
1172 $positiverates =
'0';
1175 print
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr, 1);
1188 print
'<table class="liste centpercent">';
1189 print
'<tr class="liste_titre"><td>';
1190 print $langs->trans(
"PriceLevel");
1192 print
' <a class="editfielda" href="'.dolBuildUrl($_SERVER[
"PHP_SELF"], [
'action' =>
'editlabelsellingprice',
'id' =>
$object->id],
true).
'">'.
img_edit($langs->trans(
'EditSellingPriceLabel'), 0).
'</a>';
1195 print
'<td style="text-align: right">'.$langs->trans(
"SellingPrice").
'</td>';
1196 print
'<td style="text-align: right">'.$langs->trans(
"MinPrice").
'</td>';
1198 $extrafields->fetch_name_optionals_label(
"product_price");
1199 if ($extrafields->attributes[
"product_price"] && array_key_exists(
'label', $extrafields->attributes[
"product_price"])) {
1200 $extralabels = $extrafields->attributes[
"product_price"][
'label'];
1201 if (!empty($extralabels)) {
1202 foreach ($extralabels as $key => $value) {
1204 if (!empty($extrafields->attributes[
"product_price"][
'list'][$key]) && $extrafields->attributes[
"product_price"][
'list'][$key] != 3) {
1205 if (!empty($extrafields->attributes[
"product_price"][
'langfile'][$key])) {
1206 $langs->load($extrafields->attributes[
"product_price"][
'langfile'][$key]);
1208 if (!empty($extrafields->attributes[
"product_price"][
'help'][$key])) {
1209 $extratitle = $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_price"][
'help'][$key]));
1211 $extratitle = $langs->trans($value);
1213 $field =
'ef.' . $key;
1214 print
'<td style="text-align: right">'.$extratitle.
'</td>';
1221 $produit_multiprices_limit =
getDolGlobalInt(
'PRODUIT_MULTIPRICES_LIMIT');
1222 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
1223 print
'<tr class="oddeven">';
1227 $keyforlabel =
'PRODUIT_MULTIPRICES_LABEL'.$i;
1228 if (preg_match(
'/editlabelsellingprice/', $action)) {
1229 print
'<form method="post" action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'">';
1230 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1231 print
'<input type="hidden" name="action" value="setlabelsellingprice">';
1232 print
'<input type="hidden" name="pricelevel" value="'.$i.
'">';
1233 print $langs->trans(
"SellingPrice").
' '.$i.
' - ';
1234 print
'<input class="maxwidthonsmartphone" type="text" name="labelsellingprice" value="' .
getDolGlobalString($keyforlabel).
'">';
1235 print
' <input type="submit" class="button smallpaddingimp" value="'.$langs->trans(
"Modify").
'">';
1238 print $langs->trans(
"SellingPrice").
' '.$i;
1245 if (
$object->multiprices_base_type [$i] ==
'TTC') {
1246 print
'<td class="right"><span class="amount">'.price(
$object->multiprices_ttc[$i]);
1248 print
'<td class="right"><span class="amount">'.price(
$object->multiprices[$i]);
1251 if (
$object->multiprices_base_type[$i]) {
1252 print
' '.$langs->trans(
$object->multiprices_base_type [$i]).
'</span></td>';
1254 print
' '.$langs->trans(
$object->price_base_type).
'</span></td>';
1258 print
'<td style="text-align: right">';
1259 if (empty(
$object->multiprices_base_type[$i])) {
1260 $object->multiprices_base_type[$i] =
"HT";
1262 if (
$object->multiprices_base_type[$i] ==
'TTC') {
1263 print
price(
$object->multiprices_min_ttc[$i]).
' '.$langs->trans(
$object->multiprices_base_type[$i]);
1265 print
price(
$object->multiprices_min[$i]).
' '.$langs->trans(
$object->multiprices_base_type[$i]);
1268 if (!empty($extralabels)) {
1269 require_once DOL_DOCUMENT_ROOT .
'/core/class/genericobject.class.php';
1272 $genericObject->table_element =
'product_price';
1273 $sql1 =
"SELECT rowid";
1274 $sql1 .=
" FROM ".$object->db->prefix().
"product_price";
1275 $sql1 .=
" WHERE entity IN (".getEntity(
'productprice').
")";
1276 $sql1 .=
" AND price_level=".((int) $i);
1277 $sql1 .=
" AND fk_product = ".((int)
$object->id);
1278 $sql1 .=
" ORDER BY date_price DESC, rowid DESC";
1279 $sql1 .=
" LIMIT 1";
1280 $resql1 =
$object->db->query($sql1);
1281 if ($resql1 && $lineid =
$object->db->fetch_object($resql1)) {
1282 $genericObject->id = $lineid->rowid;
1283 $genericObject->fetch_optionals();
1285 foreach ($extralabels as $key => $value) {
1286 if (!empty($extrafields->attributes[
"product_price"][
'list'][$key]) && $extrafields->attributes[
"product_price"][
'list'][$key] != 3) {
1287 print
'<td align="right">'.$extrafields->showOutputField($key, $genericObject->array_options[
'options_' . $key],
'',
'product_price').
"</td>";
1296 print
'<tr><td>'.$langs->trans(
"PriceByQuantity").
' '.$i;
1300 print
'</td><td colspan="2">';
1302 if (
$object->prices_by_qty[$i] == 1) {
1303 print
'<table width="50%" class="border" summary="List of quantities">';
1305 print
'<tr class="liste_titre">';
1306 print
'<td>'.$langs->trans(
"PriceByQuantityRange").
' '.$i.
'</td>';
1307 print
'<td class="right">'.$langs->trans(
"HT").
'</td>';
1308 print
'<td class="right">'.$langs->trans(
"UnitPrice").
'</td>';
1309 print
'<td class="right">'.$langs->trans(
"Discount").
'</td>';
1310 print
'<td> </td>';
1313 foreach (
$object->prices_by_qty_list[$i] as $ii => $prices) {
1314 if ($action ==
'edit_price_by_qty' && $rowid == $prices[
'rowid'] && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1315 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1316 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1317 print
'<input type="hidden" name="action" value="update_price_by_qty">';
1318 print
'<input type="hidden" name="priceid" value="'.$object->prices_by_qty_id[$i].
'">';
1319 print
'<input type="hidden" value="'.$prices[
'rowid'].
'" name="rowid">';
1320 print
'<tr class="'.($ii % 2 == 0 ?
'pair' :
'impair').
'">';
1321 print
'<td><input size="5" type="text" value="'.$prices[
'quantity'].
'" name="quantity"></td>';
1322 print
'<td class="right" colspan="2"><input size="10" type="text" value="'.price2num($prices[
'price'],
'MU').
'" name="price"> '.
$object->price_base_type.
'</td>';
1323 print
'<td class="right nowraponall"><input size="5" type="text" value="'.$prices[
'remise_percent'].
'" name="remise_percent"> %</td>';
1324 print
'<td class="center"><input type="submit" value="'.$langs->trans(
"Modify").
'" class="button"></td>';
1328 print
'<tr class="'.($ii % 2 == 0 ?
'pair' :
'impair').
'">';
1329 print
'<td>'.$prices[
'quantity'].
'</td>';
1330 print
'<td class="right">'.price($prices[
'price']).
'</td>';
1331 print
'<td class="right">'.price($prices[
'unitprice']).
'</td>';
1332 print
'<td class="right">'.price($prices[
'remise_percent']).
' %</td>';
1333 print
'<td class="center">';
1334 if (($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1335 print
'<a class="editfielda marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=edit_price_by_qty&token='.newToken().
'&rowid='.$prices[
"rowid"].
'">';
1337 print
'<a class="marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=delete_price_by_qty&token='.newToken().
'&rowid='.$prices[
"rowid"].
'">';
1346 if ($action !=
'edit_price_by_qty' && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1347 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1348 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1349 print
'<input type="hidden" name="action" value="update_price_by_qty">';
1350 print
'<input type="hidden" name="priceid" value="'.$object->prices_by_qty_id[$i].
'">';
1351 print
'<input type="hidden" value="0" name="rowid">';
1352 print
'<tr class="'.($ii % 2 == 0 ?
'pair' :
'impair').
'">';
1353 print
'<td><input size="5" type="text" value="1" name="quantity"></td>';
1354 print
'<td class="right" class="nowrap"><input size="10" type="text" value="0" name="price"> '.$object->price_base_type.
'</td>';
1355 print
'<td class="right"> </td>';
1356 print
'<td class="right" class="nowraponall"><input size="5" type="text" value="0" name="remise_percent"> %</td>';
1357 print
'<td class="center"><input type="submit" value="'.$langs->trans(
"Add").
'" class="button"></td>';
1363 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>';
1365 print $langs->trans(
"No");
1366 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>';
1375 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
1376 print
'<tr><td class="">';
1377 print (!
getDolGlobalString(
'PRODUCT_DENY_CHANGE_PRODUCT_TYPE')) ? $form->editfieldkey(
"Type",
'fk_product_type', (
string)
$object->type, $object, 0, $typeformat) : $langs->trans(
'Type');
1379 print $form->editfieldval(
"Type",
'fk_product_type',
$object->type, $object, 0, $typeformat);
1384 print
'<tr><td class="titlefield">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1386 $positiverates =
'';
1391 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax1_tx);
1394 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax2_tx);
1396 if (empty($positiverates)) {
1397 $positiverates =
'0';
1399 echo
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr, 0, 1);
1409 print
'<tr class="field_selling_price"><td>'.$langs->trans(
"SellingPrice").
'</td><td>';
1410 if (
$object->price_base_type ==
'TTC') {
1415 print
'<i class="opacitymedium"> - ' .
price(
$object->price_ttc).
' '.$langs->trans(
'TTC') .
'</i>';
1422 print
'<tr class="field_min_price"><td>'.$langs->trans(
"MinPrice").
'</td><td>';
1423 if (
$object->price_base_type ==
'TTC') {
1428 print
'<i class="opacitymedium"> - ' .
price(
$object->price_min_ttc).
' '.$langs->trans(
'TTC') .
'</i>';
1435 print
'<tr class="field_price_label"><td>'.$form->textwithpicto($langs->trans(
"PackagingForThisProduct"), $langs->trans(
"PackagingForThisProductDesc")).
'</td><td>';
1441 print
'<tr class="field_price_label"><td>'.$langs->trans(
"PriceLabel").
'</td><td>';
1448 print
'<tr><td>'.$langs->trans(
"PriceByQuantity");
1449 if (
$object->prices_by_qty[0] == 0) {
1450 print
' <a href="'.$_SERVER[
'PHP_SELF'].
'?id='.
$object->id.
'&action=activate_price_by_qty&level=1&token='.newToken().
'">('.$langs->trans(
"Activate").
')';
1452 print
' <a href="'.$_SERVER[
'PHP_SELF'].
'?id='.
$object->id.
'&action=disable_price_by_qty&level=1&token='.newToken().
'">('.$langs->trans(
"DisablePriceByQty").
')';
1456 if (
$object->prices_by_qty[0] == 1) {
1457 print
'<table width="50%" class="border" summary="List of quantities">';
1458 print
'<tr class="liste_titre">';
1460 print
'<td>'.$langs->trans(
"Quantity").
'</td>';
1461 print
'<td class="right">'.$langs->trans(
"Price").
'</td>';
1462 print
'<td class="right"></td>';
1463 print
'<td class="right">'.$langs->trans(
"UnitPrice").
'</td>';
1464 print
'<td class="right">'.$langs->trans(
"Discount").
'</td>';
1465 print
'<td> </td>';
1467 if ($action !=
'edit_price_by_qty') {
1468 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1469 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1470 print
'<input type="hidden" name="action" value="update_price_by_qty">';
1471 print
'<input type="hidden" name="priceid" value="'.$object->prices_by_qty_id[0].
'">';
1472 print
'<input type="hidden" value="0" name="rowid">';
1474 print
'<tr class="'.(($ii % 2) == 0 ?
'pair' :
'impair').
'">';
1475 print
'<td><input size="5" type="text" value="1" name="quantity"></td>';
1476 print
'<td class="right"><input class="width50 right" type="text" value="0" name="price"></td>';
1480 print
'<td class="right"> </td>';
1481 print
'<td class="right nowraponall"><input type="text" class="width50 right" value="0" name="remise_percent"> %</td>';
1482 print
'<td class="center"><input type="submit" value="'.$langs->trans(
"Add").
'" class="button"></td>';
1487 foreach (
$object->prices_by_qty_list[0] as $ii => $prices) {
1488 if ($action ==
'edit_price_by_qty' && $rowid == $prices[
'rowid'] && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1489 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1490 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1491 print
'<input type="hidden" name="action" value="update_price_by_qty">';
1492 print
'<input type="hidden" name="priceid" value="'.$object->prices_by_qty_id[0].
'">';
1493 print
'<input type="hidden" value="'.$prices[
'rowid'].
'" name="rowid">';
1494 print
'<tr class="'.($ii % 2 == 0 ?
'pair' :
'impair').
'">';
1495 print
'<td><input size="5" type="text" value="'.$prices[
'quantity'].
'" name="quantity"></td>';
1496 print
'<td class="right"><input class="width50 right" type="text" value="'.price2num($prices[
'price'],
'MU').
'" name="price"></td>';
1497 print
'<td class="right">';
1499 print $prices[
'price_base_type'];
1501 print
'<td class="right"> </td>';
1502 print
'<td class="right nowraponall"><input class="width50 right" type="text" value="'.$prices[
'remise_percent'].
'" name="remise_percent"> %</td>';
1503 print
'<td class="center"><input type="submit" value="'.$langs->trans(
"Modify").
'" class="button"></td>';
1507 print
'<tr class="'.($ii % 2 == 0 ?
'pair' :
'impair').
'">';
1508 print
'<td>'.$prices[
'quantity'].
'</td>';
1509 print
'<td class="right">'.price($prices[
'price']).
'</td>';
1510 print
'<td class="right">';
1512 print $prices[
'price_base_type'];
1514 print
'<td class="right">'.price($prices[
'unitprice']).
'</td>';
1515 print
'<td class="right">'.price($prices[
'remise_percent']).
' %</td>';
1516 print
'<td class="center">';
1517 if (($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1518 print
'<a class="editfielda marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=edit_price_by_qty&token='.newToken().
'&rowid='.$prices[
"rowid"].
'">';
1520 print
'<a class="marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=delete_price_by_qty&token='.newToken().
'&rowid='.$prices[
"rowid"].
'">';
1531 print $langs->trans(
"No");
1540print
'<div class="clearboth"></div>';
1549if (!$action || $action ==
'delete' || $action ==
'showlog_customer_price' || $action ==
'showlog_default_price' || $action ==
'add_customer_price'
1550 || $action ==
'activate_price_by_qty' || $action ==
'disable_price_by_qty') {
1551 print
"\n".
'<div class="tabsAction">'.
"\n";
1553 $parameters = array();
1554 $reshook = $hookmanager->executeHooks(
'addMoreActionsButtons', $parameters, $object, $action);
1555 if (empty($reshook)) {
1558 print
'<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' .
dol_escape_htmltag($langs->trans(
"NoEditVariants")) .
'">' . $langs->trans(
"UpdateDefaultPrice") .
'</a></div>';
1562 if ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer')) {
1563 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>';
1565 print
'<div class="inline-block divButAction"><span class="butActionRefused" title="'.dol_escape_htmltag($langs->trans(
"NotEnoughPermissions")).
'">' . $langs->trans(
"UpdateDefaultPrice") .
'</span></div>';
1570 if ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer')) {
1571 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>';
1573 print
'<div class="inline-block divButAction"><span class="butActionRefused" title="'.dol_escape_htmltag($langs->trans(
"NotEnoughPermissions")).
'">' . $langs->trans(
"AddCustomerPrice") .
'</span></div>';
1578 if ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer')) {
1579 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>';
1581 print
'<div class="inline-block divButAction"><span class="butActionRefused" title="'.dol_escape_htmltag($langs->trans(
"NotEnoughPermissions")).
'">' . $langs->trans(
"UpdateVAT") .
'</span></div>';
1584 if ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer')) {
1585 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>';
1587 print
'<div class="inline-block divButAction"><span class="butActionRefused" title="'.dol_escape_htmltag($langs->trans(
"NotEnoughPermissions")).
'">' . $langs->trans(
"UpdateLevelPrices") .
'</span></div>';
1602if ($action ==
'edit_vat' && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1605 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1606 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1607 print
'<input type="hidden" name="action" value="update_vat">';
1608 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
1612 print
'<table class="border centpercent">';
1615 print
'<tr><td>'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1623 print $form->buttonsSaveCancel();
1625 print
'<br></form><br>';
1628if (($action ==
'edit_price' || $action ==
'edit_level_price') &&
$object->getRights()->creer) {
1633 print
'<!-- Edit price -->'.
"\n";
1634 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1635 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1636 print
'<input type="hidden" name="action" value="update_price">';
1637 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
1641 print
'<div class="div-table-responsive-no-min">';
1642 print
'<table class="border centpercent">';
1645 print
'<tr><td class="titlefield">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1651 print $langs->trans(
'PriceBase');
1654 print $form->selectPriceBaseType(
$object->price_base_type,
"price_base_type");
1661 print
'<!-- Show price mode of dynamicprices editor -->'.
"\n";
1662 print
'<tr><td>'.$langs->trans(
"PriceMode").
'</td><td>';
1663 print
img_picto(
'',
'dynamicprice',
'class="pictofixedwidth"');
1665 $price_expression_list = array(0 => $langs->trans(
"Numeric").
' <span class="opacitymedium">('.$langs->trans(
"NoDynamicPrice").
')</span>');
1666 foreach ($price_expression->list_price_expression() as $entry) {
1667 $price_expression_list[$entry->id] = $entry->title;
1669 $price_expression_preselection =
GETPOST(
'eid') ?
GETPOST(
'eid') : (
$object->fk_price_expression ?
$object->fk_price_expression :
'0');
1670 print $form->selectarray(
'eid', $price_expression_list, $price_expression_preselection);
1671 print
' <a id="expression_editor" class="classlink">'.$langs->trans(
"PriceExpressionEditor").
'</a>';
1677 <script
type=
"text/javascript">
1678 jQuery(document).ready(
function() {
1679 jQuery(
"#expression_editor").click(
function() {
1680 window.location =
"<?php echo DOL_URL_ROOT ?>/product/dynamic_price/editor.php?id=<?php echo $id ?>&tab=price&eid=" + $(
"#eid").val();
1682 jQuery(
"#eid").change(on_change);
1685 function on_change() {
1686 if ($(
"#eid").val() == 0) {
1687 jQuery(
"#price_numeric").show();
1689 jQuery(
"#price_numeric").hide();
1698 $product->fetch($id, $ref,
'',
'1');
1699 print
'<tr id="price_numeric"><td>';
1700 $text = $langs->trans(
'SellingPrice');
1701 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
1703 if (
$object->price_base_type ==
'TTC') {
1704 print
'<input name="price" size="10" value="'.price($product->price_ttc).
'">';
1706 print
'<input name="price" size="10" value="'.price($product->price).
'">';
1712 $text = $langs->trans(
'MinPrice');
1713 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
1715 if (
$object->price_base_type ==
'TTC') {
1716 print
'<input name="price_min" size="10" value="'.($object->price_min_ttc ?
price(
$object->price_min_ttc) :
'').
'">';
1718 print
'<input name="price_min" size="10" value="'.($object->price_min ?
price(
$object->price_min) :
'').
'">';
1721 print
' '.$langs->trans(
"MinimumRecommendedPrice",
price((
float) $maxpricesupplier, 0,
'', 1, -1, -1,
'auto')).
' '.
img_warning().
'</td>';
1729 print $form->textwithpicto($langs->trans(
"PackagingForThisProduct"), $langs->trans(
"PackagingForThisProductDesc"));
1731 $packaging =
$object->packaging;
1732 print
'<input class="flat" name="packaging" size="5" value="' . ($packaging ?
price($packaging, 0,
'', 1, -1, 2) :
'').
'">';
1739 print $langs->trans(
'PriceLabel');
1741 print
'<input name="price_label" maxlength="255" class="minwidth300 maxwidth400onsmartphone" value="'.$object->price_label.
'">';
1745 $parameters = array();
1746 $reshook = $hookmanager->executeHooks(
'formObjectOptions', $parameters, $object, $action);
1753 print $form->buttonsSaveCancel();
1756 } elseif ($action ==
'edit_level_price' &&
$object->getRights()->creer) {
1757 print
'<!-- Edit price per level -->'.
"\n"; ?>
1760 var showHidePriceRules =
function () {
1761 var otherPrices = $(
'div.fiche form table tbody tr:not(:first)');
1762 var minPrice1 = $(
'div.fiche form input[name="price_min[1]"]');
1764 if (jQuery(
'input#usePriceRules').prop(
'checked')) {
1773 jQuery(document).ready(
function () {
1774 showHidePriceRules();
1776 jQuery(
'input#usePriceRules').click(showHidePriceRules);
1781 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1782 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1783 print
'<input type="hidden" name="action" value="update_level_price">';
1784 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
1789 print $langs->trans(
'UseMultipriceRules').
' <input type="checkbox" id="usePriceRules" name="usePriceRules" '.(
$object->price_autogen ?
'checked' :
'').
'><br><br>';
1792 print
'<div class="div-table-responsive-no-min">';
1793 print
'<table class="noborder">';
1794 print
'<thead><tr class="liste_titre">';
1796 print
'<td>'.$langs->trans(
"PriceLevel").
'</td>';
1799 print
'<td style="text-align: center">'.$langs->trans(
"DefaultTaxRate").
'</td>';
1804 print
'<td class="center">'.$langs->trans(
"SellingPrice").
'</td>';
1806 print
'<td class="center">'.$langs->trans(
"MinPrice").
'</td>';
1813 $extrafields->fetch_name_optionals_label(
"product_price");
1814 if ($extrafields->attributes[
"product_price"] && array_key_exists(
'label', $extrafields->attributes[
"product_price"])) {
1815 $extralabels = $extrafields->attributes[
"product_price"][
'label'];
1816 if (!empty($extralabels)) {
1817 foreach ($extralabels as $key => $value) {
1819 if (!empty($extrafields->attributes[
"product_price"][
'list'][$key]) && $extrafields->attributes[
"product_price"][
'list'][$key] != 3) {
1820 if (!empty($extrafields->attributes[
"product_price"][
'langfile'][$key])) {
1821 $langs->load($extrafields->attributes[
"product_price"][
'langfile'][$key]);
1823 if (!empty($extrafields->attributes[
"product_price"][
'help'][$key])) {
1824 $extratitle = $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_price"][
'help'][$key]));
1826 $extratitle = $langs->trans($value);
1828 print
'<td style="text-align: right">'.$extratitle.
'</td>';
1833 print
'</tr></thead>';
1837 $produit_multiprices_limit =
getDolGlobalInt(
'PRODUIT_MULTIPRICES_LIMIT');
1838 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
1839 print
'<tr class="oddeven">';
1841 $keyforlabel =
'PRODUIT_MULTIPRICES_LABEL'.$i;
1843 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
1849 print
'<input type="hidden" name="tva_tx['.$i.
']" value="'.(
$object->default_vat_code ?
$object->tva_tx.
' ('.
$object->default_vat_code.
')' :
$object->tva_tx).
'">';
1850 print
'<input type="hidden" name="tva_npr['.$i.
']" value="'.
$object->tva_npr.
'">';
1851 print
'<input type="hidden" name="localtax1_tx['.$i.
']" value="'.
$object->localtax1_tx.
'">';
1852 print
'<input type="hidden" name="localtax1_type['.$i.
']" value="'.
$object->localtax1_type.
'">';
1853 print
'<input type="hidden" name="localtax2_tx['.$i.
']" value="'.
$object->localtax2_tx.
'">';
1854 print
'<input type="hidden" name="localtax2_type['.$i.
']" value="'.
$object->localtax2_type.
'">';
1858 print
'<td style="text-align: center">';
1864 print
'<td style="text-align: center">';
1865 if (
$object->multiprices_base_type [$i] ==
'TTC') {
1866 print
'<input name="price['.$i.
']" size="10" value="'.
price(
$object->multiprices_ttc [$i]).
'">';
1868 print
'<input name="price['.$i.
']" size="10" value="'.
price(
$object->multiprices [$i]).
'">';
1870 print
' '.$form->selectPriceBaseType(
$object->multiprices_base_type [$i],
"multiprices_base_type[".$i.
"]");
1874 print
'<td style="text-align: center">';
1875 if (
$object->multiprices_base_type [$i] ==
'TTC') {
1876 print
'<input name="price_min['.$i.
']" size="10" value="'.
price(
$object->multiprices_min_ttc [$i]).
'">';
1878 print
'<input name="price_min['.$i.
']" size="10" value="'.
price(
$object->multiprices_min [$i]).
'">';
1881 print
'<td class="left">'.$langs->trans(
"MinimumRecommendedPrice",
price((
float) $maxpricesupplier, 0,
'', 1, -1, -1,
'auto')).
' '.
img_warning().
'</td>';
1885 if (!empty($extralabels)) {
1886 require_once DOL_DOCUMENT_ROOT .
'/core/class/genericobject.class.php';
1889 $genericObject->table_element =
'product_price';
1890 $sql1 =
"SELECT rowid";
1891 $sql1 .=
" FROM ".$object->db->prefix().
"product_price";
1892 $sql1 .=
" WHERE entity IN (".getEntity(
'productprice').
")";
1893 $sql1 .=
" AND price_level=".((int) $i);
1894 $sql1 .=
" AND fk_product = ".((int)
$object->id);
1895 $sql1 .=
" ORDER BY date_price DESC, rowid DESC";
1896 $sql1 .=
" LIMIT 1";
1897 $resql1 =
$object->db->query($sql1);
1898 if ($resql1 && $lineid =
$object->db->fetch_object($resql1)) {
1899 $genericObject->id = $lineid->rowid;
1900 $genericObject->fetch_optionals();
1902 foreach ($extralabels as $key => $value) {
1903 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))) {
1904 if (!empty($extrafields->attributes[
"product_price"][
'langfile'][$key])) {
1905 $langs->load($extrafields->attributes[
"product_price"][
'langfile'][$key]);
1909 print
'<td align="center">';
1910 print $extrafields->showInputField($key, $genericObject->array_options[
'options_' . $key],
'', (
string) $i,
'',
'', $genericObject,
'product_price');
1926 print $form->buttonsSaveCancel();
1937 $sortfield =
GETPOST(
'sortfield',
'aZ09comma');
1938 $sortorder =
GETPOST(
'sortorder',
'aZ09comma');
1940 if (empty($page) || $page == -1) {
1943 $offset = $limit * $page;
1944 $pageprev = $page - 1;
1945 $pagenext = $page + 1;
1947 $sortorder =
"ASC,ASC";
1950 $sortfield =
"soc.nom,t.date_begin";
1954 $filter = array(
't.fk_product' => (
string)
$object->id);
1956 if (!empty($search_soc)) {
1957 $filter[
'soc.nom'] = (
string) $search_soc;
1960 if ($action ==
'add_customer_price') {
1962 $maxpricesupplier =
$object->min_recommended_price();
1964 print
'<!-- add_customer_price -->';
1967 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1968 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1969 print
'<input type="hidden" name="action" value="add_customer_price_confirm">';
1970 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
1972 print
'<div class="tabBar tabBarWithBottom">';
1974 print
'<table class="border centpercent">';
1976 print
'<td class="fieldrequired">'.$langs->trans(
'ThirdParty').
'</td>';
1978 $filter =
'(s.client:IN:1,2,3)';
1979 print
img_picto(
'',
'company').$form->select_company(
GETPOSTINT(
'socid'),
'socid', $filter,
'SelectThirdParty', 0, 0, array(), 0,
'minwidth300');
1984 print
'<tr><td>' . $langs->trans(
'RefCustomer') .
'</td>';
1985 print
'<td><input name="ref_customer" size="12"></td></tr>';
1989 print
'<tr><td>'.$langs->trans(
"AppliedPricesFrom").
'</td><td>';
1990 print $form->selectDate(!empty($date_begin) ? $date_begin :
dol_now(),
"date_begin", 0, 0, 1,
"date_begin");
1995 print
'<tr><td>'.$langs->trans(
"AppliedPricesTo").
'</td><td>';
1996 print $form->selectDate($date_end,
"date_end", 0, 0, 1,
"date_end");
2000 print
'<tr><td class="fieldrequired">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
2005 print
'<tr><td class="fieldrequired">';
2006 print $langs->trans(
'PriceBase');
2009 print $form->selectPriceBaseType(
$object->price_base_type,
"price_base_type");
2014 print
'<tr><td class="fieldrequired">';
2015 $text = $langs->trans(
'SellingPrice');
2016 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
2018 if (
$object->price_base_type ==
'TTC') {
2019 print
'<input name="price" size="10" value="'.price(
$object->price_ttc).
'">';
2021 print
'<input name="price" size="10" value="'.price(
$object->price).
'">';
2027 $text = $langs->trans(
'MinPrice');
2028 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
2029 if (
$object->price_base_type ==
'TTC') {
2030 print
'<td><input name="price_min" size="10" value="'.price(
$object->price_min_ttc).
'">';
2032 print
'<td><input name="price_min" size="10" value="'.price(
$object->price_min).
'">';
2035 print
'<td class="left">'.$langs->trans(
"MinimumRecommendedPrice",
price($maxpricesupplier, 0,
'', 1, -1, -1,
'auto')).
' '.
img_warning().
'</td>';
2041 print $langs->trans(
'PriceLabel');
2043 print
'<input name="price_label" maxlength="255" class="minwidth300 maxwidth400onsmartphone" value="'.$object->price_label.
'">';
2049 print
'<tr><td>'.$langs->trans(
"Discount").
'</td><td>';
2050 print
'<input name="discount_percent" size="10" value="'.price($discount_percent).
'">';
2054 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2055 $extralabels = !empty($extrafields->attributes[
"product_customer_price"][
'label']) ? $extrafields->attributes[
"product_customer_price"][
'label'] :
'';
2056 $extrafield_values = $extrafields->getOptionalsFromPost(
"product_customer_price");
2057 if (!empty($extralabels)) {
2058 if (empty($prodcustprice->id)) {
2059 foreach ($extralabels as $key => $value) {
2060 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))) {
2061 if (!empty($extrafields->attributes[
"product_customer_price"][
'langfile'][$key])) {
2062 $langs->load($extrafields->attributes[
"product_customer_price"][
'langfile'][$key]);
2065 print
'<tr><td'.($extrafields->attributes[
"product_customer_price"][
'required'][$key] ?
' class="fieldrequired"' :
'').
'>';
2066 if (!empty($extrafields->attributes[
"product_customer_price"][
'help'][$key])) {
2067 print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_customer_price"][
'help'][$key]));
2069 print $langs->trans($value);
2071 print
'</td><td>'.$extrafields->showInputField($key, GETPOSTISSET(
'options_'.$key) ? $extrafield_values[
'options_'.$key] :
'',
'',
'',
'',
'', 0,
'product_customer_price').
'</td></tr>';
2082 print
'<div class="center">';
2085 print
'<div class="marginbottomonly">';
2086 print
'<input type="checkbox" name="updatechildprice" id="updatechildprice" value="1"> ';
2087 print
'<label for="updatechildprice">'.$langs->trans(
'ForceUpdateChildPriceSoc').
'</label>';
2090 print $form->buttonsSaveCancel();
2093 } elseif ($action ==
'edit_customer_price') {
2095 $maxpricesupplier =
$object->min_recommended_price();
2097 print
'<!-- edit_customer_price -->';
2100 $result = $prodcustprice->fetch(
GETPOSTINT(
'lineid'));
2105 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
2106 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2107 print
'<input type="hidden" name="action" value="update_customer_price_confirm">';
2108 print
'<input type="hidden" name="lineid" value="'.$prodcustprice->id.
'">';
2110 print
'<table class="liste centpercent">';
2112 print
'<td class="titlefield fieldrequired">'.$langs->trans(
'ThirdParty').
'</td>';
2114 $staticsoc->fetch($prodcustprice->fk_soc);
2115 print
"<td>".$staticsoc->getNomUrl(1).
"</td>";
2119 print
'<tr><td>' . $langs->trans(
'RefCustomer') .
'</td>';
2120 print
'<td><input name="ref_customer" size="12" value="' .
dol_escape_htmltag($prodcustprice->ref_customer) .
'"></td></tr>';
2123 print
'<tr><td>'.$langs->trans(
"AppliedPricesFrom").
'</td><td>';
2124 print $form->selectDate($prodcustprice->date_begin,
"date_begin", 0, 0, 1,
"date_begin");
2128 print
'<tr><td>'.$langs->trans(
"AppliedPricesTo").
'</td><td>';
2129 print $form->selectDate($prodcustprice->date_end,
"date_end", 0, 0, 1,
"date_end");
2133 print
'<tr><td class="fieldrequired">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
2134 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);
2138 print
'<tr><td class="fieldrequired">';
2139 print $langs->trans(
'PriceBase');
2142 print $form->selectPriceBaseType($prodcustprice->price_base_type,
"price_base_type");
2147 print
'<tr><td class="fieldrequired">';
2148 $text = $langs->trans(
'SellingPrice');
2149 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
2151 if ($prodcustprice->price_base_type ==
'TTC') {
2152 print
'<input name="price" size="10" value="'.price($prodcustprice->price_ttc).
'">';
2154 print
'<input name="price" size="10" value="'.price($prodcustprice->price).
'">';
2160 $text = $langs->trans(
'MinPrice');
2161 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
2163 if ($prodcustprice->price_base_type ==
'TTC') {
2164 print
'<input name="price_min" size="10" value="'.price($prodcustprice->price_min_ttc).
'">';
2166 print
'<input name="price_min" size="10" value="'.price($prodcustprice->price_min).
'">';
2170 print
'<td class="left">'.$langs->trans(
"MinimumRecommendedPrice",
price($maxpricesupplier, 0,
'', 1, -1, -1,
'auto')).
' '.
img_warning().
'</td>';
2176 print $langs->trans(
'PriceLabel');
2178 print
'<input name="price_label" maxlength="255" class="minwidth300 maxwidth400onsmartphone" value="'.$prodcustprice->price_label.
'">';
2183 print
'<tr><td>'.$langs->trans(
"Discount").
'</td><td>';
2184 print
'<input name="discount_percent" size="10" value="'.price($prodcustprice->discount_percent).
'">';
2188 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2189 $extralabels = !empty($extrafields->attributes[
"product_customer_price"][
'label']) ? $extrafields->attributes[
"product_customer_price"][
'label'] :
'';
2190 $extrafield_values = $extrafields->getOptionalsFromPost(
"product_customer_price");
2191 if (!empty($extralabels)) {
2193 foreach ($extralabels as $key => $value) {
2194 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && ($extrafields->attributes[
"product_customer_price"][
'list'][$key] == 1 || $extrafields->attributes[
"product_customer_price"][
'list'][$key] == 3 || ($action ==
"edit_price" && $extrafields->attributes[
"product_customer_price"][
'list'][$key] == 4))) {
2195 if (!empty($extrafields->attributes[
"product_customer_price"][
'langfile'][$key])) {
2196 $langs->load($extrafields->attributes[
"product_customer_price"][
'langfile'][$key]);
2199 print
'<tr><td'.($extrafields->attributes[
"product_customer_price"][
'required'][$key] ?
' class="fieldrequired"' :
'').
'>';
2200 if (!empty($extrafields->attributes[
"product_customer_price"][
'help'][$key])) {
2201 print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_customer_price"][
'help'][$key]));
2203 print $langs->trans($value);
2205 print
'</td><td>'.$extrafields->showInputField($key, GETPOSTISSET(
'options_'.$key) ? $extrafield_values[
'options_'.$key] :
'',
'',
'',
'',
'', 0,
'product_customer_price').
'</td></tr>';
2210 $sql .=
" fk_object";
2211 foreach ($extralabels as $key => $value) {
2212 $sql .=
", ".$db->sanitize($key);
2214 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product_customer_price_extrafields";
2215 $sql .=
" WHERE fk_object = ".((int) $prodcustprice->id);
2216 $resql =
$db->query($sql);
2218 $obj =
$db->fetch_object($resql);
2219 foreach ($extralabels as $key => $value) {
2220 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && ($extrafields->attributes[
"product_customer_price"][
'list'][$key] == 1 || $extrafields->attributes[
"product_customer_price"][
'list'][$key] == 3 || ($action ==
"edit_price" && $extrafields->attributes[
"product_customer_price"][
'list'][$key] == 4))) {
2221 if (!empty($extrafields->attributes[
"product_customer_price"][
'langfile'][$key])) {
2222 $langs->load($extrafields->attributes[
"product_customer_price"][
'langfile'][$key]);
2225 print
'<tr><td'.($extrafields->attributes[
"product_customer_price"][
'required'][$key] ?
' class="fieldrequired"' :
'').
'>';
2226 if (!empty($extrafields->attributes[
"product_customer_price"][
'help'][$key])) {
2227 print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_customer_price"][
'help'][$key]));
2229 print $langs->trans($value);
2231 print
'</td><td>'.$extrafields->showInputField($key, GETPOSTISSET(
'options_'.$key) ? $extrafield_values[
'options_'.$key] : $obj->{$key},
'',
'',
'',
'', 0,
'product_customer_price');
2243 print
'<div class="center">';
2244 print
'<div class="marginbottomonly">';
2245 print
'<input type="checkbox" name="updatechildprice" id="updatechildprice" value="1"> ';
2246 print
'<label for="updatechildprice">'.$langs->trans(
'ForceUpdateChildPriceSoc').
'</label>';
2249 print $form->buttonsSaveCancel();
2251 print
'<br></form>';
2252 } elseif ($action ==
'showlog_customer_price') {
2254 print
'<!-- list of all log of prices per customer -->'.
"\n";
2256 $sortfield =
't.datec';
2257 $filter = array(
't.fk_product' => (
string)
$object->id,
't.fk_soc' => (
string)
GETPOSTINT(
'socid'));
2260 $nbtotalofrecords =
'';
2262 $nbtotalofrecords = $prodcustprice->fetchAllLog($sortorder, $sortfield,
$conf->liste_limit, $offset, $filter);
2265 $result = $prodcustprice->fetchAllLog($sortorder, $sortfield,
$conf->liste_limit, $offset, $filter);
2270 $option =
'&socid='.GETPOSTINT(
'socid').
'&id='.
$object->id;
2275 $title = $langs->trans(
'PriceByCustomerLog');
2276 $title .=
' - '.$staticsoc->getNomUrl(1);
2278 $backbutton =
'<a class="justalink" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'">'.$langs->trans(
"GoBack").
'</a>';
2281 print_barre_liste($title, $page, $_SERVER[
'PHP_SELF'], $option, $sortfield, $sortorder, $backbutton, count($prodcustprice->lines), $nbtotalofrecords,
'title_accountancy.png');
2283 if (count($prodcustprice->lines) > 0) {
2284 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
2285 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2286 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
2288 print
'<div class="div-table-responsive-no-min">';
2289 print
'<table class="liste centpercent">';
2291 print
'<tr class="liste_titre">';
2292 print
'<td>'.$langs->trans(
"ThirdParty").
'</td>';
2293 print
'<td>'.$langs->trans(
'RefCustomer').
'</td>';
2294 print
'<td>'.$langs->trans(
"AppliedPricesFrom").
'</td>';
2295 print
'<td>'.$langs->trans(
"AppliedPricesTo").
'</td>';
2296 print
'<td class="center">'.$langs->trans(
"PriceBase").
'</td>';
2297 print
'<td class="right">'.$langs->trans(
"DefaultTaxRate").
'</td>';
2298 print
'<td class="right">'.$langs->trans(
"HT").
'</td>';
2299 print
'<td class="right">'.$langs->trans(
"TTC").
'</td>';
2300 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2301 print
'<td class="right">'.$langs->trans(
"INCT").
'</td>';
2303 print
'<td class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"HT").
'</td>';
2304 print
'<td class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"TTC").
'</td>';
2305 print
'<td class="right">'.$langs->trans(
"PriceLabel").
'</td>';
2306 print
'<td class="right">'.$langs->trans(
"Discount").
'</td>';
2307 print
'<td class="right">'.$langs->trans(
"ChangedBy").
'</td>';
2308 print
'<td>'.$langs->trans(
"DateCreation").
'</td>';
2311 foreach ($prodcustprice->lines as $line) {
2314 $staticsoc->fetch($line->fk_soc);
2316 $tva_tx = $line->default_vat_code ? $line->tva_tx.
' ('.$line->default_vat_code.
')' : $line->tva_tx;
2319 if ($line->price_base_type ==
'HT') {
2322 $pu = $line->price_ttc;
2326 $localtaxarray =
getLocalTaxesFromRate($line->tva_tx.($line->default_vat_code ?
' ('.$line->default_vat_code.
')' :
''), 0, $staticsoc,
$mysoc);
2328 $resultarray =
calcul_price_total(1, $pu, 0, (
float) $line->tva_tx, 1, 1, 0, $line->price_base_type, $line->recuperableonly,
$object->type,
$mysoc, $localtaxarray);
2330 $total_ht = $resultarray[0];
2331 $total_vat = $resultarray[1];
2332 $total_localtax1 = $resultarray[9];
2333 $total_localtax2 = $resultarray[10];
2334 $total_ttc = $resultarray[2];
2336 print
'<tr class="oddeven">';
2338 print
'<td class="tdoverflowmax125">'.$staticsoc->getNomUrl(1).
"</td>";
2339 print
'<td>'.$line->ref_customer.
'</td>';
2340 print
"<td>".dol_print_date($line->date_begin,
"day",
'tzuserrel').
"</td>";
2341 print
"<td>".dol_print_date($line->date_end,
"day",
'tzuserrel').
"</td>";
2342 print
'<td class="center">'.$langs->trans($line->price_base_type).
"</td>";
2343 print
'<td class="right nowraponall">';
2345 $positiverates =
'';
2347 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->tva_tx);
2350 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->localtax1_tx);
2353 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->localtax2_tx);
2355 if (empty($positiverates)) {
2356 $positiverates =
'0';
2359 echo
vatrate($positiverates.($line->default_vat_code ?
' ('.$line->default_vat_code.
')' :
''), true, ($line->tva_npr ? $line->tva_npr : $line->recuperableonly));
2363 print
'<td class="right"><span class="amount">'.price($line->price).
"</span></td>";
2365 print
'<td class="right"><span class="amount">'.price($line->price_ttc).
"</span></td>";
2366 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2367 print
'<td class="right">'.price($resultarray[2]).
'</td>';
2370 print
'<td class="right">'.price($line->price_min).
'</td>';
2371 print
'<td class="right">'.price($line->price_min_ttc).
'</td>';
2372 print
'<td class="right">'.dolPrintHTML($line->price_label).
'</td>';
2373 print
'<td class="right">'.price($line->discount_percent).
'</td>';
2376 print
'<td class="tdoverflowmax125">';
2378 if ($line->fk_user > 0) {
2380 $userstatic->fetch($line->fk_user);
2381 print $userstatic->getNomUrl(1,
'', 0, 0, 24, 0,
'login');
2385 print
"<td>".dol_print_date($line->datec,
"dayhour",
'tzuserrel').
"</td>";
2391 print $langs->trans(
'None');
2393 } elseif ($action !=
'showlog_default_price' && $action !=
'edit_price' && $action !=
'edit_level_price') {
2395 print
'<!-- list of all prices per customer -->'.
"\n";
2398 $nbtotalofrecords =
'';
2400 $nbtotalofrecords = $prodcustprice->fetchAll($sortorder, $sortfield, 0, 0, $filter);
2403 $result = $prodcustprice->fetchAll($sortorder, $sortfield,
$conf->liste_limit, $offset, $filter);
2408 $option =
'&search_soc='.$search_soc.
'&id='.
$object->id;
2411 print_barre_liste($langs->trans(
'PriceByCustomer'), $page, $_SERVER [
'PHP_SELF'], $option, $sortfield, $sortorder,
'', count($prodcustprice->lines), $nbtotalofrecords,
'title_accountancy.png');
2413 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
2414 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2415 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
2417 print
'<!-- List of prices per customer -->'.
"\n";
2418 print
'<div class="div-table-responsive-no-min">'.
"\n";
2419 print
'<table class="liste centpercent">'.
"\n";
2421 if (count($prodcustprice->lines) > 0 || $search_soc) {
2422 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2423 $custom_price_extralabels = !empty($extrafields->attributes[
"product_customer_price"][
'label']) ? $extrafields->attributes[
"product_customer_price"][
'label'] :
'';
2429 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2432 if (!empty($custom_price_extralabels) && is_array($custom_price_extralabels)) {
2433 $colspan += count($custom_price_extralabels);
2436 print
'<tr class="liste_titre">';
2437 print
'<td class="liste_titre"><input type="text" class="flat maxwidth125" name="search_soc" value="'.$search_soc.
'"></td>';
2438 print
'<td class="liste_titre" colspan="'.$colspan.
'"> </td>';
2440 print
'<td class="liste_titre maxwidthsearch">';
2441 $searchpicto = $form->showFilterAndCheckAddButtons(0);
2447 print
'<tr class="liste_titre">';
2448 print
'<td>'.$langs->trans(
"ThirdParty").
'</td>';
2449 print
'<td>'.$langs->trans(
'RefCustomer').
'</td>';
2450 print
'<td>'.$langs->trans(
"AppliedPricesFrom").
'</td>';
2451 print
'<td>'.$langs->trans(
"AppliedPricesTo").
'</td>';
2452 print
'<td class="center">'.$langs->trans(
"PriceBase").
'</td>';
2453 print
'<td class="right">'.$langs->trans(
"DefaultTaxRate").
'</td>';
2454 print
'<td class="right">'.$langs->trans(
"HT").
'</td>';
2455 print
'<td class="right">'.$langs->trans(
"TTC").
'</td>';
2456 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2457 print
'<td class="right">'.$langs->trans(
"INCT").
'</td>';
2459 print
'<td class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"HT").
'</td>';
2460 print
'<td class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"TTC").
'</td>';
2461 print
'<td class="right">'.$langs->trans(
"PriceLabel").
'</td>';
2462 print
'<td class="right">'.$langs->trans(
"Discount").
'</td>';
2464 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2465 if ($extrafields->attributes[
"product_customer_price"] && array_key_exists(
'label', $extrafields->attributes[
"product_customer_price"])) {
2466 $extralabels = $extrafields->attributes[
"product_customer_price"][
'label'];
2467 if (!empty($extralabels)) {
2468 foreach ($extralabels as $key => $value) {
2470 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && $extrafields->attributes[
"product_customer_price"][
'list'][$key] != 3) {
2471 if (!empty($extrafields->attributes[
"product_customer_price"][
'langfile'][$key])) {
2472 $langs->load($extrafields->attributes[
"product_customer_price"][
'langfile'][$key]);
2474 if (!empty($extrafields->attributes[
"product_customer_price"][
'help'][$key])) {
2475 $extratitle = $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_customer_price"][
'help'][$key]));
2477 $extratitle = $langs->trans($value);
2479 print
'<td style="text-align: right">'.$extratitle.
'</td>';
2484 print
'<td>'.$langs->trans(
"ChangedBy").
'</td>';
2489 if (
$object->price_base_type ==
'HT') {
2498 $resultarray =
calcul_price_total(1, $pu, 0,
$object->tva_tx, 1, 1, 0,
$object->price_base_type, 0,
$object->type,
$mysoc, $localtaxarray);
2500 $total_ht = $resultarray[0];
2501 $total_vat = $resultarray[1];
2502 $total_localtax1 = $resultarray[9];
2503 $total_localtax2 = $resultarray[10];
2504 $total_ttc = $resultarray[2];
2507 print
'<!-- PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES -->'.
"\n";
2508 print
'<tr class="oddeven">';
2509 print
'<td colspan="4">' . $langs->trans(
'Default') .
'</td>';
2511 print
'<td class="center">'.$langs->trans(
$object->price_base_type).
"</td>";
2514 print
'<td class="right nowraponall">';
2516 $positiverates =
'';
2521 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax1_tx);
2524 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax2_tx);
2526 if (empty($positiverates)) {
2527 $positiverates =
'0';
2529 echo
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr);
2533 print
'<td class="right"><span class="amount">'.price(
$object->price).
"</span></td>";
2535 print
'<td class="right"><span class="amount">'.price(
$object->price_ttc).
"</span></td>";
2536 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2538 print
'<td class="right"><span class="amount">'.price($resultarray[2]).
'</span></td>';
2541 print
'<td class="right">'.price(
$object->price_min).
'</td>';
2542 print
'<td class="right">'.price(
$object->price_min_ttc).
'</td>';
2543 print
'<td class="right">'.dolPrintHTML(
$object->price_label).
'</td>';
2544 print
'<td class="right"></td>';
2545 print
'<td class="right"></td>';
2546 if (!empty($extralabels)) {
2547 foreach ($extralabels as $key) {
2549 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && $extrafields->attributes[
"product_customer_price"][
'list'][$key] != 3) {
2550 print
'<td class="right"></td>';
2554 if ($user->hasRight(
'produit',
'supprimer') || $user->hasRight(
'service',
'supprimer')) {
2555 print
'<td class="nowraponall">';
2556 print
'<a class="marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?action=showlog_default_price&token='.newToken().
'&id='.
$object->id.
'">';
2557 print
img_info($langs->trans(
'PriceByCustomerLog'));
2560 print
'<a class="marginleftonly marginrightonly editfielda" href="'.$_SERVER[
"PHP_SELF"].
'?action=edit_price&token='.newToken().
'&id='.
$object->id.
'">';
2561 print
img_edit(
'default', 0,
'style="vertical-align: middle;"');
2568 if (count($prodcustprice->lines) > 0) {
2569 foreach ($prodcustprice->lines as $line) {
2572 $staticsoc->fetch($line->fk_soc);
2574 $tva_tx = $line->default_vat_code ? $line->tva_tx.
' ('.$line->default_vat_code.
')' : $line->tva_tx;
2577 if ($line->price_base_type ==
'HT') {
2580 $pu = $line->price_ttc;
2584 $localtaxarray =
getLocalTaxesFromRate($line->tva_tx.($line->default_vat_code ?
' ('.$line->default_vat_code.
')' :
''), 0, $staticsoc,
$mysoc);
2586 $resultarray =
calcul_price_total(1, $pu, 0, (
float) $line->tva_tx, 1, 1, 0, $line->price_base_type, $line->recuperableonly,
$object->type,
$mysoc, $localtaxarray);
2588 $total_ht = $resultarray[0];
2589 $total_vat = $resultarray[1];
2590 $total_localtax1 = $resultarray[9];
2591 $total_localtax2 = $resultarray[10];
2592 $total_ttc = $resultarray[2];
2594 print
'<tr class="oddeven">';
2596 print
'<td class="tdoverflowmax125">'.$staticsoc->getNomUrl(1).
"</td>";
2597 print
'<td>'.dolPrintHTML($line->ref_customer).
'</td>';
2598 print
"<td>".dol_print_date($line->date_begin,
"day",
'tzuserrel').
"</td>";
2599 print
"<td>".dol_print_date($line->date_end,
"day",
'tzuserrel').
"</td>";
2600 print
'<td class="center">'.$langs->trans($line->price_base_type).
"</td>";
2602 print
'<td class="right nowraponall">';
2604 $positiverates =
'';
2606 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->tva_tx);
2609 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->localtax1_tx);
2612 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->localtax2_tx);
2614 if (empty($positiverates)) {
2615 $positiverates =
'0';
2618 echo
vatrate($positiverates.($line->default_vat_code ?
' ('.$line->default_vat_code.
')' :
''), true, (!empty($line->tva_npr) ? $line->tva_npr : $line->recuperableonly));
2622 print
'<td class="right"><span class="amount">'.price($line->price).
"</span></td>";
2624 print
'<td class="right"><span class="amount">'.price($line->price_ttc).
"</span></td>";
2625 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2627 print
'<td class="right"><span class="amount">'.price($resultarray[2]).
'</span></td>';
2630 print
'<td class="right">'.price($line->price_min).
'</td>';
2631 print
'<td class="right">'.price($line->price_min_ttc).
'</td>';
2632 print
'<td class="right">'.dolPrintHTMLForAttribute($line->price_label).
'</td>';
2633 print
'<td class="right">'.price($line->discount_percent).
'</td>';
2636 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2637 $extralabels = $extrafields->attributes[
"product_customer_price"][
'label'] ?? array();
2638 if (!empty($extralabels)) {
2640 $sql .=
" fk_object";
2641 foreach ($extralabels as $key => $value) {
2642 $sql .=
", ".$db->sanitize($key);
2644 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product_customer_price_extrafields";
2645 $sql .=
" WHERE fk_object = ".((int) $line->id);
2646 $resql =
$db->query($sql);
2648 if (
$db->num_rows($resql) != 1) {
2649 foreach ($extralabels as $key => $value) {
2650 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && $extrafields->attributes[
"product_customer_price"][
'list'][$key] != 3) {
2655 $obj =
$db->fetch_object($resql);
2656 foreach ($extralabels as $key => $value) {
2657 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && $extrafields->attributes[
"product_customer_price"][
'list'][$key] != 3) {
2658 print
'<td align="right">'.$extrafields->showOutputField($key, $obj->{$key},
'',
'product_customer_price').
"</td>";
2667 print
'<td class="tdoverflowmax125">';
2668 if ($line->fk_user > 0) {
2670 $userstatic->fetch($line->fk_user);
2672 print $userstatic->getNomUrl(-1,
'', 0, 0, 24, 0,
'login');
2678 print
'<td class="right nowraponall">';
2679 if ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer')) {
2680 print
'<a href="'.$_SERVER[
"PHP_SELF"].
'?action=showlog_customer_price&token='.newToken().
'&id='.
$object->id.
'&socid='.$line->fk_soc.
'">';
2681 print
img_info($langs->trans(
'PriceByCustomerLog'));
2684 print
'<a class="marginleftonly editfielda" href="'.$_SERVER[
"PHP_SELF"].
'?action=edit_customer_price&token='.newToken().
'&id='.
$object->id.
'&lineid='.$line->id.
'">';
2685 print
img_edit(
'default', 0,
'style="vertical-align: middle;"');
2689 if ($user->hasRight(
'produit',
'supprimer') || $user->hasRight(
'service',
'supprimer')) {
2690 print
'<a class="marginleftonly" href="'.$_SERVER[
"PHP_SELF"].
'?action=delete_customer_price&token='.newToken().
'&id='.
$object->id.
'&lineid='.$line->id.
'">';
2691 print
img_delete(
'default',
'style="vertical-align: middle;"');
2709if ((!
getDolGlobalString(
'PRODUIT_CUSTOMER_PRICES') || $action ==
'showlog_default_price') && !in_array($action, array(
'edit_price',
'edit_level_price',
'edit_vat'))) {
2710 $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,";
2711 $sql .=
" p.price_level, p.price_min, p.price_min_ttc,p.price_by_qty,";
2712 $sql .=
" p.date_price as dp, p.fk_price_expression, u.rowid as user_id, u.login";
2713 $sql .=
" ,p.price_label";
2714 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product_price as p,";
2715 $sql .=
" ".MAIN_DB_PREFIX.
"user as u";
2716 $sql .=
" WHERE fk_product = ".((int)
$object->id);
2717 $sql .=
" AND p.entity IN (".getEntity(
'productprice').
")";
2718 $sql .=
" AND p.fk_user_author = u.rowid";
2720 $sql .=
" AND p.price_level = ".((int) $soc->price_level);
2722 $sql .=
" ORDER BY p.date_price DESC, p.rowid DESC, p.price_level ASC";
2726 $result =
$db->query($sql);
2728 print
'<div class="divlogofpreviouscustomerprice">';
2730 $num =
$db->num_rows($result);
2739 $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);
2741 $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);
2747 $result =
$db->query($sql);
2748 $num =
$db->num_rows($result);
2755 $backbutton =
'<a class="justalink" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'">'.$langs->trans(
"GoBack").
'</a>';
2759 print_barre_liste($langs->trans(
"DefaultPriceLog"), 0, $_SERVER[
"PHP_SELF"],
'',
'',
'', $backbutton, 0, $num,
'title_accountancy.png');
2762 print_barre_liste($langs->trans(
"PriceByCustomerLog"), 0, $_SERVER[
"PHP_SELF"],
'',
'',
'',
'', 0, $num,
'title_accountancy.png');
2765 print
'<!-- List of log prices -->'.
"\n";
2766 print
'<div class="div-table-responsive">'.
"\n";
2767 print
'<table class="liste centpercent noborder">'.
"\n";
2769 print
'<tr class="liste_titre">';
2770 print
'<th>'.$langs->trans(
"AppliedPricesFrom").
'</tg>';
2773 print
'<th class="center">'.$langs->trans(
"PriceLevel").
'</th>';
2776 print
'<th class="center">'.$langs->trans(
"Type").
'</th>';
2779 print
'<th class="center">'.$langs->trans(
"PriceBase").
'</th>';
2781 print
'<th class="right">'.$langs->trans(
"DefaultTaxRate").
'</th>';
2783 print
'<th class="right">'.$langs->trans(
"HT").
'</th>';
2784 print
'<th class="right">'.$langs->trans(
"TTC").
'</th>';
2785 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2786 print
'<th class="right">'.$langs->trans(
"INCT").
'</th>';
2789 print
'<th class="right">'.$langs->trans(
"PriceExpressionSelected").
'</th>';
2791 print
'<th class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"HT").
'</th>';
2792 print
'<th class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"TTC").
'</th>';
2793 print
'<th class="right">'.$langs->trans(
"Label").
'</th>';
2794 print
'<th>'.$langs->trans(
"ChangedBy").
'</th>';
2795 if ($user->hasRight(
'produit',
'supprimer')) {
2796 print
'<th class="right"> </th>';
2800 $notfirstlineforlevel = array();
2804 $objp =
$db->fetch_object($result);
2806 print
'<tr class="oddeven">';
2808 print
"<td>".dol_print_date(
$db->jdate($objp->dp),
"dayhour",
'tzuserrel').
"</td>";
2812 print
'<td class="center">'.$objp->price_level.
"</td>";
2816 $type = ($objp->price_by_qty == 1) ?
'PriceByQuantity' :
'Standard';
2817 print
'<td class="center">'.$langs->trans($type).
"</td>";
2820 print
'<td class="center">';
2821 if (empty($objp->price_by_qty)) {
2822 print $langs->trans($objp->price_base_type);
2827 print
'<td class="right">';
2829 if (empty($objp->price_by_qty)) {
2830 $positiverates =
'';
2832 $positiverates .= ($positiverates ?
'/' :
'').
price2num($objp->tva_tx);
2835 $positiverates .= ($positiverates ?
'/' :
'').
price2num($objp->localtax1_tx);
2838 $positiverates .= ($positiverates ?
'/' :
'').
price2num($objp->localtax2_tx);
2840 if (empty($positiverates)) {
2841 $positiverates =
'0';
2843 echo
vatrate($positiverates.($objp->default_vat_code ?
' ('.$objp->default_vat_code.
')' :
''), true, !empty($objp->tva_npr) ? $objp->tva_npr : 0);
2856 if ($objp->price_base_type ==
'HT') {
2859 $pu = $objp->price_ttc;
2865 $resultarray =
calcul_price_total(1, $pu, 0, $objp->tva_tx, 1, 1, 0, $objp->price_base_type, $objp->recuperableonly,
$object->type,
$mysoc, $localtaxarray);
2867 $total_ht = $resultarray[0];
2868 $total_vat = $resultarray[1];
2869 $total_localtax1 = $resultarray[9];
2870 $total_localtax2 = $resultarray[10];
2871 $total_ttc = $resultarray[2];
2874 if (!empty($objp->fk_price_expression) && !empty(
$conf->dynamicprices->enabled)) {
2876 $res = $price_expression->fetch($objp->fk_price_expression);
2877 $title = $price_expression->title;
2878 print
'<td class="right"></td>';
2879 print
'<td class="right"></td>';
2880 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2881 print
'<td class="right"></td>';
2883 print
'<td class="right">'.$title.
"</td>";
2886 print
'<td class="right">';
2887 if (empty($objp->price_by_qty)) {
2888 print
'<span class="amount">'.price($objp->price).
'</span>';
2892 print
'<td class="right">';
2893 if (empty($objp->price_by_qty)) {
2894 $price_ttc = $objp->price_ttc;
2895 print
'<span class="amount">'.price($price_ttc).
'<span>';
2898 if (
$mysoc->localtax1_assuj ==
"1" ||
$mysoc->localtax2_assuj ==
"1") {
2899 print
'<td class="right">';
2900 print $resultarray[2];
2904 print
'<td class="right"></td>';
2909 print
'<td class="right">';
2910 if (empty($objp->price_by_qty)) {
2911 print
price($objp->price_min);
2916 print
'<td class="right">';
2917 if (empty($objp->price_by_qty)) {
2918 $price_min_ttc = $objp->price_min_ttc;
2919 print
price($price_min_ttc);
2929 print
'<td class="tdoverflowmax125">';
2930 if ($objp->user_id > 0) {
2933 $userstatic->fetch($objp->user_id);
2934 print $userstatic->getNomUrl(-1,
'', 0, 0, 24, 0,
'login');
2939 if ($user->hasRight(
'produit',
'supprimer')) {
2942 if (empty($notfirstlineforlevel[$objp->price_level])) {
2943 $notfirstlineforlevel[$objp->price_level] = 1;
2951 print
'<td class="right">';
2952 if ($candelete || (
$db->jdate($objp->dp) >=
dol_now())) {
2953 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 of a generic business object.
Class for accessing price expression table.
Class to parse product price expressions.
File of class to manage predefined price products or services by customer.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
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.
dolPrintHTML($s, $allowiframe=0, $moreallowedtags=array())
Return a string (that can be on several lines) ready to be output on a HTML page.
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.
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.
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...
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
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.