dolibarr 19.0.3
products.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
3 * Copyright (C) 2005-2013 Regis Houssin <regis.houssin@inodbox.com>
4 * Copyright (C) 2007-2011 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2020 Josep LluĂ­s Amador <joseplluis@lliuretic.cat>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
26if (!defined('NOTOKENRENEWAL')) {
27 define('NOTOKENRENEWAL', 1); // Disables token renewal
28}
29if (!defined('NOREQUIREMENU')) {
30 define('NOREQUIREMENU', '1');
31}
32if (!defined('NOREQUIREHTML')) {
33 define('NOREQUIREHTML', '1');
34}
35if (!defined('NOREQUIREAJAX')) {
36 define('NOREQUIREAJAX', '1');
37}
38if (empty($_GET['keysearch']) && !defined('NOREQUIREHTML')) {
39 define('NOREQUIREHTML', '1');
40}
41
42// Load Dolibarr environment
43require '../../main.inc.php';
44
45$htmlname = GETPOST('htmlname', 'aZ09');
46$socid = GETPOST('socid', 'int');
47$type = GETPOST('type', 'int');
48$mode = GETPOST('mode', 'int');
49$status = ((GETPOST('status', 'int') >= 0) ? GETPOST('status', 'int') : - 1); // status buy when mode = customer , status purchase when mode = supplier
50$status_purchase = ((GETPOST('status_purchase', 'int') >= 0) ? GETPOST('status_purchase', 'int') : - 1); // status purchase when mode = customer
51$outjson = (GETPOST('outjson', 'int') ? GETPOST('outjson', 'int') : 0);
52$price_level = GETPOST('price_level', 'int');
53$action = GETPOST('action', 'aZ09');
54$id = GETPOST('id', 'int');
55$price_by_qty_rowid = GETPOST('pbq', 'int');
56$finished = GETPOST('finished', 'int');
57$alsoproductwithnosupplierprice = GETPOST('alsoproductwithnosupplierprice', 'int');
58$warehouseStatus = GETPOST('warehousestatus', 'alpha');
59$hidepriceinlabel = GETPOST('hidepriceinlabel', 'int');
60
61// Security check
62restrictedArea($user, 'produit|service|commande|propal|facture', 0, 'product&product');
63
64
65/*
66 * View
67 */
68
69// print '<!-- Ajax page called with url '.dol_escape_htmltag($_SERVER["PHP_SELF"]).'?'.dol_escape_htmltag($_SERVER["QUERY_STRING"]).' -->'."\n";
70// print_r($_GET);
71
72if ($action == 'fetch' && !empty($id)) {
73 // action='fetch' is used to get product information on a product. So when action='fetch', id must be the product id.
74 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
75 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
76
77 top_httphead('application/json');
78
79 $outjson = array();
80
81 $object = new Product($db);
82 $ret = $object->fetch($id);
83 if ($ret > 0) {
84 $outref = $object->ref;
85 $outlabel = $object->label;
86 $outlabel_trans = '';
87 $outdesc = $object->description;
88 $outdesc_trans = '';
89 $outtype = $object->type;
90 $outprice_ht = null;
91 $outprice_ttc = null;
92 $outpricebasetype = null;
93 $outtva_tx_formated = 0;
94 $outtva_tx = 0;
95 $outdefault_vat_code = '';
96 $outqty = 1;
97 $outdiscount = 0;
98 $mandatory_period = $object->mandatory_period;
99 $found = false;
100
101 $price_level = 1;
102 if ($socid > 0) {
103 $needchangeaccordingtothirdparty = 0;
104 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
105 $needchangeaccordingtothirdparty = 1;
106 }
107 if (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) {
108 $needchangeaccordingtothirdparty = 1;
109 }
110 if ($needchangeaccordingtothirdparty) {
111 $thirdpartytemp = new Societe($db);
112 $thirdpartytemp->fetch($socid);
113
114 //Load translation description and label according to thirdparty language
115 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
116 $newlang = $thirdpartytemp->default_lang;
117
118 if (!empty($newlang)) {
119 $outputlangs = new Translate("", $conf);
120 $outputlangs->setDefaultLang($newlang);
121 $outdesc_trans = (!empty($object->multilangs[$outputlangs->defaultlang]["description"])) ? $object->multilangs[$outputlangs->defaultlang]["description"] : $object->description;
122 $outlabel_trans = (!empty($object->multilangs[$outputlangs->defaultlang]["label"])) ? $object->multilangs[$outputlangs->defaultlang]["label"] : $object->label;
123 } else {
124 $outdesc_trans = $object->description;
125 $outlabel_trans = $object->label;
126 }
127 }
128
129 //Set price level according to thirdparty
130 if (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) {
131 $price_level = $thirdpartytemp->price_level;
132 }
133 }
134 }
135
136 // Price by qty
137 if (!empty($price_by_qty_rowid) && $price_by_qty_rowid >= 1 && (getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES'))) { // If we need a particular price related to qty
138 $sql = "SELECT price, unitprice, quantity, remise_percent";
139 $sql .= " FROM ".MAIN_DB_PREFIX."product_price_by_qty";
140 $sql .= " WHERE rowid = ".((int) $price_by_qty_rowid);
141
142 $result = $db->query($sql);
143 if ($result) {
144 $objp = $db->fetch_object($result);
145 if ($objp) {
146 $found = true;
147 $outprice_ht = price($objp->unitprice);
148 $outprice_ttc = price($objp->unitprice * (1 + ($object->tva_tx / 100)));
149
150 $outpricebasetype = $object->price_base_type;
151 $outtva_tx_formated = price($object->tva_tx);
152 $outtva_tx = price2num($object->tva_tx);
153 $outdefault_vat_code = $object->default_vat_code;
154
155 $outqty = $objp->quantity;
156 $outdiscount = $objp->remise_percent;
157 }
158 }
159 }
160
161 // Multiprice (1 price per level)
162 if (!$found && isset($price_level) && $price_level >= 1 && (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES'))) { // If we need a particular price level (from 1 to 6)
163 $sql = "SELECT price, price_ttc, price_base_type,";
164 $sql .= " tva_tx, default_vat_code"; // Vat rate and code will be used if PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL is on.
165 $sql .= " FROM ".MAIN_DB_PREFIX."product_price ";
166 $sql .= " WHERE fk_product = ".((int) $id);
167 $sql .= " AND entity IN (".getEntity('productprice').")";
168 $sql .= " AND price_level = ".((int) $price_level);
169 $sql .= " ORDER BY date_price";
170 $sql .= " DESC LIMIT 1";
171
172 $result = $db->query($sql);
173 if ($result) {
174 $objp = $db->fetch_object($result);
175 if ($objp) {
176 $found = true;
177 $outprice_ht = price($objp->price); // formated for langage user because is inserted into input field
178 $outprice_ttc = price($objp->price_ttc); // formated for langage user because is inserted into input field
179 $outpricebasetype = $objp->price_base_type;
180 if (getDolGlobalString('PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL')) {
181 $outtva_tx_formated = price($objp->tva_tx); // formated for langage user because is inserted into input field
182 $outtva_tx = price2num($objp->tva_tx); // international numeric
183 $outdefault_vat_code = $objp->default_vat_code;
184 } else {
185 // The common and default behaviour.
186 $outtva_tx_formated = price($object->tva_tx);
187 $outtva_tx = price2num($object->tva_tx);
188 $outdefault_vat_code = $object->default_vat_code;
189 }
190 }
191 }
192 }
193
194 // Price by customer
195 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') && !empty($socid)) {
196 require_once DOL_DOCUMENT_ROOT.'/product/class/productcustomerprice.class.php';
197
198 $prodcustprice = new ProductCustomerPrice($db);
199
200 $filter = array('t.fk_product' => $object->id, 't.fk_soc' => $socid);
201
202 $result = $prodcustprice->fetchAll('', '', 0, 0, $filter);
203 if ($result) {
204 if (count($prodcustprice->lines) > 0) {
205 $found = true;
206 $outprice_ht = price($prodcustprice->lines[0]->price);
207 $outprice_ttc = price($prodcustprice->lines[0]->price_ttc);
208 $outpricebasetype = $prodcustprice->lines[0]->price_base_type;
209 $outtva_tx_formated = price($prodcustprice->lines[0]->tva_tx);
210 $outtva_tx = price2num($prodcustprice->lines[0]->tva_tx);
211 $outdefault_vat_code = $prodcustprice->lines[0]->default_vat_code;
212 }
213 }
214 }
215
216 if (!$found) {
217 $outprice_ht = price($object->price);
218 $outprice_ttc = price($object->price_ttc);
219 $outpricebasetype = $object->price_base_type;
220 $outtva_tx_formated = price($object->tva_tx);
221 $outtva_tx = price2num($object->tva_tx);
222 $outdefault_vat_code = $object->default_vat_code;
223 }
224
225 // VAT to use and default VAT for product are set to same value by default
226 $product_outtva_tx_formated = $outtva_tx_formated;
227 $product_outtva_tx = $outtva_tx;
228 $product_outdefault_vat_code = $outdefault_vat_code;
229
230 // If we ask the price according to buyer, we change it.
231 if (GETPOST('addalsovatforthirdpartyid', 'int')) {
232 $thirdparty_buyer = new Societe($db);
233 $thirdparty_buyer->fetch($socid);
234
235 $tmpvatwithcode = get_default_tva($mysoc, $thirdparty_buyer, $id, 0);
236
237 if (!is_numeric($tmpvatwithcode) || $tmpvatwithcode != -1) {
238 $reg =array();
239 if (preg_match('/(.+)\s\‍((.+)\‍)/', $tmpvatwithcode, $reg)) {
240 $outtva_tx = price2num($reg[1]);
241 $outtva_tx_formated = price($outtva_tx);
242 $outdefault_vat_code = $reg[2];
243 } else {
244 $outtva_tx = price2num($tmpvatwithcode);
245 $outtva_tx_formated = price($outtva_tx);
246 $outdefault_vat_code = '';
247 }
248 }
249 }
250
251 $outjson = array(
252 'ref' => $outref,
253 'label' => $outlabel,
254 'label_trans' => $outlabel_trans,
255 'desc' => $outdesc,
256 'desc_trans' => $outdesc_trans,
257 'type' => $outtype,
258 'price_ht' => $outprice_ht,
259 'price_ttc' => $outprice_ttc,
260 'pricebasetype' => $outpricebasetype,
261 'product_tva_tx_formated' => $product_outtva_tx_formated,
262 'product_tva_tx' => $product_outtva_tx,
263 'product_default_vat_code' => $product_outdefault_vat_code,
264
265 'tva_tx_formated' => $outtva_tx_formated,
266 'tva_tx' => $outtva_tx,
267 'default_vat_code' => $outdefault_vat_code,
268
269 'qty' => $outqty,
270 'discount' => $outdiscount,
271 'mandatory_period' => $mandatory_period,
272 'array_options'=>$object->array_options
273 );
274 }
275
276 echo json_encode($outjson);
277} else {
278 require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
279
280 $langs->loadLangs(array("main", "products"));
281
282 top_httphead();
283
284 if (empty($htmlname)) {
285 print json_encode(array());
286 return;
287 }
288
289 // Filter on the product to search can be:
290 // Into an array with key $htmlname123 (we take first one found). Which page use this ?
291 // Into a var with name $htmlname can be 'prodid', 'productid', ...
292 $match = preg_grep('/('.preg_quote($htmlname, '/').'[0-9]+)/', array_keys($_GET));
293 sort($match);
294
295 $idprod = (empty($match[0]) ? '' : $match[0]); // Take first key found into GET array with matching $htmlname123
296
297 if (GETPOST($htmlname, 'alpha') == '' && (!$idprod || !GETPOST($idprod, 'alpha'))) {
298 print json_encode(array());
299 return;
300 }
301
302 // When used from jQuery, the search term is added as GET param "term".
303 $searchkey = (($idprod && GETPOST($idprod, 'alpha')) ? GETPOST($idprod, 'alpha') : (GETPOST($htmlname, 'alpha') ? GETPOST($htmlname, 'alpha') : ''));
304
305 if (!isset($form) || !is_object($form)) {
306 $form = new Form($db);
307 }
308
309 if (empty($mode) || $mode == 1) { // mode=1: customer
310 $arrayresult = $form->select_produits_list("", $htmlname, $type, 0, $price_level, $searchkey, $status, $finished, $outjson, $socid, '1', 0, '', $hidepriceinlabel, $warehouseStatus, $status_purchase);
311 } elseif ($mode == 2) { // mode=2: supplier
312 $arrayresult = $form->select_produits_fournisseurs_list($socid, "", $htmlname, $type, "", $searchkey, $status, $outjson, 0, $alsoproductwithnosupplierprice);
313 }
314
315 $db->close();
316
317 if ($outjson) {
318 print json_encode($arrayresult);
319 }
320}
Class to manage generation of HTML components Only common components must be here.
File of class to manage predefined price products or services by customer.
Class to manage products or services.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
if(!defined( 'NOREQUIREMENU')) if(!empty(GETPOST('seteventmessages', 'alpha'))) if(!function_exists("llxHeader")) top_httphead($contenttype='text/html', $forcenocache=0)
Show HTTP header.
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.