40require
'../main.inc.php';
41require_once DOL_DOCUMENT_ROOT.
'/core/lib/product.lib.php';
42require_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
43require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
44require_once DOL_DOCUMENT_ROOT.
'/product/dynamic_price/class/price_expression.class.php';
45require_once DOL_DOCUMENT_ROOT.
'/product/dynamic_price/class/price_parser.class.php';
46require_once DOL_DOCUMENT_ROOT.
'/core/class/extrafields.class.php';
59 require_once DOL_DOCUMENT_ROOT.
'/product/class/productcustomerprice.class.php';
65$langs->loadLangs(array(
'products',
'bills',
'companies',
'other'));
72$action =
GETPOST(
'action',
'aZ09');
73$cancel =
GETPOST(
'cancel',
'alpha');
76$search_soc =
GETPOST(
'search_soc');
79$fieldvalue = (!empty($id) ?
$id : (!empty($ref) ? $ref :
''));
80$fieldtype = (!empty($ref) ?
'ref' :
'rowid');
82 $socid = $user->socid;
86if ($id > 0 || !empty($ref)) {
94 $conf->global->PRODUIT_MULTIPRICES_LIMIT = 5;
98$hookmanager->initHooks(array(
'productpricecard',
'globalcard'));
101 if (
$object->type == $object::TYPE_PRODUCT) {
104 if (
$object->type == $object::TYPE_SERVICE) {
108 restrictedArea($user,
'produit|service', $fieldvalue,
'product&product',
'',
'', $fieldtype);
111$maxpricesupplier = 0;
114 $permissiontoadd =
$object->getRights()->creer;
116 $permissiontoadd = ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'));
128$parameters = array(
'id' => $id,
'ref' => $ref);
129$reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
134if (empty($reshook)) {
135 if (
GETPOST(
'button_removefilter_x',
'alpha') ||
GETPOST(
'button_removefilter.x',
'alpha') ||
GETPOST(
'button_removefilter',
'alpha')) {
139 if ($action ==
'setlabelsellingprice' && $user->admin) {
140 require_once DOL_DOCUMENT_ROOT.
'/core/lib/admin.lib.php';
141 $keyforlabel =
'PRODUIT_MULTIPRICES_LABEL'.GETPOST(
'pricelevel');
146 if (($action ==
'update_vat') && !$cancel && $permissiontoadd) {
147 $tva_tx_txt =
GETPOST(
'tva_tx',
'alpha');
149 $price_label =
GETPOST(
'price_label',
'alpha');
152 $tva_tx = $tva_tx_txt;
155 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
156 $vatratecode = $reg[1];
157 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
160 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
161 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
164 $localtax1_type =
'0';
165 $localtax2_type =
'0';
168 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
170 $vatratecode = $reg[1];
172 $sql =
"SELECT t.rowid, t.type_vat, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
173 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
174 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($mysoc->country_code).
"'";
175 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
176 $sql .=
" AND t.code = '".$db->escape($vatratecode).
"'";
177 $sql .=
" AND t.type_vat IN (0, 1)";
178 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
179 $resql = $db->query($sql);
181 $obj = $db->fetch_object($resql);
183 $npr = $obj->recuperableonly;
184 $localtax1 = $obj->localtax1;
185 $localtax2 = $obj->localtax2;
186 $localtax1_type = $obj->localtax1_type;
187 $localtax2_type = $obj->localtax2_type;
192 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
193 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
194 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($mysoc->country_code).
"'";
195 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
196 $sql .=
" AND t.code = ''";
197 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
198 $resql = $db->query($sql);
200 $obj = $db->fetch_object($resql);
202 $npr = $obj->recuperableonly;
203 $localtax1 = $obj->localtax1;
204 $localtax2 = $obj->localtax2;
205 $localtax1_type = $obj->localtax1_type;
206 $localtax2_type = $obj->localtax2_type;
211 $object->default_vat_code = $vatratecode;
214 $object->localtax1_tx = $localtax1;
215 $object->localtax2_tx = $localtax2;
216 $object->localtax1_type = $localtax1_type;
217 $object->localtax2_type = $localtax2_type;
218 $object->price_label = $price_label;
230 $produit_multiprices_limit =
getDolGlobalInt(
'PRODUIT_MULTIPRICES_LIMIT');
231 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
233 if (
$object->multiprices_base_type[$i] ==
'HT') {
234 $oldprice =
$object->multiprices[$i];
235 $oldminprice =
$object->multiprices_min[$i];
237 $oldprice =
$object->multiprices_ttc[$i];
238 $oldminprice =
$object->multiprices_min_ttc[$i];
240 $oldpricebasetype =
$object->multiprices_base_type[$i];
241 $oldnpr =
$object->multiprices_recuperableonly[$i];
244 $localtaxarray = array();
246 $ret =
$object->updatePrice($oldprice, $oldpricebasetype, $user, (
float) $tva_tx, $oldminprice, $level, $oldnpr, 0, 0, $localtaxarray, $vatratecode, $price_label);
255 if (
$object->price_base_type ==
'HT') {
257 $oldminprice =
$object->price_min;
259 $oldprice =
$object->price_ttc;
260 $oldminprice =
$object->price_min_ttc;
262 $oldpricebasetype =
$object->price_base_type;
266 $localtaxarray = array();
268 $ret =
$object->updatePrice($oldprice, $oldpricebasetype, $user, (
float) $tva_tx, $oldminprice, $level, $oldnpr, 0, 0, $localtaxarray, $vatratecode, $price_label);
286 $maxpricesupplier = 0;
288 if (($action ==
'update_price' || $action ==
'update_level_price') && !$cancel && $permissiontoadd) {
290 $pricestoupdate = array();
295 $maxpricesupplier =
$object->min_recommended_price();
300 if (isModEnabled(
'dynamicprices')) {
301 $object->fk_price_expression = empty($eid) ? 0 : $eid;
303 if (
$object->fk_price_expression != 0) {
305 require_once DOL_DOCUMENT_ROOT.
'/product/dynamic_price/class/price_parser.class.php';
308 if ($priceparser->parseProduct($object) < 0) {
317 || ($action ==
'update_level_price' &&
getDolGlobalString(
'PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')))) {
318 $newprice =
GETPOST(
'price',
'array');
319 $newprice_min =
GETPOST(
'price_min',
'array');
320 $newpricebase =
GETPOST(
'multiprices_base_type',
'array');
321 $newvattx =
GETPOST(
'tva_tx',
'array');
322 $newvatnpr =
GETPOST(
'tva_npr',
'array');
323 $newlocaltax1_tx =
GETPOST(
'localtax1_tx',
'array');
324 $newlocaltax1_type =
GETPOST(
'localtax1_type',
'array');
325 $newlocaltax2_tx =
GETPOST(
'localtax2_tx',
'array');
326 $newlocaltax2_type =
GETPOST(
'localtax2_type',
'array');
329 $object->price_autogen = (int) (
GETPOST(
'usePriceRules') ==
'on');
331 $produit_multiprices_limit =
getDolGlobalInt(
'PRODUIT_MULTIPRICES_LIMIT');
332 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
333 if (!isset($newprice[$i])) {
337 $tva_tx_txt = $newvattx[$i];
339 $tva_tx = $tva_tx_txt;
342 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
343 $vat_src_code = $reg[1];
344 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
346 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
348 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
349 $localtax1 = $newlocaltax1_tx[$i];
350 $localtax1_type = $newlocaltax1_type[$i];
351 $localtax2 = $newlocaltax2_tx[$i];
352 $localtax2_type = $newlocaltax2_type[$i];
353 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
355 $vatratecode = $reg[1];
357 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
358 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
359 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($mysoc->country_code).
"'";
360 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
361 $sql .=
" AND t.code ='".$db->escape($vatratecode).
"'";
362 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
363 $resql = $db->query($sql);
365 $obj = $db->fetch_object($resql);
367 $npr = $obj->recuperableonly;
368 $localtax1 = $obj->localtax1;
369 $localtax2 = $obj->localtax2;
370 $localtax1_type = $obj->localtax1_type;
371 $localtax2_type = $obj->localtax2_type;
375 if (in_array($mysoc->country_code, array(
'ES'))) {
382 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
383 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
384 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($mysoc->country_code).
"'";
385 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
386 $sql .=
" AND t.code = ''";
387 $resql = $db->query($sql);
389 $obj = $db->fetch_object($resql);
391 $npr = $obj->recuperableonly;
392 $localtax1 = $obj->localtax1;
393 $localtax2 = $obj->localtax2;
394 $localtax1_type = $obj->localtax1_type;
395 $localtax2_type = $obj->localtax2_type;
400 $pricestoupdate[$i] = array(
401 'price' =>
price2num($newprice[$i],
'', 2),
402 'price_min' =>
price2num($newprice_min[$i],
'', 2),
403 'price_base_type' => $newpricebase[$i],
404 'default_vat_code' => $vatratecode,
407 'localtaxes_array' => array(
'0' => $localtax1_type,
'1' => $localtax1,
'2' => $localtax2_type,
'3' => $localtax2)
418 $newpricebase =
GETPOST(
'price_base_type',
'alpha');
419 $tva_tx_txt =
GETPOST(
'tva_tx',
'alpha');
420 $price_label =
GETPOST(
'price_label',
'alpha');
422 $tva_tx = $tva_tx_txt;
425 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
426 $vat_src_code = $reg[1];
427 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
429 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
431 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
434 $localtax1_type =
'0';
435 $localtax2_type =
'0';
437 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
439 $vatratecode = $reg[1];
441 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
442 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
443 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($mysoc->country_code).
"'";
444 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
445 $sql .=
" AND t.code ='".$db->escape($vatratecode).
"'";
446 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
447 $resql = $db->query($sql);
449 $obj = $db->fetch_object($resql);
451 $npr = $obj->recuperableonly;
452 $localtax1 = $obj->localtax1;
453 $localtax2 = $obj->localtax2;
454 $localtax1_type = $obj->localtax1_type;
455 $localtax2_type = $obj->localtax2_type;
459 if (in_array($mysoc->country_code, array(
'ES'))) {
466 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
467 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
468 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($mysoc->country_code).
"'";
469 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
470 $sql .=
" AND t.code = ''";
471 $resql = $db->query($sql);
473 $obj = $db->fetch_object($resql);
475 $npr = $obj->recuperableonly;
476 $localtax1 = $obj->localtax1;
477 $localtax2 = $obj->localtax2;
478 $localtax1_type = $obj->localtax1_type;
479 $localtax2_type = $obj->localtax2_type;
484 $pricestoupdate[0] = array(
485 'price' => $newprice,
486 'price_label' => $price_label,
487 'price_min' => $newprice_min,
488 'price_base_type' => $newpricebase,
489 'default_vat_code' => $vatratecode,
492 'localtaxes_array' => array(
'0' => $localtax1_type,
'1' => $localtax1,
'2' => $localtax2_type,
'3' => $localtax2)
501 $object->packaging = (float) $packaging;
504 foreach ($pricestoupdate as $key => $val) {
505 $newprice = $val[
'price'];
507 if ($val[
'price'] < $val[
'price_min'] && !empty(
$object->fk_price_expression)) {
508 $newprice = $val[
'price_min'];
512 $newprice_min =
price2num($val[
'price_min'],
'MU');
515 if (
getDolGlobalString(
'PRODUCT_MINIMUM_RECOMMENDED_PRICE') && $newprice_min < $maxpricesupplier) {
516 setEventMessages($langs->trans(
"MinimumPriceLimit",
price($maxpricesupplier, 0,
'', 1, - 1, - 1,
'auto')),
null,
'errors');
521 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) {
522 $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']);
534 $price_extralabels = $extrafields->fetch_name_optionals_label(
"product_price");
536 $sql =
"SELECT rowid";
537 $sql .=
" FROM ".$object->db->prefix().
"product_price";
538 $sql .=
" WHERE entity IN (".getEntity(
'productprice').
")";
539 $sql .=
" AND price_level=".((int) $key);
540 $sql .=
" AND fk_product = ".((int)
$object->id);
541 $sql .=
" ORDER BY date_price DESC, rowid DESC";
543 $resql =
$object->db->query($sql);
545 $lineid =
$object->db->fetch_object($resql);
548 if (!empty($lineid->rowid)) {
549 foreach ($price_extralabels as $code => $label) {
550 $code_array =
GETPOST($code,
'array');
551 $object->array_options[
'options_'.$code] = $code_array[$key];
555 $object->table_element =
'product_price';
556 $result =
$object->insertExtraFields();
559 $object->table_element =
'product';
578 $action =
'edit_price';
584 if ($action ==
'delete' && $user->hasRight(
'produit',
'supprimer')) {
592 if ($action ==
'activate_price_by_qty' && $permissiontoadd) {
604 if ($action ==
'disable_price_by_qty' && $permissiontoadd) {
616 if ($action ==
'edit_price_by_qty') {
621 if ($action ==
'update_price_by_qty' && $permissiontoadd) {
631 if (empty($quantity)) {
633 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentities(
"Qty")),
null,
'errors');
635 if (empty($newprice)) {
637 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentities(
"Price")),
null,
'errors');
641 if (
$object->price_base_type ==
'TTC') {
646 $unitPrice =
price2num((
float) $price / (
float) $quantity,
'MU');
650 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"product_price_by_qty SET";
651 $sql .=
" price=".((float) $price).
",";
652 $sql .=
" unitprice=".((float) $unitPrice).
",";
653 $sql .=
" quantity=".((float) $quantity).
",";
654 $sql .=
" remise_percent=".((float) $remise_percent).
",";
655 $sql .=
" remise=".((float) $remise);
656 $sql .=
" WHERE rowid = ".((int) $rowid);
658 $result = $db->query($sql);
663 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"product_price_by_qty (fk_product_price,price,unitprice,quantity,remise_percent,remise) values (";
664 $sql .= ((int) $priceid).
','.((float) $price).
','.((float) $unitPrice).
','.((float) $quantity).
','.((float) $remise_percent).
','.((float) $remise).
')';
666 $result = $db->query($sql);
668 if ($db->lasterrno() ==
'DB_ERROR_RECORD_ALREADY_EXISTS') {
678 if ($action ==
'delete_price_by_qty' && $permissiontoadd) {
680 if (!empty($rowid)) {
681 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"product_price_by_qty";
682 $sql .=
" WHERE rowid = ".((int) $rowid);
684 $result = $db->query($sql);
686 setEventMessages((
'delete_price_by_qty'.$langs->transnoentities(
'MissingIds')),
null,
'errors');
690 if ($action ==
'delete_all_price_by_qty' && $permissiontoadd) {
692 if (!empty($rowid)) {
693 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"product_price_by_qty";
694 $sql .=
" WHERE fk_product_price = ".((int) $priceid);
696 $result = $db->query($sql);
698 setEventMessages((
'delete_price_by_qty'.$langs->transnoentities(
'MissingIds')),
null,
'errors');
707 if ($action ==
'add_customer_price_confirm' && !$cancel && $prodcustprice !==
null && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
708 $maxpricesupplier =
$object->min_recommended_price();
710 $update_child_soc =
GETPOSTINT(
'updatechildprice');
714 $prodcustprice->ref_customer =
GETPOST(
'ref_customer',
'alpha');
715 $prodcustprice->fk_product =
$object->id;
718 $prodcustprice->price_base_type =
GETPOST(
"price_base_type",
'alpha');
719 $prodcustprice->price_label =
GETPOST(
"price_label",
'alpha');
724 $extralabels = $extrafields->fetch_name_optionals_label(
"product_customer_price");
725 $extrafield_values = $extrafields->getOptionalsFromPost(
"product_customer_price");
727 $tva_tx_txt =
GETPOST(
"tva_tx",
'alpha');
729 $tva_tx = $tva_tx_txt;
731 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
732 $vat_src_code = $reg[1];
733 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
735 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
737 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
740 $localtax1_type =
'0';
741 $localtax2_type =
'0';
743 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
745 $vatratecode = $reg[1];
747 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
748 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
749 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($mysoc->country_code).
"'";
750 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
751 $sql .=
" AND t.code ='".$db->escape($vatratecode).
"'";
752 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
753 $resql = $db->query($sql);
755 $obj = $db->fetch_object($resql);
757 $npr = $obj->recuperableonly;
758 $localtax1 = $obj->localtax1;
759 $localtax2 = $obj->localtax2;
760 $localtax1_type = $obj->localtax1_type;
761 $localtax2_type = $obj->localtax2_type;
765 if (in_array($mysoc->country_code, array(
'ES'))) {
772 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
773 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
774 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($mysoc->country_code).
"'";
775 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
776 $sql .=
" AND t.code = ''";
777 $resql = $db->query($sql);
779 $obj = $db->fetch_object($resql);
781 $npr = $obj->recuperableonly;
782 $localtax1 = $obj->localtax1;
783 $localtax2 = $obj->localtax2;
784 $localtax1_type = $obj->localtax1_type;
785 $localtax2_type = $obj->localtax2_type;
790 $prodcustprice->default_vat_code = $vatratecode;
791 $prodcustprice->tva_tx = $tva_tx;
792 $prodcustprice->recuperableonly = $npr;
793 $prodcustprice->localtax1_tx = $localtax1;
794 $prodcustprice->localtax2_tx = $localtax2;
795 $prodcustprice->localtax1_type = $localtax1_type;
796 $prodcustprice->localtax2_type = $localtax2_type;
798 if (!($prodcustprice->fk_soc > 0)) {
799 $langs->load(
"errors");
800 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"ThirdParty")),
null,
'errors');
802 $action =
'add_customer_price';
804 if (
getDolGlobalString(
'PRODUCT_MINIMUM_RECOMMENDED_PRICE') && $prodcustprice->price_min < (
float) $maxpricesupplier) {
805 $langs->load(
"errors");
806 setEventMessages($langs->trans(
"MinimumPriceLimit",
price((
float) $maxpricesupplier, 0,
'', 1, -1, -1,
'auto')),
null,
'errors');
808 $action =
'add_customer_price';
812 $result = $prodcustprice->create($user, 0, $update_child_soc);
814 if (!empty($extrafield_values) && is_array($extrafield_values)) {
816 $res = $productcustomerprice->fetch($prodcustprice->id);
818 foreach ($extrafield_values as $key => $value) {
819 $productcustomerprice->array_options[$key] = $value;
821 $result2 = $productcustomerprice->insertExtraFields();
823 $prodcustprice->error = $productcustomerprice->error;
824 $prodcustprice->errors = $productcustomerprice->errors;
833 $action =
'add_customer_price';
841 if ($action ==
'confirm_remove_customer_price' && $prodcustprice !==
null && ($user->hasRight(
'produit',
'supprimer') || $user->hasRight(
'service',
'supprimer'))) {
843 $update_child_soc =
GETPOSTINT(
'updatechildprice');
846 $result = $prodcustprice->delete($user, 0, $update_child_soc);
849 $db->query(
"DELETE FROM ".MAIN_DB_PREFIX.
"product_customer_price_extrafields WHERE fk_object = ".((
int) $prodcustprice->id));
864 if ($action ==
'update_customer_price_confirm' && !$cancel && $prodcustprice !==
null && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
865 $maxpricesupplier =
$object->min_recommended_price();
867 $update_child_soc =
GETPOSTINT(
'updatechildprice');
872 $prodcustprice->ref_customer =
GETPOST(
'ref_customer',
'alpha');
875 $prodcustprice->price_base_type =
GETPOST(
"price_base_type",
'alpha');
876 $prodcustprice->price_label =
GETPOST(
"price_label",
'alpha');
881 $extralabels = $extrafields->fetch_name_optionals_label(
"product_customer_price");
882 $extrafield_values = $extrafields->getOptionalsFromPost(
"product_customer_price");
884 $tva_tx_txt =
GETPOST(
"tva_tx");
886 $tva_tx = $tva_tx_txt;
888 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
889 $vat_src_code = $reg[1];
890 $tva_tx = preg_replace(
'/\s*\(.*\)/',
'', $tva_tx_txt);
892 $tva_tx =
price2num(preg_replace(
'/\*/',
'', $tva_tx));
894 $npr = preg_match(
'/\*/', $tva_tx_txt) ? 1 : 0;
897 $localtax1_type =
'0';
898 $localtax2_type =
'0';
900 if (preg_match(
'/\((.*)\)/', $tva_tx_txt, $reg)) {
902 $vatratecode = $reg[1];
904 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
905 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
906 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($mysoc->country_code).
"'";
907 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
908 $sql .=
" AND t.code ='".$db->escape($vatratecode).
"'";
909 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
910 $resql = $db->query($sql);
912 $obj = $db->fetch_object($resql);
914 $npr = $obj->recuperableonly;
915 $localtax1 = $obj->localtax1;
916 $localtax2 = $obj->localtax2;
917 $localtax1_type = $obj->localtax1_type;
918 $localtax2_type = $obj->localtax2_type;
922 if (in_array($mysoc->country_code, array(
'ES'))) {
929 $sql =
"SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
930 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_tva as t, ".MAIN_DB_PREFIX.
"c_country as c";
931 $sql .=
" WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($mysoc->country_code).
"'";
932 $sql .=
" AND t.taux = ".((float) $tva_tx).
" AND t.active = 1";
933 $sql .=
" AND t.code = ''";
934 $resql = $db->query($sql);
936 $obj = $db->fetch_object($resql);
938 $npr = $obj->recuperableonly;
939 $localtax1 = $obj->localtax1;
940 $localtax2 = $obj->localtax2;
941 $localtax1_type = $obj->localtax1_type;
942 $localtax2_type = $obj->localtax2_type;
947 $prodcustprice->default_vat_code = $vatratecode;
948 $prodcustprice->tva_tx = $tva_tx;
949 $prodcustprice->recuperableonly = $npr;
950 $prodcustprice->localtax1_tx = $localtax1;
951 $prodcustprice->localtax2_tx = $localtax2;
952 $prodcustprice->localtax1_type = $localtax1_type;
953 $prodcustprice->localtax2_type = $localtax2_type;
955 if ($prodcustprice->price_min < $maxpricesupplier &&
getDolGlobalString(
'PRODUCT_MINIMUM_RECOMMENDED_PRICE')) {
956 setEventMessages($langs->trans(
"MinimumPriceLimit",
price($maxpricesupplier, 0,
'', 1, -1, -1,
'auto')),
null,
'errors');
958 $action =
'update_customer_price';
962 $result = $prodcustprice->update($user, 0, $update_child_soc);
964 if (!empty($extrafield_values) && is_array($extrafield_values)) {
966 $res = $productcustomerprice->fetch($prodcustprice->id);
968 foreach ($extrafield_values as $key => $value) {
969 $productcustomerprice->array_options[$key] = $value;
971 $result2 = $productcustomerprice->insertExtraFields();
973 $prodcustprice->error = $productcustomerprice->error;
974 $prodcustprice->errors = $productcustomerprice->errors;
983 $action =
'update_customer_price';
997$form =
new Form($db);
999if (!empty($id) || !empty($ref)) {
1004$title = $langs->trans(
'ProductServiceCard');
1008 $title = $langs->trans(
'Product').
" ".$shortlabel.
" - ".$langs->trans(
'SellingPrices');
1009 $helpurl =
'EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos';
1012 $title = $langs->trans(
'Service').
" ".$shortlabel.
" - ".$langs->trans(
'SellingPrices');
1013 $helpurl =
'EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios';
1016llxHeader(
'', $title, $helpurl,
'', 0, 0,
'',
'',
'',
'classforhorizontalscrolloftabs mod-product page-price');
1018if ($action ==
'ask_remove_customer_price' && ($user->hasRight(
'produit',
'supprimer') || $user->hasRight(
'service',
'supprimer'))) {
1019 $formquestion = array(
1020 array(
'type' =>
'checkbox',
'name' =>
'updatechildprice',
'label' => $langs->trans(
'ForceDeleteChildPriceSoc'),
'value' => 0),
1022 $formconfirm = $form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&lineid='.
GETPOSTINT(
'lineid'), $langs->trans(
'DeleteCustomerPrice'), $langs->trans(
'ConfirmDeleteCustomerPrice'),
'confirm_remove_customer_price', $formquestion, 0, 1);
1027$titre = $langs->trans(
"CardProduct".
$object->type);
1032$linkback =
'<a href="'.DOL_URL_ROOT.
'/product/list.php?restore_lastsearch_values=1&type='.
$object->type.
'">'.$langs->trans(
"BackToList").
'</a>';
1033$object->next_prev_filter =
"(te.fk_product_type:=:".((int)
$object->type).
")";
1036if ($user->socid && !in_array(
'product', explode(
',',
getDolGlobalString(
'MAIN_MODULES_FOR_EXTERNAL')))) {
1040dol_banner_tab($object,
'ref', $linkback, $shownav,
'ref');
1043print
'<div class="fichecenter">';
1045print
'<div class="underbanner clearboth"></div>';
1046print
'<table class="border tableforfield centpercent">';
1053 if (!empty($socid)) {
1056 $soc->fetch($socid);
1059 if (isModEnabled(
"product") && isModEnabled(
"service")) {
1060 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
1061 print
'<tr><td class="">';
1062 print (!
getDolGlobalString(
'PRODUCT_DENY_CHANGE_PRODUCT_TYPE')) ? $form->editfieldkey(
"Type",
'fk_product_type', (
string)
$object->type, $object, 0, $typeformat) : $langs->trans(
'Type');
1064 print $form->editfieldval(
"Type",
'fk_product_type',
$object->type, $object, 0, $typeformat);
1069 print
'<tr><td class="titlefieldcreate">';
1070 print $langs->trans(
"SellingPrice");
1072 print
'<td colspan="2">';
1073 if (
$object->multiprices_base_type[$soc->price_level] ==
'TTC') {
1074 print
'<span class="amount">'.price(
$object->multiprices_ttc[$soc->price_level]).
'</span>';
1076 print
'<span class="amount">'.price(
$object->multiprices[$soc->price_level]).
'</span>';
1078 if (
$object->multiprices_base_type[$soc->price_level]) {
1079 print
' '.$langs->trans(
$object->multiprices_base_type[$soc->price_level]);
1081 print
' '.$langs->trans(
$object->price_base_type);
1086 print
'<tr><td>'.$langs->trans(
"MinPrice").
'</td><td colspan="2">';
1087 if (
$object->multiprices_base_type[$soc->price_level] ==
'TTC') {
1088 print
price(
$object->multiprices_min_ttc[$soc->price_level]).
' '.$langs->trans(
$object->multiprices_base_type[$soc->price_level]);
1090 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]);
1096 print
'<tr><td>'.$langs->trans(
"DefaultTaxRate").
'</td><td colspan="2">';
1098 $positiverates =
'';
1100 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->multiprices_tva_tx[$soc->price_level]);
1103 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->multiprices_localtax1_tx[$soc->price_level]);
1106 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->multiprices_localtax2_tx[$soc->price_level]);
1108 if (empty($positiverates)) {
1109 $positiverates =
'0';
1111 echo
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr);
1116 print
'<tr><td>'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1118 $positiverates =
'';
1123 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax1_tx);
1126 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax2_tx);
1128 if (empty($positiverates)) {
1129 $positiverates =
'0';
1131 echo
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr);
1143 if (isModEnabled(
"product") && isModEnabled(
"service")) {
1144 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
1145 print
'<tr><td class="">';
1146 print (!
getDolGlobalString(
'PRODUCT_DENY_CHANGE_PRODUCT_TYPE')) ? $form->editfieldkey(
"Type",
'fk_product_type', (
string)
$object->type, $object, 0, $typeformat) : $langs->trans(
'Type');
1148 print $form->editfieldval(
"Type",
'fk_product_type',
$object->type, $object, 0, $typeformat);
1153 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"DefaultTaxRate").
'</td>';
1154 print
'<td colspan="2">'.vatrate(
$object->multiprices_tva_tx[1],
true).
'</td>';
1158 if (isModEnabled(
"product") && isModEnabled(
"service")) {
1159 $typeformat =
'select;0:'.$langs->trans(
"Product").
',1:'.$langs->trans(
"Service");
1160 print
'<tr><td class="">';
1161 print (!
getDolGlobalString(
'PRODUCT_DENY_CHANGE_PRODUCT_TYPE')) ? $form->editfieldkey(
"Type",
'fk_product_type', (
string)
$object->type, $object, 0, $typeformat) : $langs->trans(
'Type');
1163 print $form->editfieldval(
"Type",
'fk_product_type',
$object->type, $object, 0, $typeformat);
1168 print
'<!-- Default VAT Rate -->';
1169 print
'<tr><td class="titlefieldcreate">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1172 $positiverates =
'';
1174 $positiverates .= ($positiverates ?
'<span class="opacitymedium">/</span>' :
'').
price2num(
$object->tva_tx);
1177 $positiverates .= ($positiverates ?
'<span class="opacitymedium">/</span>' :
'').
price2num(
$object->localtax1_tx);
1180 $positiverates .= ($positiverates ?
'<span class="opacitymedium">/</span>' :
'').
price2num(
$object->localtax2_tx);
1182 if (empty($positiverates)) {
1183 $positiverates =
'0';
1186 print
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr, 1);
1199 print
'<table class="liste centpercent">';
1200 print
'<tr class="liste_titre"><td>';
1201 print $langs->trans(
"PriceLevel");
1203 print
' <a class="editfielda" href="'.$_SERVER[
"PHP_SELF"].
'?action=editlabelsellingprice&token='.
newToken().
'&pricelevel='.$i.
'&id='.
$object->id.
'">'.
img_edit($langs->trans(
'EditSellingPriceLabel'), 0).
'</a>';
1206 print
'<td style="text-align: right">'.$langs->trans(
"SellingPrice").
'</td>';
1207 print
'<td style="text-align: right">'.$langs->trans(
"MinPrice").
'</td>';
1209 $extrafields->fetch_name_optionals_label(
"product_price");
1210 if ($extrafields->attributes[
"product_price"] && array_key_exists(
'label', $extrafields->attributes[
"product_price"])) {
1211 $extralabels = $extrafields->attributes[
"product_price"][
'label'];
1212 if (!empty($extralabels)) {
1213 foreach ($extralabels as $key => $value) {
1215 if (!empty($extrafields->attributes[
"product_price"][
'list'][$key]) && $extrafields->attributes[
"product_price"][
'list'][$key] != 3) {
1216 if (!empty($extrafields->attributes[
"product_price"][
'langfile'][$key])) {
1217 $langs->load($extrafields->attributes[
"product_price"][
'langfile'][$key]);
1219 if (!empty($extrafields->attributes[
"product_price"][
'help'][$key])) {
1220 $extratitle = $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_price"][
'help'][$key]));
1222 $extratitle = $langs->trans($value);
1224 $field =
'ef.' . $key;
1225 print
'<td style="text-align: right">'.$extratitle.
'</td>';
1232 $produit_multiprices_limit =
getDolGlobalInt(
'PRODUIT_MULTIPRICES_LIMIT');
1233 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
1234 print
'<tr class="oddeven">';
1238 $keyforlabel =
'PRODUIT_MULTIPRICES_LABEL'.$i;
1239 if (preg_match(
'/editlabelsellingprice/', $action)) {
1240 print
'<form method="post" action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'">';
1241 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1242 print
'<input type="hidden" name="action" value="setlabelsellingprice">';
1243 print
'<input type="hidden" name="pricelevel" value="'.$i.
'">';
1244 print $langs->trans(
"SellingPrice").
' '.$i.
' - ';
1245 print
'<input class="maxwidthonsmartphone" type="text" name="labelsellingprice" value="' .
getDolGlobalString($keyforlabel).
'">';
1246 print
' <input type="submit" class="button smallpaddingimp" value="'.$langs->trans(
"Modify").
'">';
1249 print $langs->trans(
"SellingPrice").
' '.$i;
1256 if (
$object->multiprices_base_type [$i] ==
'TTC') {
1257 print
'<td class="right"><span class="amount">'.price(
$object->multiprices_ttc[$i]);
1259 print
'<td class="right"><span class="amount">'.price(
$object->multiprices[$i]);
1262 if (
$object->multiprices_base_type[$i]) {
1263 print
' '.$langs->trans(
$object->multiprices_base_type [$i]).
'</span></td>';
1265 print
' '.$langs->trans(
$object->price_base_type).
'</span></td>';
1269 print
'<td style="text-align: right">';
1270 if (empty(
$object->multiprices_base_type[$i])) {
1271 $object->multiprices_base_type[$i] =
"HT";
1273 if (
$object->multiprices_base_type[$i] ==
'TTC') {
1274 print
price(
$object->multiprices_min_ttc[$i]).
' '.$langs->trans(
$object->multiprices_base_type[$i]);
1276 print
price(
$object->multiprices_min[$i]).
' '.$langs->trans(
$object->multiprices_base_type[$i]);
1279 if (!empty($extralabels)) {
1280 $sql1 =
"SELECT rowid";
1281 $sql1 .=
" FROM ".$object->db->prefix().
"product_price";
1282 $sql1 .=
" WHERE entity IN (".getEntity(
'productprice').
")";
1283 $sql1 .=
" AND price_level=".((int) $i);
1284 $sql1 .=
" AND fk_product = ".((int)
$object->id);
1285 $sql1 .=
" ORDER BY date_price DESC, rowid DESC";
1286 $sql1 .=
" LIMIT 1";
1287 $resql1 =
$object->db->query($sql1);
1289 $lineid =
$object->db->fetch_object($resql1);
1292 $sql2 .=
" fk_object";
1293 foreach ($extralabels as $key => $value) {
1294 $sql2 .=
", ".$db->sanitize($key);
1296 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"product_price_extrafields";
1297 $sql2 .=
" WHERE fk_object = ".((int) $lineid->rowid);
1298 $resql2 = $db->query($sql2);
1300 if ($db->num_rows($resql2) != 1) {
1301 foreach ($extralabels as $key => $value) {
1302 if (!empty($extrafields->attributes[
"product_price"][
'list'][$key]) && $extrafields->attributes[
"product_price"][
'list'][$key] != 3) {
1303 print
'<td align="right"></td>';
1307 $obj = $db->fetch_object($resql2);
1308 foreach ($extralabels as $key => $value) {
1309 if (!empty($extrafields->attributes[
"product_price"][
'list'][$key]) && $extrafields->attributes[
"product_price"][
'list'][$key] != 3) {
1310 print
'<td align="right">'.$extrafields->showOutputField($key, $obj->{$key},
'',
'product_price').
"</td>";
1322 print
'<tr><td>'.$langs->trans(
"PriceByQuantity").
' '.$i;
1326 print
'</td><td colspan="2">';
1328 if (
$object->prices_by_qty[$i] == 1) {
1329 print
'<table width="50%" class="border" summary="List of quantities">';
1331 print
'<tr class="liste_titre">';
1332 print
'<td>'.$langs->trans(
"PriceByQuantityRange").
' '.$i.
'</td>';
1333 print
'<td class="right">'.$langs->trans(
"HT").
'</td>';
1334 print
'<td class="right">'.$langs->trans(
"UnitPrice").
'</td>';
1335 print
'<td class="right">'.$langs->trans(
"Discount").
'</td>';
1336 print
'<td> </td>';
1339 foreach (
$object->prices_by_qty_list[$i] as $ii => $prices) {
1340 if ($action ==
'edit_price_by_qty' && $rowid == $prices[
'rowid'] && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1341 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1342 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1343 print
'<input type="hidden" name="action" value="update_price_by_qty">';
1344 print
'<input type="hidden" name="priceid" value="'.$object->prices_by_qty_id[$i].
'">';
1345 print
'<input type="hidden" value="'.$prices[
'rowid'].
'" name="rowid">';
1346 print
'<tr class="'.($ii % 2 == 0 ?
'pair' :
'impair').
'">';
1347 print
'<td><input size="5" type="text" value="'.$prices[
'quantity'].
'" name="quantity"></td>';
1348 print
'<td class="right" colspan="2"><input size="10" type="text" value="'.price2num($prices[
'price'],
'MU').
'" name="price"> '.
$object->price_base_type.
'</td>';
1349 print
'<td class="right nowraponall"><input size="5" type="text" value="'.$prices[
'remise_percent'].
'" name="remise_percent"> %</td>';
1350 print
'<td class="center"><input type="submit" value="'.$langs->trans(
"Modify").
'" class="button"></td>';
1354 print
'<tr class="'.($ii % 2 == 0 ?
'pair' :
'impair').
'">';
1355 print
'<td>'.$prices[
'quantity'].
'</td>';
1356 print
'<td class="right">'.price($prices[
'price']).
'</td>';
1357 print
'<td class="right">'.price($prices[
'unitprice']).
'</td>';
1358 print
'<td class="right">'.price($prices[
'remise_percent']).
' %</td>';
1359 print
'<td class="center">';
1360 if (($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1361 print
'<a class="editfielda marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=edit_price_by_qty&token='.
newToken().
'&rowid='.$prices[
"rowid"].
'">';
1363 print
'<a class="marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=delete_price_by_qty&token='.
newToken().
'&rowid='.$prices[
"rowid"].
'">';
1372 if ($action !=
'edit_price_by_qty' && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1373 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1374 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1375 print
'<input type="hidden" name="action" value="update_price_by_qty">';
1376 print
'<input type="hidden" name="priceid" value="'.$object->prices_by_qty_id[$i].
'">';
1377 print
'<input type="hidden" value="0" name="rowid">';
1378 print
'<tr class="'.($ii % 2 == 0 ?
'pair' :
'impair').
'">';
1379 print
'<td><input size="5" type="text" value="1" name="quantity"></td>';
1380 print
'<td class="right" class="nowrap"><input size="10" type="text" value="0" name="price"> '.$object->price_base_type.
'</td>';
1381 print
'<td class="right"> </td>';
1382 print
'<td class="right" class="nowraponall"><input size="5" type="text" value="0" name="remise_percent"> %</td>';
1383 print
'<td class="center"><input type="submit" value="'.$langs->trans(
"Add").
'" class="button"></td>';
1389 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>';
1391 print $langs->trans(
"No");
1392 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>';
1400 print
'<tr><td class="titlefield">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1402 $positiverates =
'';
1407 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax1_tx);
1410 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax2_tx);
1412 if (empty($positiverates)) {
1413 $positiverates =
'0';
1415 echo
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr, 0, 1);
1425 print
'<tr class="field_selling_price"><td>'.$langs->trans(
"SellingPrice").
'</td><td>';
1426 if (
$object->price_base_type ==
'TTC') {
1431 print
'<i class="opacitymedium"> - ' .
price(
$object->price_ttc).
' '.$langs->trans(
'TTC') .
'</i>';
1438 print
'<tr class="field_min_price"><td>'.$langs->trans(
"MinPrice").
'</td><td>';
1439 if (
$object->price_base_type ==
'TTC') {
1444 print
'<i class="opacitymedium"> - ' .
price(
$object->price_min_ttc).
' '.$langs->trans(
'TTC') .
'</i>';
1451 print
'<tr class="field_price_label"><td>'.$form->textwithpicto($langs->trans(
"PackagingForThisProduct"), $langs->trans(
"PackagingForThisProductSellDesc")).
'</td><td>';
1457 print
'<tr class="field_price_label"><td>'.$langs->trans(
"PriceLabel").
'</td><td>';
1464 print
'<tr><td>'.$langs->trans(
"PriceByQuantity");
1465 if (
$object->prices_by_qty[0] == 0) {
1466 print
' <a href="'.$_SERVER[
'PHP_SELF'].
'?id='.
$object->id.
'&action=activate_price_by_qty&level=1&token='.
newToken().
'">('.$langs->trans(
"Activate").
')';
1468 print
' <a href="'.$_SERVER[
'PHP_SELF'].
'?id='.
$object->id.
'&action=disable_price_by_qty&level=1&token='.
newToken().
'">('.$langs->trans(
"DisablePriceByQty").
')';
1472 if (
$object->prices_by_qty[0] == 1) {
1473 print
'<table width="50%" class="border" summary="List of quantities">';
1474 print
'<tr class="liste_titre">';
1476 print
'<td>'.$langs->trans(
"Quantity").
'</td>';
1477 print
'<td class="right">'.$langs->trans(
"Price").
'</td>';
1478 print
'<td class="right"></td>';
1479 print
'<td class="right">'.$langs->trans(
"UnitPrice").
'</td>';
1480 print
'<td class="right">'.$langs->trans(
"Discount").
'</td>';
1481 print
'<td> </td>';
1483 if ($action !=
'edit_price_by_qty') {
1484 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1485 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1486 print
'<input type="hidden" name="action" value="update_price_by_qty">';
1487 print
'<input type="hidden" name="priceid" value="'.$object->prices_by_qty_id[0].
'">';
1488 print
'<input type="hidden" value="0" name="rowid">';
1490 print
'<tr class="'.(($ii % 2) == 0 ?
'pair' :
'impair').
'">';
1491 print
'<td><input size="5" type="text" value="1" name="quantity"></td>';
1492 print
'<td class="right"><input class="width50 right" type="text" value="0" name="price"></td>';
1496 print
'<td class="right"> </td>';
1497 print
'<td class="right nowraponall"><input type="text" class="width50 right" value="0" name="remise_percent"> %</td>';
1498 print
'<td class="center"><input type="submit" value="'.$langs->trans(
"Add").
'" class="button"></td>';
1503 foreach (
$object->prices_by_qty_list[0] as $ii => $prices) {
1504 if ($action ==
'edit_price_by_qty' && $rowid == $prices[
'rowid'] && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1505 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1506 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1507 print
'<input type="hidden" name="action" value="update_price_by_qty">';
1508 print
'<input type="hidden" name="priceid" value="'.$object->prices_by_qty_id[0].
'">';
1509 print
'<input type="hidden" value="'.$prices[
'rowid'].
'" name="rowid">';
1510 print
'<tr class="'.($ii % 2 == 0 ?
'pair' :
'impair').
'">';
1511 print
'<td><input size="5" type="text" value="'.$prices[
'quantity'].
'" name="quantity"></td>';
1512 print
'<td class="right"><input class="width50 right" type="text" value="'.price2num($prices[
'price'],
'MU').
'" name="price"></td>';
1513 print
'<td class="right">';
1515 print $prices[
'price_base_type'];
1517 print
'<td class="right"> </td>';
1518 print
'<td class="right nowraponall"><input class="width50 right" type="text" value="'.$prices[
'remise_percent'].
'" name="remise_percent"> %</td>';
1519 print
'<td class="center"><input type="submit" value="'.$langs->trans(
"Modify").
'" class="button"></td>';
1523 print
'<tr class="'.($ii % 2 == 0 ?
'pair' :
'impair').
'">';
1524 print
'<td>'.$prices[
'quantity'].
'</td>';
1525 print
'<td class="right">'.price($prices[
'price']).
'</td>';
1526 print
'<td class="right">';
1528 print $prices[
'price_base_type'];
1530 print
'<td class="right">'.price($prices[
'unitprice']).
'</td>';
1531 print
'<td class="right">'.price($prices[
'remise_percent']).
' %</td>';
1532 print
'<td class="center">';
1533 if (($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1534 print
'<a class="editfielda marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=edit_price_by_qty&token='.
newToken().
'&rowid='.$prices[
"rowid"].
'">';
1536 print
'<a class="marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=delete_price_by_qty&token='.
newToken().
'&rowid='.$prices[
"rowid"].
'">';
1547 print $langs->trans(
"No");
1556print
'<div class="clearboth"></div>';
1568if (!$action || $action ==
'delete' || $action ==
'showlog_customer_price' || $action ==
'showlog_default_price' || $action ==
'add_customer_price'
1569 || $action ==
'activate_price_by_qty' || $action ==
'disable_price_by_qty') {
1570 print
"\n".
'<div class="tabsAction">'.
"\n";
1573 $parameters = array();
1574 $reshook = $hookmanager->executeHooks(
'addMoreActionsButtons', $parameters, $object, $action);
1575 if (empty($reshook)) {
1577 if ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer')) {
1578 print
'<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' .
dol_escape_htmltag($langs->trans(
"NoEditVariants")) .
'">' . $langs->trans(
"UpdateDefaultPrice") .
'</a></div>';
1582 if ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer')) {
1583 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>';
1585 print
'<div class="inline-block divButAction"><span class="butActionRefused" title="'.dol_escape_htmltag($langs->trans(
"NotEnoughPermissions")).
'">' . $langs->trans(
"UpdateDefaultPrice") .
'</span></div>';
1590 if ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer')) {
1591 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>';
1593 print
'<div class="inline-block divButAction"><span class="butActionRefused" title="'.dol_escape_htmltag($langs->trans(
"NotEnoughPermissions")).
'">' . $langs->trans(
"AddCustomerPrice") .
'</span></div>';
1598 if ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer')) {
1599 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>';
1601 print
'<div class="inline-block divButAction"><span class="butActionRefused" title="'.dol_escape_htmltag($langs->trans(
"NotEnoughPermissions")).
'">' . $langs->trans(
"UpdateVAT") .
'</span></div>';
1604 if ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer')) {
1605 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>';
1607 print
'<div class="inline-block divButAction"><span class="butActionRefused" title="'.dol_escape_htmltag($langs->trans(
"NotEnoughPermissions")).
'">' . $langs->trans(
"UpdateLevelPrices") .
'</span></div>';
1622if ($action ==
'edit_vat' && ($user->hasRight(
'produit',
'creer') || $user->hasRight(
'service',
'creer'))) {
1625 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1626 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1627 print
'<input type="hidden" name="action" value="update_vat">';
1628 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
1632 print
'<table class="border centpercent">';
1635 print
'<tr><td>'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1643 print $form->buttonsSaveCancel();
1645 print
'<br></form><br>';
1648if (($action ==
'edit_price' || $action ==
'edit_level_price') &&
$object->getRights()->creer) {
1653 print
'<!-- Edit price -->'.
"\n";
1654 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1655 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1656 print
'<input type="hidden" name="action" value="update_price">';
1657 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
1661 print
'<div class="div-table-responsive-no-min">';
1662 print
'<table class="border centpercent">';
1665 print
'<tr><td class="titlefield">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
1671 print $langs->trans(
'PriceBase');
1674 print $form->selectPriceBaseType(
$object->price_base_type,
"price_base_type");
1679 if (isModEnabled(
'dynamicprices')) {
1681 print
'<!-- Show price mode of dynamicprices editor -->'.
"\n";
1682 print
'<tr><td>'.$langs->trans(
"PriceMode").
'</td><td>';
1683 print
img_picto(
'',
'dynamicprice',
'class="pictofixedwidth"');
1685 $price_expression_list = array(0 => $langs->trans(
"Numeric").
' <span class="opacitymedium">('.$langs->trans(
"NoDynamicPrice").
')</span>');
1686 foreach ($price_expression->list_price_expression() as $entry) {
1687 $price_expression_list[$entry->id] = $entry->title;
1689 $price_expression_preselection =
GETPOST(
'eid') ?
GETPOST(
'eid') : (
$object->fk_price_expression ?
$object->fk_price_expression :
'0');
1690 print $form->selectarray(
'eid', $price_expression_list, $price_expression_preselection);
1691 print
' <a id="expression_editor" class="classlink">'.$langs->trans(
"PriceExpressionEditor").
'</a>';
1697 <script
type=
"text/javascript">
1698 jQuery(document).ready(
function() {
1699 jQuery(
"#expression_editor").click(
function() {
1700 window.location =
"<?php echo DOL_URL_ROOT ?>/product/dynamic_price/editor.php?id=<?php echo $id ?>&tab=price&eid=" + $(
"#eid").val();
1702 jQuery(
"#eid").change(on_change);
1705 function on_change() {
1706 if ($(
"#eid").val() == 0) {
1707 jQuery(
"#price_numeric").show();
1709 jQuery(
"#price_numeric").hide();
1718 $product->fetch($id, $ref,
'',
'1');
1719 print
'<tr id="price_numeric"><td>';
1720 $text = $langs->trans(
'SellingPrice');
1721 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
1723 if (
$object->price_base_type ==
'TTC') {
1724 print
'<input name="price" size="10" value="'.price($product->price_ttc).
'">';
1726 print
'<input name="price" size="10" value="'.price($product->price).
'">';
1732 $text = $langs->trans(
'MinPrice');
1733 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
1735 if (
$object->price_base_type ==
'TTC') {
1736 print
'<input name="price_min" size="10" value="'.price(
$object->price_min_ttc).
'">';
1738 print
'<input name="price_min" size="10" value="'.price(
$object->price_min).
'">';
1741 print
' '.$langs->trans(
"MinimumRecommendedPrice",
price((
float) $maxpricesupplier, 0,
'', 1, -1, -1,
'auto')).
' '.
img_warning().
'</td>';
1749 print $form->textwithpicto($langs->trans(
"PackagingForThisProduct"), $langs->trans(
"PackagingForThisProductSellDesc"));
1751 $packaging =
$object->packaging;
1752 print
'<input class="flat" name="packaging" size="5" value="' .
price($packaging, 0,
'', 1, -1, 2).
'">';
1759 print $langs->trans(
'PriceLabel');
1761 print
'<input name="price_label" maxlength="255" class="minwidth300 maxwidth400onsmartphone" value="'.$object->price_label.
'">';
1765 $parameters = array();
1766 $reshook = $hookmanager->executeHooks(
'formObjectOptions', $parameters, $object, $action);
1773 print $form->buttonsSaveCancel();
1776 } elseif ($action ==
'edit_level_price' &&
$object->getRights()->creer) {
1777 print
'<!-- Edit price per level -->'.
"\n"; ?>
1780 var showHidePriceRules =
function () {
1781 var otherPrices = $(
'div.fiche form table tbody tr:not(:first)');
1782 var minPrice1 = $(
'div.fiche form input[name="price_min[1]"]');
1784 if (jQuery(
'input#usePriceRules').prop(
'checked')) {
1793 jQuery(document).ready(
function () {
1794 showHidePriceRules();
1796 jQuery(
'input#usePriceRules').click(showHidePriceRules);
1801 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
1802 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1803 print
'<input type="hidden" name="action" value="update_level_price">';
1804 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
1809 print $langs->trans(
'UseMultipriceRules').
' <input type="checkbox" id="usePriceRules" name="usePriceRules" '.(
$object->price_autogen ?
'checked' :
'').
'><br><br>';
1812 print
'<div class="div-table-responsive-no-min">';
1813 print
'<table class="noborder">';
1814 print
'<thead><tr class="liste_titre">';
1816 print
'<td>'.$langs->trans(
"PriceLevel").
'</td>';
1819 print
'<td style="text-align: center">'.$langs->trans(
"DefaultTaxRate").
'</td>';
1824 print
'<td class="center">'.$langs->trans(
"SellingPrice").
'</td>';
1826 print
'<td class="center">'.$langs->trans(
"MinPrice").
'</td>';
1833 $extrafields->fetch_name_optionals_label(
"product_price");
1834 if ($extrafields->attributes[
"product_price"] && array_key_exists(
'label', $extrafields->attributes[
"product_price"])) {
1835 $extralabels = $extrafields->attributes[
"product_price"][
'label'];
1836 if (!empty($extralabels)) {
1837 foreach ($extralabels as $key => $value) {
1839 if (!empty($extrafields->attributes[
"product_price"][
'list'][$key]) && $extrafields->attributes[
"product_price"][
'list'][$key] != 3) {
1840 if (!empty($extrafields->attributes[
"product_price"][
'langfile'][$key])) {
1841 $langs->load($extrafields->attributes[
"product_price"][
'langfile'][$key]);
1843 if (!empty($extrafields->attributes[
"product_price"][
'help'][$key])) {
1844 $extratitle = $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_price"][
'help'][$key]));
1846 $extratitle = $langs->trans($value);
1848 print
'<td style="text-align: right">'.$extratitle.
'</td>';
1853 print
'</tr></thead>';
1857 $produit_multiprices_limit =
getDolGlobalInt(
'PRODUIT_MULTIPRICES_LIMIT');
1858 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
1859 print
'<tr class="oddeven">';
1861 $keyforlabel =
'PRODUIT_MULTIPRICES_LABEL'.$i;
1863 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
1869 print
'<input type="hidden" name="tva_tx['.$i.
']" value="'.(
$object->default_vat_code ?
$object->tva_tx.
' ('.
$object->default_vat_code.
')' :
$object->tva_tx).
'">';
1870 print
'<input type="hidden" name="tva_npr['.$i.
']" value="'.
$object->tva_npr.
'">';
1871 print
'<input type="hidden" name="localtax1_tx['.$i.
']" value="'.
$object->localtax1_tx.
'">';
1872 print
'<input type="hidden" name="localtax1_type['.$i.
']" value="'.
$object->localtax1_type.
'">';
1873 print
'<input type="hidden" name="localtax2_tx['.$i.
']" value="'.
$object->localtax2_tx.
'">';
1874 print
'<input type="hidden" name="localtax2_type['.$i.
']" value="'.
$object->localtax2_type.
'">';
1878 print
'<td style="text-align: center">';
1879 print $form->load_tva(
"tva_tx[".$i.
']',
$object->multiprices_tva_tx[$i], $mysoc,
null,
$object->id, 0,
$object->type,
false, 1);
1884 print
'<td style="text-align: center">';
1885 if (
$object->multiprices_base_type [$i] ==
'TTC') {
1886 print
'<input name="price['.$i.
']" size="10" value="'.
price(
$object->multiprices_ttc [$i]).
'">';
1888 print
'<input name="price['.$i.
']" size="10" value="'.
price(
$object->multiprices [$i]).
'">';
1890 print
' '.$form->selectPriceBaseType(
$object->multiprices_base_type [$i],
"multiprices_base_type[".$i.
"]");
1894 print
'<td style="text-align: center">';
1895 if (
$object->multiprices_base_type [$i] ==
'TTC') {
1896 print
'<input name="price_min['.$i.
']" size="10" value="'.
price(
$object->multiprices_min_ttc [$i]).
'">';
1898 print
'<input name="price_min['.$i.
']" size="10" value="'.
price(
$object->multiprices_min [$i]).
'">';
1901 print
'<td class="left">'.$langs->trans(
"MinimumRecommendedPrice",
price((
float) $maxpricesupplier, 0,
'', 1, -1, -1,
'auto')).
' '.
img_warning().
'</td>';
1905 if (!empty($extralabels)) {
1906 $sql1 =
"SELECT rowid";
1907 $sql1 .=
" FROM ".$object->db->prefix().
"product_price";
1908 $sql1 .=
" WHERE entity IN (".getEntity(
'productprice').
")";
1909 $sql1 .=
" AND price_level=".((int) $i);
1910 $sql1 .=
" AND fk_product = ".((int)
$object->id);
1911 $sql1 .=
" ORDER BY date_price DESC, rowid DESC";
1912 $sql1 .=
" LIMIT 1";
1913 $resql1 =
$object->db->query($sql1);
1915 $lineid =
$object->db->fetch_object($resql1);
1917 if (empty($lineid->rowid)) {
1918 foreach ($extralabels as $key => $value) {
1919 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))) {
1920 if (!empty($extrafields->attributes[
"product_price"][
'langfile'][$key])) {
1921 $langs->load($extrafields->attributes[
"product_price"][
'langfile'][$key]);
1924 $extravalue = GETPOSTISSET(
'options_'.$key) ? $extrafield_values[
'options_'.$key] : $obj->{$key};
1925 print
'<td align="center"><input name="'.$key.
'['.$i.
']" size="10" value="'.$extravalue.
'"></td>';
1930 $sql .=
" fk_object";
1931 foreach ($extralabels as $key => $value) {
1932 $sql .=
", ".$db->sanitize($key);
1934 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product_price_extrafields";
1935 $sql .=
" WHERE fk_object = ".((int) $lineid->rowid);
1936 $resql = $db->query($sql);
1938 $obj = $db->fetch_object($resql);
1939 foreach ($extralabels as $key => $value) {
1940 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))) {
1941 if (!empty($extrafields->attributes[
"product_price"][
'langfile'][$key])) {
1942 $langs->load($extrafields->attributes[
"product_price"][
'langfile'][$key]);
1945 $extravalue = (GETPOSTISSET(
'options_'.$key) ? $extrafield_values[
'options_'.$key] : $obj->{$key} ??
'');
1946 print
'<td align="center"><input name="'.$key.
'['.$i.
']" size="10" value="'.$extravalue.
'"></td>';
1963 print $form->buttonsSaveCancel();
1974 $sortfield =
GETPOST(
'sortfield',
'aZ09comma');
1975 $sortorder =
GETPOST(
'sortorder',
'aZ09comma');
1977 if (empty($page) || $page == -1) {
1980 $offset = $limit * $page;
1981 $pageprev = $page - 1;
1982 $pagenext = $page + 1;
1984 $sortorder =
"ASC,ASC";
1987 $sortfield =
"soc.nom,t.date_begin";
1991 $filter = array(
't.fk_product' => (
string)
$object->id);
1993 if (!empty($search_soc)) {
1994 $filter[
'soc.nom'] = (string) $search_soc;
1997 if ($action ==
'add_customer_price') {
1999 $maxpricesupplier =
$object->min_recommended_price();
2001 print
'<!-- add_customer_price -->';
2004 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
2005 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2006 print
'<input type="hidden" name="action" value="add_customer_price_confirm">';
2007 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
2009 print
'<div class="tabBar tabBarWithBottom">';
2011 print
'<table class="border centpercent">';
2013 print
'<td class="fieldrequired">'.$langs->trans(
'ThirdParty').
'</td>';
2015 $filter =
'(s.client:IN:1,2,3)';
2016 print
img_picto(
'',
'company').$form->select_company(
GETPOSTINT(
'socid'),
'socid', $filter,
'SelectThirdParty', 0, 0, array(), 0,
'minwidth300');
2021 print
'<tr><td>' . $langs->trans(
'RefCustomer') .
'</td>';
2022 print
'<td><input name="ref_customer" size="12"></td></tr>';
2026 print
'<tr><td>'.$langs->trans(
"AppliedPricesFrom").
'</td><td>';
2027 print $form->selectDate(!empty($date_begin) ? $date_begin :
dol_now(),
"date_begin", 0, 0, 1,
"date_begin");
2032 print
'<tr><td>'.$langs->trans(
"AppliedPricesTo").
'</td><td>';
2033 print $form->selectDate($date_end,
"date_end", 0, 0, 1,
"date_end");
2037 print
'<tr><td class="fieldrequired">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
2042 print
'<tr><td class="fieldrequired">';
2043 print $langs->trans(
'PriceBase');
2046 print $form->selectPriceBaseType(
$object->price_base_type,
"price_base_type");
2051 print
'<tr><td class="fieldrequired">';
2052 $text = $langs->trans(
'SellingPrice');
2053 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
2055 if (
$object->price_base_type ==
'TTC') {
2056 print
'<input name="price" size="10" value="'.price(
$object->price_ttc).
'">';
2058 print
'<input name="price" size="10" value="'.price(
$object->price).
'">';
2064 $text = $langs->trans(
'MinPrice');
2065 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
2066 if (
$object->price_base_type ==
'TTC') {
2067 print
'<td><input name="price_min" size="10" value="'.price(
$object->price_min_ttc).
'">';
2069 print
'<td><input name="price_min" size="10" value="'.price(
$object->price_min).
'">';
2072 print
'<td class="left">'.$langs->trans(
"MinimumRecommendedPrice",
price($maxpricesupplier, 0,
'', 1, -1, -1,
'auto')).
' '.
img_warning().
'</td>';
2078 print $langs->trans(
'PriceLabel');
2080 print
'<input name="price_label" maxlength="255" class="minwidth300 maxwidth400onsmartphone" value="'.$object->price_label.
'">';
2086 print
'<tr><td>'.$langs->trans(
"Discount").
'</td><td>';
2087 print
'<input name="discount_percent" size="10" value="'.price($discount_percent).
'">';
2091 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2092 $extralabels = !empty($extrafields->attributes[
"product_customer_price"][
'label']) ? $extrafields->attributes[
"product_customer_price"][
'label'] :
'';
2093 $extrafield_values = $extrafields->getOptionalsFromPost(
"product_customer_price");
2094 if (!empty($extralabels)) {
2095 if (empty($prodcustprice->id)) {
2096 foreach ($extralabels as $key => $value) {
2097 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))) {
2098 if (!empty($extrafields->attributes[
"product_customer_price"][
'langfile'][$key])) {
2099 $langs->load($extrafields->attributes[
"product_customer_price"][
'langfile'][$key]);
2102 print
'<tr><td'.($extrafields->attributes[
"product_customer_price"][
'required'][$key] ?
' class="fieldrequired"' :
'').
'>';
2103 if (!empty($extrafields->attributes[
"product_customer_price"][
'help'][$key])) {
2104 print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_customer_price"][
'help'][$key]));
2106 print $langs->trans($value);
2108 print
'</td><td>'.$extrafields->showInputField($key, GETPOSTISSET(
'options_'.$key) ? $extrafield_values[
'options_'.$key] :
'',
'',
'',
'',
'', 0,
'product_customer_price').
'</td></tr>';
2119 print
'<div class="center">';
2122 print
'<div class="marginbottomonly">';
2123 print
'<input type="checkbox" name="updatechildprice" id="updatechildprice" value="1"> ';
2124 print
'<label for="updatechildprice">'.$langs->trans(
'ForceUpdateChildPriceSoc').
'</label>';
2127 print $form->buttonsSaveCancel();
2130 } elseif ($action ==
'edit_customer_price') {
2132 $maxpricesupplier =
$object->min_recommended_price();
2134 print
'<!-- edit_customer_price -->';
2137 $result = $prodcustprice->fetch(
GETPOSTINT(
'lineid'));
2142 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
2143 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2144 print
'<input type="hidden" name="action" value="update_customer_price_confirm">';
2145 print
'<input type="hidden" name="lineid" value="'.$prodcustprice->id.
'">';
2147 print
'<table class="liste centpercent">';
2149 print
'<td class="titlefield fieldrequired">'.$langs->trans(
'ThirdParty').
'</td>';
2150 $staticsoc =
new Societe($db);
2151 $staticsoc->fetch($prodcustprice->fk_soc);
2152 print
"<td>".$staticsoc->getNomUrl(1).
"</td>";
2156 print
'<tr><td>' . $langs->trans(
'RefCustomer') .
'</td>';
2157 print
'<td><input name="ref_customer" size="12" value="' .
dol_escape_htmltag($prodcustprice->ref_customer) .
'"></td></tr>';
2160 print
'<tr><td>'.$langs->trans(
"AppliedPricesFrom").
'</td><td>';
2161 print $form->selectDate($prodcustprice->date_begin,
"date_begin", 0, 0, 1,
"date_begin");
2165 print
'<tr><td>'.$langs->trans(
"AppliedPricesTo").
'</td><td>';
2166 print $form->selectDate($prodcustprice->date_end,
"date_end", 0, 0, 1,
"date_end");
2170 print
'<tr><td class="fieldrequired">'.$langs->trans(
"DefaultTaxRate").
'</td><td>';
2171 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);
2175 print
'<tr><td class="fieldrequired">';
2176 print $langs->trans(
'PriceBase');
2179 print $form->selectPriceBaseType($prodcustprice->price_base_type,
"price_base_type");
2184 print
'<tr><td class="fieldrequired">';
2185 $text = $langs->trans(
'SellingPrice');
2186 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
2188 if ($prodcustprice->price_base_type ==
'TTC') {
2189 print
'<input name="price" size="10" value="'.price($prodcustprice->price_ttc).
'">';
2191 print
'<input name="price" size="10" value="'.price($prodcustprice->price).
'">';
2197 $text = $langs->trans(
'MinPrice');
2198 print $form->textwithpicto($text, $langs->trans(
"PrecisionUnitIsLimitedToXDecimals",
getDolGlobalString(
'MAIN_MAX_DECIMALS_UNIT')), 1,
'help');
2200 if ($prodcustprice->price_base_type ==
'TTC') {
2201 print
'<input name="price_min" size="10" value="'.price($prodcustprice->price_min_ttc).
'">';
2203 print
'<input name="price_min" size="10" value="'.price($prodcustprice->price_min).
'">';
2207 print
'<td class="left">'.$langs->trans(
"MinimumRecommendedPrice",
price($maxpricesupplier, 0,
'', 1, -1, -1,
'auto')).
' '.
img_warning().
'</td>';
2213 print $langs->trans(
'PriceLabel');
2215 print
'<input name="price_label" maxlength="255" class="minwidth300 maxwidth400onsmartphone" value="'.$prodcustprice->price_label.
'">';
2220 print
'<tr><td>'.$langs->trans(
"Discount").
'</td><td>';
2221 print
'<input name="discount_percent" size="10" value="'.price($prodcustprice->discount_percent).
'">';
2225 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2226 $extralabels = !empty($extrafields->attributes[
"product_customer_price"][
'label']) ? $extrafields->attributes[
"product_customer_price"][
'label'] :
'';
2227 $extrafield_values = $extrafields->getOptionalsFromPost(
"product_customer_price");
2228 if (!empty($extralabels)) {
2230 foreach ($extralabels as $key => $value) {
2231 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && ($extrafields->attributes[
"product_customer_price"][
'list'][$key] == 1 || $extrafields->attributes[
"product_customer_price"][
'list'][$key] == 3 || ($action ==
"edit_customer_price" && $extrafields->attributes[
"product_customer_price"][
'list'][$key] == 4))) {
2232 if (!empty($extrafields->attributes[
"product_customer_price"][
'langfile'][$key])) {
2233 $langs->load($extrafields->attributes[
"product_customer_price"][
'langfile'][$key]);
2236 print
'<tr><td'.($extrafields->attributes[
"product_customer_price"][
'required'][$key] ?
' class="fieldrequired"' :
'').
'>';
2237 if (!empty($extrafields->attributes[
"product_customer_price"][
'help'][$key])) {
2238 print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_customer_price"][
'help'][$key]));
2240 print $langs->trans($value);
2242 print
'</td><td>'.$extrafields->showInputField($key, GETPOSTISSET(
'options_'.$key) ? $extrafield_values[
'options_'.$key] :
'',
'',
'',
'',
'', 0,
'product_customer_price').
'</td></tr>';
2247 $sql .=
" fk_object";
2248 foreach ($extralabels as $key => $value) {
2249 $sql .=
", ".$db->sanitize($key);
2251 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product_customer_price_extrafields";
2252 $sql .=
" WHERE fk_object = ".((int) $prodcustprice->id);
2253 $resql = $db->query($sql);
2255 $obj = $db->fetch_object($resql);
2256 foreach ($extralabels as $key => $value) {
2257 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && ($extrafields->attributes[
"product_customer_price"][
'list'][$key] == 1 || $extrafields->attributes[
"product_customer_price"][
'list'][$key] == 3 || ($action ==
"edit_customer_price" && $extrafields->attributes[
"product_customer_price"][
'list'][$key] == 4))) {
2258 if (!empty($extrafields->attributes[
"product_customer_price"][
'langfile'][$key])) {
2259 $langs->load($extrafields->attributes[
"product_customer_price"][
'langfile'][$key]);
2262 print
'<tr><td'.($extrafields->attributes[
"product_customer_price"][
'required'][$key] ?
' class="fieldrequired"' :
'').
'>';
2263 if (!empty($extrafields->attributes[
"product_customer_price"][
'help'][$key])) {
2264 print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_customer_price"][
'help'][$key]));
2266 print $langs->trans($value);
2268 print
'</td><td>'.$extrafields->showInputField($key, GETPOSTISSET(
'options_'.$key) ? $extrafield_values[
'options_'.$key] : $obj->{$key},
'',
'',
'',
'', 0,
'product_customer_price');
2280 print
'<div class="center">';
2281 print
'<div class="marginbottomonly">';
2282 print
'<input type="checkbox" name="updatechildprice" id="updatechildprice" value="1"> ';
2283 print
'<label for="updatechildprice">'.$langs->trans(
'ForceUpdateChildPriceSoc').
'</label>';
2286 print $form->buttonsSaveCancel();
2288 print
'<br></form>';
2289 } elseif ($action ==
'showlog_customer_price') {
2291 print
'<!-- list of all log of prices per customer -->'.
"\n";
2293 $sortfield =
't.datec';
2294 $filter = array(
't.fk_product' => (
string)
$object->id,
't.fk_soc' => (
string)
GETPOSTINT(
'socid'));
2297 $nbtotalofrecords =
'';
2299 $nbtotalofrecords = $prodcustprice->fetchAllLog($sortorder, $sortfield,
$conf->liste_limit, $offset, $filter);
2302 $result = $prodcustprice->fetchAllLog($sortorder, $sortfield,
$conf->liste_limit, $offset, $filter);
2307 $option =
'&socid='.GETPOSTINT(
'socid').
'&id='.
$object->id;
2309 $staticsoc =
new Societe($db);
2312 $title = $langs->trans(
'PriceByCustomerLog');
2313 $title .=
' - '.$staticsoc->getNomUrl(1);
2315 $backbutton =
'<a class="justalink" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'">'.$langs->trans(
"Back").
'</a>';
2318 print_barre_liste($title, $page, $_SERVER[
'PHP_SELF'], $option, $sortfield, $sortorder, $backbutton, count($prodcustprice->lines), $nbtotalofrecords,
'title_accountancy.png');
2320 if (count($prodcustprice->lines) > 0) {
2321 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
2322 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2323 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
2325 print
'<div class="div-table-responsive-no-min">';
2326 print
'<table class="liste centpercent">';
2328 print
'<tr class="liste_titre">';
2329 print
'<td>'.$langs->trans(
"ThirdParty").
'</td>';
2330 print
'<td>'.$langs->trans(
'RefCustomer').
'</td>';
2331 print
'<td>'.$langs->trans(
"AppliedPricesFrom").
'</td>';
2332 print
'<td>'.$langs->trans(
"AppliedPricesTo").
'</td>';
2333 print
'<td class="center">'.$langs->trans(
"PriceBase").
'</td>';
2334 print
'<td class="right">'.$langs->trans(
"DefaultTaxRate").
'</td>';
2335 print
'<td class="right">'.$langs->trans(
"HT").
'</td>';
2336 print
'<td class="right">'.$langs->trans(
"TTC").
'</td>';
2337 if ($mysoc->localtax1_assuj ==
"1" || $mysoc->localtax2_assuj ==
"1") {
2338 print
'<td class="right">'.$langs->trans(
"INCT").
'</td>';
2340 print
'<td class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"HT").
'</td>';
2341 print
'<td class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"TTC").
'</td>';
2342 print
'<td class="right">'.$langs->trans(
"PriceLabel").
'</td>';
2343 print
'<td class="right">'.$langs->trans(
"Discount").
'</td>';
2344 print
'<td class="right">'.$langs->trans(
"ChangedBy").
'</td>';
2345 print
'<td>'.$langs->trans(
"DateCreation").
'</td>';
2348 foreach ($prodcustprice->lines as $line) {
2350 $staticsoc =
new Societe($db);
2351 $staticsoc->fetch($line->fk_soc);
2353 $tva_tx = $line->default_vat_code ? $line->tva_tx.
' ('.$line->default_vat_code.
')' : $line->tva_tx;
2356 if ($line->price_base_type ==
'HT') {
2359 $pu = $line->price_ttc;
2363 $localtaxarray =
getLocalTaxesFromRate($line->tva_tx.($line->default_vat_code ?
' ('.$line->default_vat_code.
')' :
''), 0, $staticsoc, $mysoc);
2365 $resultarray =
calcul_price_total(1, $pu, 0, (
float) $line->tva_tx, 1, 1, 0, $line->price_base_type, $line->recuperableonly,
$object->type, $mysoc, $localtaxarray);
2367 $total_ht = $resultarray[0];
2368 $total_vat = $resultarray[1];
2369 $total_localtax1 = $resultarray[9];
2370 $total_localtax2 = $resultarray[10];
2371 $total_ttc = $resultarray[2];
2373 print
'<tr class="oddeven">';
2375 print
'<td class="tdoverflowmax125">'.$staticsoc->getNomUrl(1).
"</td>";
2376 print
'<td>'.$line->ref_customer.
'</td>';
2377 print
"<td>".dol_print_date($line->date_begin,
"day",
'tzuserrel').
"</td>";
2378 print
"<td>".dol_print_date($line->date_end,
"day",
'tzuserrel').
"</td>";
2379 print
'<td class="center">'.$langs->trans($line->price_base_type).
"</td>";
2380 print
'<td class="right">';
2382 $positiverates =
'';
2384 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->tva_tx);
2387 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->localtax1_tx);
2390 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->localtax2_tx);
2392 if (empty($positiverates)) {
2393 $positiverates =
'0';
2396 echo
vatrate($positiverates.($line->default_vat_code ?
' ('.$line->default_vat_code.
')' :
''), true, ($line->tva_npr ? $line->tva_npr : $line->recuperableonly));
2400 print
'<td class="right"><span class="amount">'.price($line->price).
"</span></td>";
2402 print
'<td class="right"><span class="amount">'.price($line->price_ttc).
"</span></td>";
2403 if ($mysoc->localtax1_assuj ==
"1" || $mysoc->localtax2_assuj ==
"1") {
2404 print
'<td class="right">'.price($resultarray[2]).
'</td>';
2407 print
'<td class="right">'.price($line->price_min).
'</td>';
2408 print
'<td class="right">'.price($line->price_min_ttc).
'</td>';
2409 print
'<td class="right">'.$line->price_label.
'</td>';
2410 print
'<td class="right">'.price($line->discount_percent).
'</td>';
2413 $userstatic =
new User($db);
2414 $userstatic->fetch($line->fk_user);
2415 print
'<td class="right">';
2416 print $userstatic->getNomUrl(1,
'', 0, 0, 24, 0,
'login');
2419 print
"<td>".dol_print_date($line->datec,
"dayhour",
'tzuserrel').
"</td>";
2425 print $langs->trans(
'None');
2427 } elseif ($action !=
'showlog_default_price' && $action !=
'edit_price' && $action !=
'edit_level_price') {
2429 print
'<!-- list of all prices per customer -->'.
"\n";
2432 $nbtotalofrecords =
'';
2434 $nbtotalofrecords = $prodcustprice->fetchAll($sortorder, $sortfield, 0, 0, $filter);
2437 $result = $prodcustprice->fetchAll($sortorder, $sortfield,
$conf->liste_limit, $offset, $filter);
2442 $option =
'&search_soc='.$search_soc.
'&id='.
$object->id;
2445 print_barre_liste($langs->trans(
'PriceByCustomer'), $page, $_SERVER [
'PHP_SELF'], $option, $sortfield, $sortorder,
'', count($prodcustprice->lines), $nbtotalofrecords,
'title_accountancy.png');
2447 print
'<form action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="POST">';
2448 print
'<input type="hidden" name="token" value="'.newToken().
'">';
2449 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
2451 print
'<!-- List of prices per customer -->'.
"\n";
2452 print
'<div class="div-table-responsive-no-min">'.
"\n";
2453 print
'<table class="liste centpercent">'.
"\n";
2455 if (count($prodcustprice->lines) > 0 || $search_soc) {
2456 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2457 $custom_price_extralabels = !empty($extrafields->attributes[
"product_customer_price"][
'label']) ? $extrafields->attributes[
"product_customer_price"][
'label'] :
'';
2463 if ($mysoc->localtax1_assuj ==
"1" || $mysoc->localtax2_assuj ==
"1") {
2466 if (!empty($custom_price_extralabels) && is_array($custom_price_extralabels)) {
2467 $colspan += count($custom_price_extralabels);
2470 print
'<tr class="liste_titre">';
2471 print
'<td class="liste_titre"><input type="text" class="flat maxwidth125" name="search_soc" value="'.$search_soc.
'"></td>';
2472 print
'<td class="liste_titre" colspan="'.$colspan.
'"> </td>';
2474 print
'<td class="liste_titre maxwidthsearch">';
2475 $searchpicto = $form->showFilterAndCheckAddButtons(0);
2481 print
'<tr class="liste_titre">';
2482 print
'<td>'.$langs->trans(
"ThirdParty").
'</td>';
2483 print
'<td>'.$langs->trans(
'RefCustomer').
'</td>';
2484 print
'<td>'.$langs->trans(
"AppliedPricesFrom").
'</td>';
2485 print
'<td>'.$langs->trans(
"AppliedPricesTo").
'</td>';
2486 print
'<td class="center">'.$langs->trans(
"PriceBase").
'</td>';
2487 print
'<td class="right">'.$langs->trans(
"DefaultTaxRate").
'</td>';
2488 print
'<td class="right">'.$langs->trans(
"HT").
'</td>';
2489 print
'<td class="right">'.$langs->trans(
"TTC").
'</td>';
2490 if ($mysoc->localtax1_assuj ==
"1" || $mysoc->localtax2_assuj ==
"1") {
2491 print
'<td class="right">'.$langs->trans(
"INCT").
'</td>';
2493 print
'<td class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"HT").
'</td>';
2494 print
'<td class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"TTC").
'</td>';
2495 print
'<td class="right">'.$langs->trans(
"PriceLabel").
'</td>';
2496 print
'<td class="right">'.$langs->trans(
"Discount").
'</td>';
2498 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2499 if ($extrafields->attributes[
"product_customer_price"] && array_key_exists(
'label', $extrafields->attributes[
"product_customer_price"])) {
2500 $extralabels = $extrafields->attributes[
"product_customer_price"][
'label'];
2501 if (!empty($extralabels)) {
2502 foreach ($extralabels as $key => $value) {
2504 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && $extrafields->attributes[
"product_customer_price"][
'list'][$key] != 3) {
2505 if (!empty($extrafields->attributes[
"product_customer_price"][
'langfile'][$key])) {
2506 $langs->load($extrafields->attributes[
"product_customer_price"][
'langfile'][$key]);
2508 if (!empty($extrafields->attributes[
"product_customer_price"][
'help'][$key])) {
2509 $extratitle = $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes[
"product_customer_price"][
'help'][$key]));
2511 $extratitle = $langs->trans($value);
2513 print
'<td style="text-align: right">'.$extratitle.
'</td>';
2518 print
'<td>'.$langs->trans(
"ChangedBy").
'</td>';
2523 if (
$object->price_base_type ==
'HT') {
2530 $localtaxarray =
getLocalTaxesFromRate(
$object->tva_tx.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), 0, $mysoc, $mysoc);
2532 $resultarray =
calcul_price_total(1, $pu, 0,
$object->tva_tx, 1, 1, 0,
$object->price_base_type, 0,
$object->type, $mysoc, $localtaxarray);
2534 $total_ht = $resultarray[0];
2535 $total_vat = $resultarray[1];
2536 $total_localtax1 = $resultarray[9];
2537 $total_localtax2 = $resultarray[10];
2538 $total_ttc = $resultarray[2];
2541 print
'<!-- PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES -->'.
"\n";
2542 print
'<tr class="oddeven">';
2543 print
'<td colspan="4">' . $langs->trans(
'Default') .
'</td>';
2545 print
'<td class="center">'.$langs->trans(
$object->price_base_type).
"</td>";
2548 print
'<td class="right">';
2550 $positiverates =
'';
2555 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax1_tx);
2558 $positiverates .= ($positiverates ?
'/' :
'').
price2num(
$object->localtax2_tx);
2560 if (empty($positiverates)) {
2561 $positiverates =
'0';
2563 echo
vatrate($positiverates.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), true,
$object->tva_npr);
2569 print
'<td class="right"><span class="amount">'.price(
$object->price).
"</span></td>";
2571 print
'<td class="right"><span class="amount">'.price(
$object->price_ttc).
"</span></td>";
2572 if ($mysoc->localtax1_assuj ==
"1" || $mysoc->localtax2_assuj ==
"1") {
2574 print
'<td class="right"><span class="amount">'.price($resultarray[2]).
'</span></td>';
2577 print
'<td class="right">'.price(
$object->price_min).
'</td>';
2578 print
'<td class="right">'.price(
$object->price_min_ttc).
'</td>';
2579 print
'<td class="right">'.$object->price_label.
'</td>';
2580 print
'<td class="right"></td>';
2581 print
'<td class="right"></td>';
2582 if (!empty($extralabels)) {
2583 foreach ($extralabels as $key) {
2585 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && $extrafields->attributes[
"product_customer_price"][
'list'][$key] != 3) {
2586 print
'<td class="right"></td>';
2590 if ($user->hasRight(
'produit',
'supprimer') || $user->hasRight(
'service',
'supprimer')) {
2591 print
'<td class="nowraponall">';
2592 print
'<a class="marginleftonly marginrightonly" href="'.$_SERVER[
"PHP_SELF"].
'?action=showlog_default_price&token='.
newToken().
'&id='.
$object->id.
'">';
2593 print
img_info($langs->trans(
'PriceByCustomerLog'));
2596 print
'<a class="marginleftonly marginrightonly editfielda" href="'.$_SERVER[
"PHP_SELF"].
'?action=edit_price&token='.
newToken().
'&id='.
$object->id.
'">';
2597 print
img_edit(
'default', 0,
'style="vertical-align: middle;"');
2604 if (count($prodcustprice->lines) > 0) {
2605 foreach ($prodcustprice->lines as $line) {
2607 $staticsoc =
new Societe($db);
2608 $staticsoc->fetch($line->fk_soc);
2610 $tva_tx = $line->default_vat_code ? $line->tva_tx.
' ('.$line->default_vat_code.
')' : $line->tva_tx;
2613 if ($line->price_base_type ==
'HT') {
2616 $pu = $line->price_ttc;
2620 $localtaxarray =
getLocalTaxesFromRate($line->tva_tx.($line->default_vat_code ?
' ('.$line->default_vat_code.
')' :
''), 0, $staticsoc, $mysoc);
2622 $resultarray =
calcul_price_total(1, $pu, 0, (
float) $line->tva_tx, 1, 1, 0, $line->price_base_type, $line->recuperableonly,
$object->type, $mysoc, $localtaxarray);
2624 $total_ht = $resultarray[0];
2625 $total_vat = $resultarray[1];
2626 $total_localtax1 = $resultarray[9];
2627 $total_localtax2 = $resultarray[10];
2628 $total_ttc = $resultarray[2];
2630 print
'<tr class="oddeven">';
2632 print
'<td class="tdoverflowmax125">'.$staticsoc->getNomUrl(1).
"</td>";
2633 print
'<td>'.dol_escape_htmltag($line->ref_customer).
'</td>';
2634 print
"<td>".dol_print_date($line->date_begin,
"day",
'tzuserrel').
"</td>";
2635 print
"<td>".dol_print_date($line->date_end,
"day",
'tzuserrel').
"</td>";
2636 print
'<td class="center">'.$langs->trans($line->price_base_type).
"</td>";
2638 print
'<td class="right">';
2640 $positiverates =
'';
2642 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->tva_tx);
2645 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->localtax1_tx);
2648 $positiverates .= ($positiverates ?
'/' :
'').
price2num($line->localtax2_tx);
2650 if (empty($positiverates)) {
2651 $positiverates =
'0';
2654 echo
vatrate($positiverates.($line->default_vat_code ?
' ('.$line->default_vat_code.
')' :
''), true, (!empty($line->tva_npr) ? $line->tva_npr : $line->recuperableonly));
2658 print
'<td class="right"><span class="amount">'.price($line->price).
"</span></td>";
2660 print
'<td class="right"><span class="amount">'.price($line->price_ttc).
"</span></td>";
2661 if ($mysoc->localtax1_assuj ==
"1" || $mysoc->localtax2_assuj ==
"1") {
2663 print
'<td class="right"><span class="amount">'.price($resultarray[2]).
'</span></td>';
2666 print
'<td class="right">'.price($line->price_min).
'</td>';
2667 print
'<td class="right">'.price($line->price_min_ttc).
'</td>';
2668 print
'<td class="right">'.$line->price_label.
'</td>';
2669 print
'<td class="right">'.price($line->discount_percent).
'</td>';
2672 $extrafields->fetch_name_optionals_label(
"product_customer_price");
2673 $extralabels = $extrafields->attributes[
"product_customer_price"][
'label'] ?? array();
2674 if (!empty($extralabels)) {
2676 $sql .=
" fk_object";
2677 foreach ($extralabels as $key => $value) {
2678 $sql .=
", ".$db->sanitize($key);
2680 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product_customer_price_extrafields";
2681 $sql .=
" WHERE fk_object = ".((int) $line->id);
2682 $resql = $db->query($sql);
2684 if ($db->num_rows($resql) != 1) {
2685 foreach ($extralabels as $key => $value) {
2686 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && $extrafields->attributes[
"product_customer_price"][
'list'][$key] != 3) {
2691 $obj = $db->fetch_object($resql);
2692 foreach ($extralabels as $key => $value) {
2693 if (!empty($extrafields->attributes[
"product_customer_price"][
'list'][$key]) && $extrafields->attributes[
"product_customer_price"][
'list'][$key] != 3) {
2694 print
'<td align="right">'.$extrafields->showOutputField($key, $obj->{$key},
'',
'product_customer_price').
"</td>";
2703 $userstatic =
new User($db);
2704 $userstatic->fetch($line->fk_user);
2707 print $userstatic->getNomUrl(-1,
'', 0, 0, 24, 0,
'login');
2712 if ($user->hasRight(
'produit',
'supprimer') || $user->hasRight(
'service',
'supprimer')) {
2713 print
'<td class="right nowraponall">';
2714 print
'<a href="'.$_SERVER[
"PHP_SELF"].
'?action=showlog_customer_price&token='.
newToken().
'&id='.
$object->id.
'&socid='.$line->fk_soc.
'">';
2715 print
img_info($langs->trans(
'PriceByCustomerLog'));
2718 print
'<a class="marginleftonly editfielda" href="'.$_SERVER[
"PHP_SELF"].
'?action=edit_customer_price&token='.
newToken().
'&id='.
$object->id.
'&lineid='.$line->id.
'">';
2719 print
img_edit(
'default', 0,
'style="vertical-align: middle;"');
2722 print
'<a class="marginleftonly" href="'.$_SERVER[
"PHP_SELF"].
'?action=ask_remove_customer_price&token='.
newToken().
'&id='.
$object->id.
'&lineid='.$line->id.
'">';
2723 print
img_delete(
'default',
'style="vertical-align: middle;"');
2741if ((!
getDolGlobalString(
'PRODUIT_CUSTOMER_PRICES') || $action ==
'showlog_default_price') && !in_array($action, array(
'edit_price',
'edit_level_price',
'edit_vat'))) {
2742 $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,";
2743 $sql .=
" p.price_level, p.price_min, p.price_min_ttc,p.price_by_qty,";
2744 $sql .=
" p.date_price as dp, p.fk_price_expression, u.rowid as user_id, u.login";
2745 $sql .=
" ,p.price_label";
2746 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product_price as p,";
2747 $sql .=
" ".MAIN_DB_PREFIX.
"user as u";
2748 $sql .=
" WHERE fk_product = ".((int)
$object->id);
2749 $sql .=
" AND p.entity IN (".getEntity(
'productprice').
")";
2750 $sql .=
" AND p.fk_user_author = u.rowid";
2752 $sql .=
" AND p.price_level = ".((int) $soc->price_level);
2754 $sql .=
" ORDER BY p.date_price DESC, p.rowid DESC, p.price_level ASC";
2758 $result = $db->query($sql);
2760 print
'<div class="divlogofpreviouscustomerprice">';
2762 $num = $db->num_rows($result);
2771 $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);
2779 $result = $db->query($sql);
2780 $num = $db->num_rows($result);
2787 $backbutton =
'<a class="justalink" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'">'.$langs->trans(
"Back").
'</a>';
2791 print_barre_liste($langs->trans(
"DefaultPriceLog"), 0, $_SERVER[
"PHP_SELF"],
'',
'',
'', $backbutton, 0, $num,
'title_accountancy.png');
2794 print_barre_liste($langs->trans(
"PriceByCustomerLog"), 0, $_SERVER[
"PHP_SELF"],
'',
'',
'',
'', 0, $num,
'title_accountancy.png');
2797 print
'<!-- List of log prices -->'.
"\n";
2798 print
'<div class="div-table-responsive">'.
"\n";
2799 print
'<table class="liste centpercent noborder">'.
"\n";
2801 print
'<tr class="liste_titre">';
2802 print
'<th>'.$langs->trans(
"AppliedPricesFrom").
'</tg>';
2805 print
'<th class="center">'.$langs->trans(
"PriceLevel").
'</th>';
2808 print
'<th class="center">'.$langs->trans(
"Type").
'</th>';
2811 print
'<th class="center">'.$langs->trans(
"PriceBase").
'</th>';
2813 print
'<th class="right">'.$langs->trans(
"DefaultTaxRate").
'</th>';
2815 print
'<th class="right">'.$langs->trans(
"HT").
'</th>';
2816 print
'<th class="right">'.$langs->trans(
"TTC").
'</th>';
2817 if ($mysoc->localtax1_assuj ==
"1" || $mysoc->localtax2_assuj ==
"1") {
2818 print
'<th class="right">'.$langs->trans(
"INCT").
'</th>';
2820 if (isModEnabled(
'dynamicprices')) {
2821 print
'<th class="right">'.$langs->trans(
"PriceExpressionSelected").
'</th>';
2823 print
'<th class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"HT").
'</th>';
2824 print
'<th class="right">'.$langs->trans(
"MinPrice").
' '.$langs->trans(
"TTC").
'</th>';
2825 print
'<th class="right">'.$langs->trans(
"Label").
'</th>';
2826 print
'<th>'.$langs->trans(
"ChangedBy").
'</th>';
2827 if ($user->hasRight(
'produit',
'supprimer')) {
2828 print
'<th class="right"> </th>';
2832 $notfirstlineforlevel = array();
2836 $objp = $db->fetch_object($result);
2838 print
'<tr class="oddeven">';
2840 print
"<td>".dol_print_date($db->jdate($objp->dp),
"dayhour",
'tzuserrel').
"</td>";
2844 print
'<td class="center">'.$objp->price_level.
"</td>";
2848 $type = ($objp->price_by_qty == 1) ?
'PriceByQuantity' :
'Standard';
2849 print
'<td class="center">'.$langs->trans($type).
"</td>";
2852 print
'<td class="center">';
2853 if (empty($objp->price_by_qty)) {
2854 print $langs->trans($objp->price_base_type);
2859 print
'<td class="right">';
2861 if (empty($objp->price_by_qty)) {
2862 $positiverates =
'';
2864 $positiverates .= ($positiverates ?
'/' :
'').
price2num($objp->tva_tx);
2867 $positiverates .= ($positiverates ?
'/' :
'').
price2num($objp->localtax1_tx);
2870 $positiverates .= ($positiverates ?
'/' :
'').
price2num($objp->localtax2_tx);
2872 if (empty($positiverates)) {
2873 $positiverates =
'0';
2875 echo
vatrate($positiverates.($objp->default_vat_code ?
' ('.$objp->default_vat_code.
')' :
''), true, !empty($objp->tva_npr) ? $objp->tva_npr : 0);
2888 if ($objp->price_base_type ==
'HT') {
2891 $pu = $objp->price_ttc;
2895 $localtaxarray =
getLocalTaxesFromRate($objp->tva_tx.($object->default_vat_code ?
' ('.$object->default_vat_code.
')' :
''), 0, $mysoc, $mysoc);
2897 $resultarray =
calcul_price_total(1, $pu, 0, $objp->tva_tx, 1, 1, 0, $objp->price_base_type, $objp->recuperableonly,
$object->type, $mysoc, $localtaxarray);
2899 $total_ht = $resultarray[0];
2900 $total_vat = $resultarray[1];
2901 $total_localtax1 = $resultarray[9];
2902 $total_localtax2 = $resultarray[10];
2903 $total_ttc = $resultarray[2];
2906 if (!empty($objp->fk_price_expression) && !empty(
$conf->dynamicprices->enabled)) {
2908 $res = $price_expression->fetch($objp->fk_price_expression);
2909 $title = $price_expression->title;
2910 print
'<td class="right"></td>';
2911 print
'<td class="right"></td>';
2912 if ($mysoc->localtax1_assuj ==
"1" || $mysoc->localtax2_assuj ==
"1") {
2913 print
'<td class="right"></td>';
2915 print
'<td class="right">'.$title.
"</td>";
2918 print
'<td class="right">';
2919 if (empty($objp->price_by_qty)) {
2920 print
'<span class="amount">'.price($objp->price).
'</span>';
2924 print
'<td class="right">';
2925 if (empty($objp->price_by_qty)) {
2926 $price_ttc = $objp->price_ttc;
2927 print
'<span class="amount">'.price($price_ttc).
'<span>';
2930 if ($mysoc->localtax1_assuj ==
"1" || $mysoc->localtax2_assuj ==
"1") {
2931 print
'<td class="right">';
2932 print $resultarray[2];
2935 if (isModEnabled(
'dynamicprices')) {
2936 print
'<td class="right"></td>';
2941 print
'<td class="right">';
2942 if (empty($objp->price_by_qty)) {
2943 print
price($objp->price_min);
2948 print
'<td class="right">';
2949 if (empty($objp->price_by_qty)) {
2950 $price_min_ttc = $objp->price_min_ttc;
2951 print
price($price_min_ttc);
2956 print
'<td class="right">';
2957 print $objp->price_label;
2962 if ($objp->user_id > 0) {
2963 $userstatic =
new User($db);
2964 $userstatic->fetch($objp->user_id);
2965 print $userstatic->getNomUrl(-1,
'', 0, 0, 24, 0,
'login');
2971 if ($user->hasRight(
'produit',
'supprimer')) {
2974 if (empty($notfirstlineforlevel[$objp->price_level])) {
2975 $notfirstlineforlevel[$objp->price_level] = 1;
2983 print
'<td class="right">';
2984 if ($candelete || ($db->jdate($objp->dp) >=
dol_now())) {
2985 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( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Class for accessing price expression table.
Class to parse product price expressions.
File of class to manage predefined price products or services by customer.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
dol_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...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formatted for view output Used into pdf and HTML pages.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
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.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_clone($object, $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...
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.
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, 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...
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
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
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.